diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 03d427d3fc59..f22d626c4af2 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -143,6 +143,39 @@ uint64_t decode_uint64(const char *p, int base, char **end = nullptr, return addr; } +void append_hex_value(std::ostream &ostrm, const void *buf, size_t buf_size, + bool swap) { + int i; + const uint8_t *p = (const uint8_t *)buf; + if (swap) { + for (i = static_cast(buf_size) - 1; i >= 0; i--) + ostrm << RAWHEX8(p[i]); + } else { + for (size_t i = 0; i < buf_size; i++) + ostrm << RAWHEX8(p[i]); + } +} + +std::string cstring_to_asciihex_string(const char *str) { + std::string hex_str; + hex_str.reserve(strlen(str) * 2); + while (str && *str) { + uint8_t c = *str++; + char hexbuf[5]; + snprintf(hexbuf, sizeof(hexbuf), "%02x", c); + hex_str += hexbuf; + } + return hex_str; +} + +void append_hexified_string(std::ostream &ostrm, const std::string &string) { + size_t string_size = string.size(); + const char *string_buf = string.c_str(); + for (size_t i = 0; i < string_size; i++) { + ostrm << RAWHEX8(*(string_buf + i)); + } +} + extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); @@ -171,7 +204,8 @@ RNBRemote::RNBRemote() m_extended_mode(false), m_noack_mode(false), m_thread_suffix_supported(false), m_list_threads_in_stop_reply(false), m_compression_minsize(384), m_enable_compression_next_send_packet(false), - m_compression_mode(compression_types::none) { + m_compression_mode(compression_types::none), + m_enable_error_strings(false) { DNBLogThreadedIf(LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); CreatePacketTable(); } @@ -365,6 +399,11 @@ void RNBRemote::CreatePacketTable() { t.push_back(Packet( query_symbol_lookup, &RNBRemote::HandlePacket_qSymbol, NULL, "qSymbol:", "Notify that host debugger is ready to do symbol lookups")); + t.push_back(Packet(enable_error_strings, + &RNBRemote::HandlePacket_QEnableErrorStrings, NULL, + "QEnableErrorStrings", + "Tell " DEBUGSERVER_PROGRAM_NAME + " it can append descriptive error messages in replies.")); t.push_back(Packet(json_query_thread_extended_info, &RNBRemote::HandlePacket_jThreadExtendedInfo, NULL, "jThreadExtendedInfo", @@ -769,6 +808,15 @@ rnb_err_t RNBRemote::SendPacket(const std::string &s) { return rnb_err; } +rnb_err_t RNBRemote::SendErrorPacket(std::string errcode, + const std::string &errmsg) { + if (m_enable_error_strings && !errmsg.empty()) { + errcode += ";"; + errcode += cstring_to_asciihex_string(errmsg.c_str()); + } + return SendPacket(errcode); +} + /* Get a packet via gdb remote protocol. Strip off the prefix/suffix, verify the checksum to make sure a valid packet was received, send an ACK if they match. */ @@ -884,7 +932,7 @@ rnb_err_t RNBRemote::HandlePacket_ILLFORMED(const char *file, int line, DNBLogThreadedIf(LOG_RNB_PACKETS, "%8u %s:%i ILLFORMED: '%s' (%s)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), file, line, __FUNCTION__, p); - return SendPacket("E03"); + return SendErrorPacket("E03"); } rnb_err_t RNBRemote::GetPacket(std::string &packet_payload, @@ -1565,13 +1613,8 @@ rnb_err_t RNBRemote::HandlePacket_H(const char *p) { rnb_err_t RNBRemote::HandlePacket_qLaunchSuccess(const char *p) { if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Status() == 0) return SendPacket("OK"); - std::ostringstream ret_str; std::string status_str; - std::string error_quoted = binary_encode_string - (m_ctx.LaunchStatusAsString(status_str)); - ret_str << "E" << error_quoted; - - return SendPacket(ret_str.str()); + return SendErrorPacket("E89", m_ctx.LaunchStatusAsString(status_str)); } rnb_err_t RNBRemote::HandlePacket_qShlibInfoAddr(const char *p) { @@ -1584,7 +1627,7 @@ rnb_err_t RNBRemote::HandlePacket_qShlibInfoAddr(const char *p) { return SendPacket(ostrm.str()); } } - return SendPacket("E44"); + return SendErrorPacket("E44"); } rnb_err_t RNBRemote::HandlePacket_qStepPacketSupported(const char *p) { @@ -1758,7 +1801,7 @@ rnb_err_t RNBRemote::HandlePacket_qRcmd(const char *p) { DNBLogSetLogCallback(FileLogCallback, log_file); return SendPacket("OK"); } - return SendPacket("E71"); + return SendErrorPacket("E71"); } else if (variable == "logmask") { char *end; errno = 0; @@ -1776,13 +1819,13 @@ rnb_err_t RNBRemote::HandlePacket_qRcmd(const char *p) { DNBLogSetLogMask(logmask); return SendPacket("OK"); } - return SendPacket("E72"); + return SendErrorPacket("E72"); } - return SendPacket("E70"); + return SendErrorPacket("E70"); } - return SendPacket("E69"); + return SendErrorPacket("E69"); } - return SendPacket("E73"); + return SendErrorPacket("E73"); } rnb_err_t RNBRemote::HandlePacket_qC(const char *p) { @@ -1974,7 +2017,7 @@ rnb_err_t RNBRemote::HandlePacket_qRegisterInfo(const char *p) { return SendPacket(ostrm.str()); } - return SendPacket("E45"); + return SendErrorPacket("E45"); } /* This expects a packet formatted like @@ -2222,7 +2265,7 @@ rnb_err_t set_logging(const char *p) { rnb_err_t RNBRemote::HandlePacket_QSetIgnoredExceptions(const char *p) { // We can't set the ignored exceptions if we have a running process: if (m_ctx.HasValidProcessID()) - return SendPacket("E35"); + return SendErrorPacket("E35"); p += sizeof("QSetIgnoredExceptions:") - 1; bool success = true; @@ -2247,7 +2290,7 @@ rnb_err_t RNBRemote::HandlePacket_QSetIgnoredExceptions(const char *p) { if (success) return SendPacket("OK"); else - return SendPacket("E36"); + return SendErrorPacket("E36"); } rnb_err_t RNBRemote::HandlePacket_QThreadSuffixSupported(const char *p) { @@ -2268,7 +2311,7 @@ rnb_err_t RNBRemote::HandlePacket_QSetLogging(const char *p) { if (result == rnb_success) return SendPacket("OK"); else - return SendPacket("E35"); + return SendErrorPacket("E35"); } rnb_err_t RNBRemote::HandlePacket_QSetDisableASLR(const char *p) { @@ -2282,7 +2325,7 @@ rnb_err_t RNBRemote::HandlePacket_QSetDisableASLR(const char *p) { g_disable_aslr = 1; break; default: - return SendPacket("E56"); + return SendErrorPacket("E56"); } return SendPacket("OK"); } @@ -2322,9 +2365,9 @@ rnb_err_t RNBRemote::HandlePacket_QSetSTDIO(const char *p) { } if (success) return SendPacket("OK"); - return SendPacket("E57"); + return SendErrorPacket("E57"); } - return SendPacket("E58"); + return SendErrorPacket("E58"); } rnb_err_t RNBRemote::HandlePacket_QSetWorkingDir(const char *p) { @@ -2335,15 +2378,15 @@ rnb_err_t RNBRemote::HandlePacket_QSetWorkingDir(const char *p) { struct stat working_dir_stat; if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1) { m_ctx.GetWorkingDir().clear(); - return SendPacket("E61"); // Working directory doesn't exist... + return SendErrorPacket("E61"); // Working directory doesn't exist... } else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR) { return SendPacket("OK"); } else { m_ctx.GetWorkingDir().clear(); - return SendPacket("E62"); // Working directory isn't a directory... + return SendErrorPacket("E62"); // Working directory isn't a directory... } } - return SendPacket("E59"); // Invalid path + return SendErrorPacket("E59"); // Invalid path } return SendPacket( "E60"); // Already had a process, too late to set working dir @@ -2368,7 +2411,7 @@ rnb_err_t RNBRemote::HandlePacket_QSyncThreadState(const char *p) { if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid)) return SendPacket("OK"); else - return SendPacket("E61"); + return SendErrorPacket("E61"); } rnb_err_t RNBRemote::HandlePacket_QSetDetachOnError(const char *p) { @@ -2516,7 +2559,7 @@ rnb_err_t RNBRemote::HandlePacket_QLaunchArch(const char *p) { p += sizeof("QLaunchArch:") - 1; if (DNBSetArchitecture(p)) return SendPacket("OK"); - return SendPacket("E63"); + return SendErrorPacket("E63"); } rnb_err_t RNBRemote::HandlePacket_QSetProcessEvent(const char *p) { @@ -2527,46 +2570,13 @@ rnb_err_t RNBRemote::HandlePacket_QSetProcessEvent(const char *p) { if (DNBProcessSendEvent(Context().ProcessID(), p)) return SendPacket("OK"); else - return SendPacket("E80"); + return SendErrorPacket("E80"); } else { Context().PushProcessEvent(p); } return SendPacket("OK"); } -void append_hex_value(std::ostream &ostrm, const void *buf, size_t buf_size, - bool swap) { - int i; - const uint8_t *p = (const uint8_t *)buf; - if (swap) { - for (i = static_cast(buf_size) - 1; i >= 0; i--) - ostrm << RAWHEX8(p[i]); - } else { - for (size_t i = 0; i < buf_size; i++) - ostrm << RAWHEX8(p[i]); - } -} - -std::string cstring_to_asciihex_string(const char *str) { - std::string hex_str; - hex_str.reserve (strlen (str) * 2); - while (str && *str) { - uint8_t c = *str++; - char hexbuf[5]; - snprintf (hexbuf, sizeof(hexbuf), "%02x", c); - hex_str += hexbuf; - } - return hex_str; -} - -void append_hexified_string(std::ostream &ostrm, const std::string &string) { - size_t string_size = string.size(); - const char *string_buf = string.c_str(); - for (size_t i = 0; i < string_size; i++) { - ostrm << RAWHEX8(*(string_buf + i)); - } -} - void register_value_in_hex_fixed_width(std::ostream &ostrm, nub_process_t pid, nub_thread_t tid, const register_map_entry_t *reg, @@ -2690,7 +2700,7 @@ static void ReadStackMemory(nub_process_t pid, nub_thread_t tid, rnb_err_t RNBRemote::SendStopReplyPacketForThread(nub_thread_t tid) { const nub_process_t pid = m_ctx.ProcessID(); if (pid == INVALID_NUB_PROCESS) - return SendPacket("E50"); + return SendErrorPacket("E50"); struct DNBThreadStopInfo tid_stop_info; @@ -2944,7 +2954,7 @@ rnb_err_t RNBRemote::SendStopReplyPacketForThread(nub_thread_t tid) { return SendPacket(ostrm.str()); } - return SendPacket("E51"); + return SendErrorPacket("E51"); } /* '?' @@ -2954,7 +2964,7 @@ rnb_err_t RNBRemote::SendStopReplyPacketForThread(nub_thread_t tid) { rnb_err_t RNBRemote::HandlePacket_last_signal(const char *unused) { if (!m_ctx.HasValidProcessID()) { // Inferior is not yet specified/running - return SendPacket("E02"); + return SendErrorPacket("E02"); } nub_process_t pid = m_ctx.ProcessID(); @@ -3092,7 +3102,7 @@ rnb_err_t RNBRemote::HandlePacket_M(const char *p) { nub_size_t wrote = DNBProcessMemoryWrite(m_ctx.ProcessID(), addr, length, buf); if (wrote != length) - return SendPacket("E09"); + return SendErrorPacket("E09"); else return SendPacket("OK"); } @@ -3130,12 +3140,12 @@ rnb_err_t RNBRemote::HandlePacket_m(const char *p) { std::string buf(length, '\0'); if (buf.empty()) { - return SendPacket("E78"); + return SendErrorPacket("E78"); } nub_size_t bytes_read = DNBProcessMemoryRead(m_ctx.ProcessID(), addr, buf.size(), &buf[0]); if (bytes_read == 0) { - return SendPacket("E08"); + return SendErrorPacket("E08"); } // "The reply may contain fewer bytes than requested if the server was able @@ -3196,12 +3206,12 @@ rnb_err_t RNBRemote::HandlePacket_x(const char *p) { std::vector buf(length); if (buf.capacity() != length) { - return SendPacket("E79"); + return SendErrorPacket("E79"); } nub_size_t bytes_read = DNBProcessMemoryRead(m_ctx.ProcessID(), addr, buf.size(), &buf[0]); if (bytes_read == 0) { - return SendPacket("E80"); + return SendErrorPacket("E80"); } std::vector buf_quoted; @@ -3272,7 +3282,7 @@ rnb_err_t RNBRemote::HandlePacket_X(const char *p) { nub_size_t wrote = DNBProcessMemoryWrite(m_ctx.ProcessID(), addr, data.size(), buf); if (wrote != data.size()) - return SendPacket("E08"); + return SendErrorPacket("E08"); return SendPacket("OK"); } @@ -3285,7 +3295,7 @@ rnb_err_t RNBRemote::HandlePacket_X(const char *p) { rnb_err_t RNBRemote::HandlePacket_g(const char *p) { std::ostringstream ostrm; if (!m_ctx.HasValidProcessID()) { - return SendPacket("E11"); + return SendErrorPacket("E11"); } if (g_num_reg_entries == 0) @@ -3311,7 +3321,7 @@ rnb_err_t RNBRemote::HandlePacket_g(const char *p) { return SendPacket(ostrm.str()); } } - return SendPacket("E74"); + return SendErrorPacket("E74"); } /* 'G XXX...' -- write registers @@ -3320,7 +3330,7 @@ rnb_err_t RNBRemote::HandlePacket_g(const char *p) { rnb_err_t RNBRemote::HandlePacket_G(const char *p) { if (!m_ctx.HasValidProcessID()) { - return SendPacket("E11"); + return SendErrorPacket("E11"); } if (g_num_reg_entries == 0) @@ -3351,15 +3361,15 @@ rnb_err_t RNBRemote::HandlePacket_G(const char *p) { if (reg_ctx_size == reg_ctx.size()) return SendPacket("OK"); else - return SendPacket("E55"); + return SendErrorPacket("E55"); } else { DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu " "bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size); - return SendPacket("E64"); + return SendErrorPacket("E64"); } } - return SendPacket("E65"); + return SendErrorPacket("E65"); } static bool RNBRemoteShouldCancelCallback(void *not_used) { @@ -3422,7 +3432,7 @@ rnb_err_t RNBRemote::HandlePacket_AllocateMemory(const char *p) { } } } - return SendPacket("E53"); + return SendErrorPacket("E53"); } // FORMAT: _mXXXXXX @@ -3445,7 +3455,7 @@ rnb_err_t RNBRemote::HandlePacket_DeallocateMemory(const char *p) { if (DNBProcessMemoryDeallocate(m_ctx.ProcessID(), addr)) return SendPacket("OK"); } - return SendPacket("E54"); + return SendErrorPacket("E54"); } // FORMAT: QSaveRegisterState;thread:TTTT; (when thread suffix is supported) @@ -3483,7 +3493,7 @@ rnb_err_t RNBRemote::HandlePacket_SaveRegisterState(const char *p) { snprintf(response, sizeof(response), "%u", save_id); return SendPacket(response); } else { - return SendPacket("E75"); + return SendErrorPacket("E75"); } } // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT; (when thread suffix is @@ -3527,9 +3537,9 @@ rnb_err_t RNBRemote::HandlePacket_RestoreRegisterState(const char *p) { if (DNBThreadRestoreRegisterState(pid, tid, save_id)) return SendPacket("OK"); else - return SendPacket("E77"); + return SendErrorPacket("E77"); } - return SendPacket("E76"); + return SendErrorPacket("E76"); } static bool GetProcessNameFrom_vAttach(const char *&p, @@ -3908,12 +3918,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) { if (attach_pid == INVALID_NUB_PROCESS_ARCH) { DNBLogError("debugserver is x86_64 binary running in translation, attach " "failed."); - std::string return_message = "E96;"; - return_message += - cstring_to_asciihex_string("debugserver is x86_64 binary running in " - "translation, attach failed."); - SendPacket(return_message.c_str()); - return rnb_err; + return SendErrorPacket("E96", "debugserver is x86_64 binary running in " + "translation, attach failed."); } if (attach_pid != INVALID_NUB_PROCESS) { @@ -3944,16 +3950,12 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) { // The order of these checks is important. if (process_does_not_exist (pid_attaching_to)) { DNBLogError("Tried to attach to pid that doesn't exist"); - std::string return_message = "E96;"; - return_message += cstring_to_asciihex_string("no such process."); - return SendPacket(return_message); + return SendErrorPacket("E96", "no such process"); } if (process_is_already_being_debugged (pid_attaching_to)) { DNBLogError("Tried to attach to process already being debugged"); - std::string return_message = "E96;"; - return_message += cstring_to_asciihex_string("tried to attach to " - "process already being debugged"); - return SendPacket(return_message); + return SendErrorPacket("E96", "tried to attach to " + "process already being debugged"); } uid_t my_uid, process_uid; if (attach_failed_due_to_uid_mismatch (pid_attaching_to, @@ -3969,31 +3971,27 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) { process_username = pw->pw_name; } DNBLogError("Tried to attach to process with uid mismatch"); - std::string return_message = "E96;"; - std::string msg = "tried to attach to process as user '" - + my_username + "' and process is running " - "as user '" + process_username + "'"; - return_message += cstring_to_asciihex_string(msg.c_str()); - return SendPacket(return_message); + std::string msg = "tried to attach to process as user '" + + my_username + + "' and process is running " + "as user '" + + process_username + "'"; + return SendErrorPacket("E96", msg); } if (!login_session_has_gui_access() && !developer_mode_enabled()) { DNBLogError("Developer mode is not enabled and this is a " "non-interactive session"); - std::string return_message = "E96;"; - return_message += cstring_to_asciihex_string("developer mode is " - "not enabled on this machine " - "and this is a non-interactive " - "debug session."); - return SendPacket(return_message); + return SendErrorPacket("E96", "developer mode is " + "not enabled on this machine " + "and this is a non-interactive " + "debug session."); } if (!login_session_has_gui_access()) { DNBLogError("This is a non-interactive session"); - std::string return_message = "E96;"; - return_message += cstring_to_asciihex_string("this is a " - "non-interactive debug session, " - "cannot get permission to debug " - "processes."); - return SendPacket(return_message); + return SendErrorPacket("E96", "this is a " + "non-interactive debug session, " + "cannot get permission to debug " + "processes."); } } @@ -4013,12 +4011,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) { error_explainer += err_str; error_explainer += ")"; } - std::string default_return_msg = "E96;"; - default_return_msg += cstring_to_asciihex_string - (error_explainer.c_str()); - SendPacket (default_return_msg); DNBLogError("Attach failed: \"%s\".", err_str); - return rnb_err; + return SendErrorPacket("E96", error_explainer); } } @@ -4037,7 +4031,7 @@ rnb_err_t RNBRemote::HandlePacket_T(const char *p) { "No thread specified in T packet"); } if (!m_ctx.HasValidProcessID()) { - return SendPacket("E15"); + return SendErrorPacket("E15"); } errno = 0; nub_thread_t tid = strtoul(p, NULL, 16); @@ -4049,7 +4043,7 @@ rnb_err_t RNBRemote::HandlePacket_T(const char *p) { nub_state_t state = DNBThreadGetState(m_ctx.ProcessID(), tid); if (state == eStateInvalid || state == eStateExited || state == eStateCrashed) { - return SendPacket("E16"); + return SendErrorPacket("E16"); } return SendPacket("OK"); @@ -4061,7 +4055,7 @@ rnb_err_t RNBRemote::HandlePacket_z(const char *p) { "No thread specified in z packet"); if (!m_ctx.HasValidProcessID()) - return SendPacket("E15"); + return SendErrorPacket("E15"); char packet_cmd = *p++; char break_type = *p++; @@ -4105,7 +4099,7 @@ rnb_err_t RNBRemote::HandlePacket_z(const char *p) { return SendPacket("OK"); } else { // We failed to set the software breakpoint - return SendPacket("E09"); + return SendErrorPacket("E09"); } } break; @@ -4126,7 +4120,7 @@ rnb_err_t RNBRemote::HandlePacket_z(const char *p) { return SendPacket("OK"); } else { // We failed to set the watchpoint - return SendPacket("E09"); + return SendErrorPacket("E09"); } } break; @@ -4141,7 +4135,7 @@ rnb_err_t RNBRemote::HandlePacket_z(const char *p) { if (DNBBreakpointClear(pid, addr)) { return SendPacket("OK"); } else { - return SendPacket("E08"); + return SendErrorPacket("E08"); } break; @@ -4151,7 +4145,7 @@ rnb_err_t RNBRemote::HandlePacket_z(const char *p) { if (DNBWatchpointClear(pid, addr)) { return SendPacket("OK"); } else { - return SendPacket("E08"); + return SendErrorPacket("E08"); } break; @@ -4193,7 +4187,7 @@ rnb_err_t RNBRemote::HandlePacket_p(const char *p) { "No thread specified in p packet"); } if (!m_ctx.HasValidProcessID()) { - return SendPacket("E15"); + return SendErrorPacket("E15"); } nub_process_t pid = m_ctx.ProcessID(); errno = 0; @@ -4245,7 +4239,7 @@ rnb_err_t RNBRemote::HandlePacket_P(const char *p) { return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Empty P packet"); } if (!m_ctx.HasValidProcessID()) { - return SendPacket("E28"); + return SendErrorPacket("E28"); } nub_process_t pid = m_ctx.ProcessID(); @@ -4262,15 +4256,15 @@ rnb_err_t RNBRemote::HandlePacket_P(const char *p) { "Improperly formed P packet"); if (reg == UINT32_MAX) - return SendPacket("E29"); + return SendErrorPacket("E29"); if (equal_char != '=') - return SendPacket("E30"); + return SendErrorPacket("E30"); const register_map_entry_t *reg_entry; if (reg >= g_num_reg_entries) - return SendPacket("E47"); + return SendErrorPacket("E47"); reg_entry = &g_reg_entries[reg]; @@ -4279,7 +4273,7 @@ rnb_err_t RNBRemote::HandlePacket_P(const char *p) { DNBLogError( "RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg); - return SendPacket("E48"); + return SendErrorPacket("E48"); } DNBRegisterValue reg_value; @@ -4293,7 +4287,7 @@ rnb_err_t RNBRemote::HandlePacket_P(const char *p) { if (!DNBThreadSetRegisterValueByID(pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) { - return SendPacket("E32"); + return SendErrorPacket("E32"); } return SendPacket("OK"); } @@ -4305,7 +4299,7 @@ rnb_err_t RNBRemote::HandlePacket_c(const char *p) { const nub_process_t pid = m_ctx.ProcessID(); if (pid == INVALID_NUB_PROCESS) - return SendPacket("E23"); + return SendErrorPacket("E23"); DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS}; @@ -4324,7 +4318,7 @@ rnb_err_t RNBRemote::HandlePacket_c(const char *p) { thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); if (!DNBProcessResume(pid, thread_actions.GetFirst(), thread_actions.GetSize())) - return SendPacket("E25"); + return SendErrorPacket("E25"); // Don't send an "OK" packet; response is the stopped/exited message. return rnb_success; } @@ -4362,7 +4356,7 @@ rnb_err_t RNBRemote::HandlePacket_MemoryRegionInfo(const char *p) { if (*p == '\0') return SendPacket("OK"); if (*p++ != ':') - return SendPacket("E67"); + return SendErrorPacket("E67"); if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2; @@ -4502,7 +4496,7 @@ rnb_err_t RNBRemote::HandlePacket_QEnableCompression(const char *p) { return SendPacket("OK"); } - return SendPacket("E88"); + return SendErrorPacket("E88"); } rnb_err_t RNBRemote::HandlePacket_qSpeedTest(const char *p) { @@ -4521,7 +4515,7 @@ rnb_err_t RNBRemote::HandlePacket_qSpeedTest(const char *p) { g_data[response_size + 5] = '\0'; return SendPacket(g_data); } else { - return SendPacket("E79"); + return SendErrorPacket("E79"); } } @@ -4540,7 +4534,7 @@ rnb_err_t RNBRemote::HandlePacket_WatchpointSupportInfo(const char *p) { if (*p == '\0') return SendPacket("OK"); if (*p++ != ':') - return SendPacket("E67"); + return SendErrorPacket("E67"); errno = 0; uint32_t num = DNBWatchpointGetNumSupportedHWP(m_ctx.ProcessID()); @@ -4558,7 +4552,7 @@ rnb_err_t RNBRemote::HandlePacket_C(const char *p) { const nub_process_t pid = m_ctx.ProcessID(); if (pid == INVALID_NUB_PROCESS) - return SendPacket("E36"); + return SendErrorPacket("E36"); DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS}; @@ -4584,10 +4578,10 @@ rnb_err_t RNBRemote::HandlePacket_C(const char *p) { thread_actions.Append(action); thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, action.signal); if (!DNBProcessSignal(pid, process_signo)) - return SendPacket("E52"); + return SendErrorPacket("E52"); if (!DNBProcessResume(pid, thread_actions.GetFirst(), thread_actions.GetSize())) - return SendPacket("E38"); + return SendErrorPacket("E38"); /* Don't send an "OK" packet; response is the stopped/exited message. */ return rnb_success; } @@ -4602,10 +4596,10 @@ rnb_err_t RNBRemote::HandlePacket_D(const char *p) { else { DNBLog("error while detaching from pid %u due to D packet", m_ctx.ProcessID()); - SendPacket("E"); + SendErrorPacket("E01"); } } else { - SendPacket("E"); + SendErrorPacket("E04"); } return rnb_success; } @@ -4647,7 +4641,7 @@ rnb_err_t RNBRemote::HandlePacket_stop_process(const char *p) { rnb_err_t RNBRemote::HandlePacket_s(const char *p) { const nub_process_t pid = m_ctx.ProcessID(); if (pid == INVALID_NUB_PROCESS) - return SendPacket("E32"); + return SendErrorPacket("E32"); // Hardware supported stepping not supported on arm nub_thread_t tid = GetContinueThread(); @@ -4655,7 +4649,7 @@ rnb_err_t RNBRemote::HandlePacket_s(const char *p) { tid = GetCurrentThread(); if (tid == INVALID_NUB_THREAD) - return SendPacket("E33"); + return SendErrorPacket("E33"); DNBThreadResumeActions thread_actions; thread_actions.AppendAction(tid, eStateStepping); @@ -4664,7 +4658,7 @@ rnb_err_t RNBRemote::HandlePacket_s(const char *p) { thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); if (!DNBProcessResume(pid, thread_actions.GetFirst(), thread_actions.GetSize())) - return SendPacket("E49"); + return SendErrorPacket("E49"); // Don't send an "OK" packet; response is the stopped/exited message. return rnb_success; } @@ -4675,7 +4669,7 @@ rnb_err_t RNBRemote::HandlePacket_s(const char *p) { rnb_err_t RNBRemote::HandlePacket_S(const char *p) { const nub_process_t pid = m_ctx.ProcessID(); if (pid == INVALID_NUB_PROCESS) - return SendPacket("E36"); + return SendErrorPacket("E36"); DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS}; @@ -4699,11 +4693,11 @@ rnb_err_t RNBRemote::HandlePacket_S(const char *p) { action.tid = GetContinueThread(); if (action.tid == 0 || action.tid == (nub_thread_t)-1) - return SendPacket("E40"); + return SendErrorPacket("E40"); nub_state_t tstate = DNBThreadGetState(pid, action.tid); if (tstate == eStateInvalid || tstate == eStateExited) - return SendPacket("E37"); + return SendErrorPacket("E37"); DNBThreadResumeActions thread_actions; thread_actions.Append(action); @@ -4712,7 +4706,7 @@ rnb_err_t RNBRemote::HandlePacket_S(const char *p) { thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); if (!DNBProcessResume(pid, thread_actions.GetFirst(), thread_actions.GetSize())) - return SendPacket("E39"); + return SendErrorPacket("E39"); // Don't send an "OK" packet; response is the stopped/exited message. return rnb_success; @@ -5242,7 +5236,7 @@ rnb_err_t RNBRemote::HandlePacket_qXfer(const char *command) { UpdateTargetXML(); if (g_target_xml.empty()) - return SendPacket("E83"); + return SendErrorPacket("E83"); if (length > g_target_xml.size()) { xml_out << 'l'; // No more data @@ -5273,13 +5267,13 @@ rnb_err_t RNBRemote::HandlePacket_qXfer(const char *command) { } } } else { - SendPacket("E85"); + SendErrorPacket("E85"); } } else { - SendPacket("E86"); + SendErrorPacket("E86"); } } - return SendPacket("E82"); + return SendErrorPacket("E82"); } rnb_err_t RNBRemote::HandlePacket_qGDBServerVersion(const char *p) { @@ -5298,7 +5292,7 @@ rnb_err_t RNBRemote::HandlePacket_qGDBServerVersion(const char *p) { rnb_err_t RNBRemote::HandlePacket_jGetDyldProcessState(const char *p) { const nub_process_t pid = m_ctx.ProcessID(); if (pid == INVALID_NUB_PROCESS) - return SendPacket("E87"); + return SendErrorPacket("E87"); JSONGenerator::ObjectSP dyld_state_sp = DNBGetDyldProcessState(pid); if (dyld_state_sp) { @@ -5308,7 +5302,7 @@ rnb_err_t RNBRemote::HandlePacket_jGetDyldProcessState(const char *p) { if (strm.str().size() > 0) return SendPacket(strm.str()); } - return SendPacket("E88"); + return SendErrorPacket("E88"); } // A helper function that retrieves a single integer value from @@ -5648,7 +5642,7 @@ rnb_err_t RNBRemote::HandlePacket_jThreadsInfo(const char *p) { return SendPacket(strm.str()); } } - return SendPacket("E85"); + return SendErrorPacket("E85"); } rnb_err_t RNBRemote::HandlePacket_jThreadExtendedInfo(const char *p) { @@ -5656,7 +5650,7 @@ rnb_err_t RNBRemote::HandlePacket_jThreadExtendedInfo(const char *p) { std::ostringstream json; // If we haven't run the process yet, return an error. if (!m_ctx.HasValidProcessID()) { - return SendPacket("E81"); + return SendErrorPacket("E81"); } pid = m_ctx.ProcessID(); @@ -5925,7 +5919,7 @@ RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p) { nub_process_t pid; // If we haven't run the process yet, return an error. if (!m_ctx.HasValidProcessID()) { - return SendPacket("E83"); + return SendErrorPacket("E83"); } pid = m_ctx.ProcessID(); @@ -5960,7 +5954,7 @@ RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p) { if (json_str.str().size() > 0) { return SendPacket(json_str.str()); } else { - SendPacket("E84"); + SendErrorPacket("E84"); } } } @@ -5976,7 +5970,7 @@ rnb_err_t RNBRemote::HandlePacket_jGetSharedCacheInfo(const char *p) { nub_process_t pid; // If we haven't run the process yet, return an error. if (!m_ctx.HasValidProcessID()) { - return SendPacket("E85"); + return SendErrorPacket("E85"); } pid = m_ctx.ProcessID(); @@ -5993,7 +5987,7 @@ rnb_err_t RNBRemote::HandlePacket_jGetSharedCacheInfo(const char *p) { if (json_str.str().size() > 0) { return SendPacket(json_str.str()); } else { - SendPacket("E86"); + SendErrorPacket("E86"); } } } @@ -6195,6 +6189,11 @@ rnb_err_t RNBRemote::HandlePacket_qSymbol(const char *command) { } } +rnb_err_t RNBRemote::HandlePacket_QEnableErrorStrings(const char *p) { + m_enable_error_strings = true; + return SendPacket("OK"); +} + static std::pair GetCPUTypesFromHost(nub_process_t pid) { cpu_type_t cputype = DNBProcessGetCPUType(pid); diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h index dad390ae0b63..a95bece79b46 100644 --- a/lldb/tools/debugserver/source/RNBRemote.h +++ b/lldb/tools/debugserver/source/RNBRemote.h @@ -33,6 +33,7 @@ enum class compression_types { zlib_deflate, lz4, lzma, lzfse, none }; class RNBRemote { public: + // clang-format off enum PacketEnum { invalid_packet = 0, ack, // '+' @@ -137,8 +138,10 @@ public: set_detach_on_error, // 'QSetDetachOnError:' query_transfer, // 'qXfer:' json_query_dyld_process_state, // 'jGetDyldProcessState' + enable_error_strings, // 'QEnableErrorStrings' unknown_type }; + // clang-format on typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p); @@ -196,6 +199,7 @@ public: rnb_err_t HandlePacket_qGDBServerVersion(const char *p); rnb_err_t HandlePacket_qProcessInfo(const char *p); rnb_err_t HandlePacket_qSymbol(const char *p); + rnb_err_t HandlePacket_QEnableErrorStrings(const char *p); rnb_err_t HandlePacket_QStartNoAckMode(const char *p); rnb_err_t HandlePacket_QThreadSuffixSupported(const char *p); rnb_err_t HandlePacket_QSetLogging(const char *p); @@ -356,6 +360,8 @@ protected: rnb_err_t GetPacket(std::string &packet_data, RNBRemote::Packet &packet_info, bool wait); rnb_err_t SendPacket(const std::string &); + rnb_err_t SendErrorPacket(std::string errcode, + const std::string &errmsg = ""); std::string CompressString(const std::string &); void CreatePacketTable(); @@ -405,6 +411,9 @@ protected: bool m_enable_compression_next_send_packet; compression_types m_compression_mode; + + bool m_enable_error_strings; // Whether we can append asciihex error strings + // after Exx error replies }; /* We translate the /usr/include/mach/exception_types.h exception types