9#include "lldb/Host/Config.h"
14#include <netinet/in.h>
17#include <sys/socket.h>
22#include <sys/sysctl.h>
106#include "llvm/ADT/STLExtras.h"
107#include "llvm/ADT/ScopeExit.h"
108#include "llvm/ADT/StringMap.h"
109#include "llvm/ADT/StringSwitch.h"
110#include "llvm/Support/Casting.h"
111#include "llvm/Support/Chrono.h"
112#include "llvm/Support/ErrorExtras.h"
113#include "llvm/Support/FormatAdapters.h"
114#include "llvm/Support/Threading.h"
115#include "llvm/Support/raw_ostream.h"
117#if defined(__APPLE__)
118#define DEBUGSERVER_BASENAME "debugserver"
120#define DEBUGSERVER_BASENAME "lldb-server.exe"
122#define DEBUGSERVER_BASENAME "lldb-server"
142 llvm::consumeError(file.takeError());
146 ((
Process *)p)->DumpPluginHistory(stream);
152#define LLDB_PROPERTIES_processgdbremote
153#include "ProcessGDBRemoteProperties.inc"
156#define LLDB_PROPERTIES_processgdbremote
157#include "ProcessGDBRemotePropertiesEnum.inc"
162 static llvm::StringRef GetSettingName() {
166 PluginProperties() : Properties() {
167 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
168 m_collection_sp->Initialize(g_processgdbremote_properties_def);
171 ~PluginProperties()
override =
default;
173 uint64_t GetPacketTimeout() {
174 const uint32_t idx = ePropertyPacketTimeout;
175 return GetPropertyAtIndexAs<uint64_t>(
176 idx, g_processgdbremote_properties[idx].default_uint_value);
179 bool SetPacketTimeout(uint64_t timeout) {
180 const uint32_t idx = ePropertyPacketTimeout;
181 return SetPropertyAtIndex(idx, timeout);
184 FileSpec GetTargetDefinitionFile()
const {
185 const uint32_t idx = ePropertyTargetDefinitionFile;
186 return GetPropertyAtIndexAs<FileSpec>(idx, {});
189 bool GetUseSVR4()
const {
190 const uint32_t idx = ePropertyUseSVR4;
191 return GetPropertyAtIndexAs<bool>(
192 idx, g_processgdbremote_properties[idx].default_uint_value != 0);
195 bool GetUseGPacketForReading()
const {
196 const uint32_t idx = ePropertyUseGPacketForReading;
197 return GetPropertyAtIndexAs<bool>(idx,
true);
200 uint64_t GetPacketTestDelay()
const {
201 const uint32_t idx = ePropertyPacketTestDelay;
202 return GetPropertyAtIndexAs<uint64_t>(
203 idx, g_processgdbremote_properties[idx].default_uint_value);
207std::chrono::seconds ResumeTimeout() {
return std::chrono::seconds(5); }
209static std::pair<uint16_t, uint16_t> GetClientTerminalSize() {
211 CONSOLE_SCREEN_BUFFER_INFO csbi{};
212 HANDLE h = ::GetStdHandle(STD_OUTPUT_HANDLE);
213 if (h != INVALID_HANDLE_VALUE && ::GetConsoleScreenBufferInfo(h, &csbi)) {
214 int cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
215 int rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
216 if (cols > 0 && rows > 0)
217 return {
static_cast<uint16_t
>(cols),
static_cast<uint16_t
>(rows)};
219#elif LLDB_ENABLE_POSIX
221 if (::ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0 &&
223 return {ws.ws_col, ws.ws_row};
231 static PluginProperties g_settings;
239#if defined(__APPLE__)
240#define LOW_PORT (IPPORT_RESERVED)
241#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
243#define LOW_PORT (1024u)
244#define HIGH_PORT (49151u)
248 return "GDB Remote protocol based debugging plug-in.";
257 const FileSpec *crash_file_path,
bool can_connect) {
273 return std::chrono::milliseconds(
282 bool plugin_specified_by_name) {
283 if (plugin_specified_by_name)
287 Module *exe_module = target_sp->GetExecutableModulePointer();
291 switch (exe_objfile->
GetType()) {
315 :
Process(target_sp, listener_sp),
319 Listener::MakeListener(
"lldb.process.gdb-remote.async-listener")),
329 "async thread should exit");
331 "async thread continue");
333 "async thread did exit");
337 const uint32_t async_event_mask =
343 "ProcessGDBRemote::%s failed to listen for "
344 "m_async_broadcaster events",
348 const uint64_t timeout_seconds =
350 if (timeout_seconds > 0)
351 m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
359 llvm::sys::TimePoint<> now = std::chrono::system_clock::now();
360 std::string name = llvm::formatv(
361 "gdb-remote-packet-history-{0:%Y-%m-%dT%H-%M-%S}.txt", now);
363 std::move(name), [
this]() -> std::string {
394std::shared_ptr<ThreadGDBRemote>
396 return std::make_shared<ThreadGDBRemote>(*
this, tid);
400 const FileSpec &target_definition_fspec) {
406 if (module_object_sp) {
409 "gdb-server-target-definition",
error));
411 if (target_definition_sp) {
413 target_definition_sp->GetValueForKey(
"host-info"));
415 if (
auto host_info_dict = target_object->GetAsDictionary()) {
417 host_info_dict->GetValueForKey(
"triple");
418 if (
auto triple_string_value = triple_value->GetAsString()) {
419 std::string triple_string =
420 std::string(triple_string_value->GetValue());
421 ArchSpec host_arch(triple_string.c_str());
430 target_definition_sp->GetValueForKey(
"breakpoint-pc-offset");
431 if (breakpoint_pc_offset_value) {
432 if (
auto breakpoint_pc_int_value =
433 breakpoint_pc_offset_value->GetAsSignedInteger())
438 *target_definition_sp,
GetTarget().GetArchitecture()) > 0) {
447 const llvm::StringRef &comma_separated_register_numbers,
448 std::vector<uint32_t> ®nums,
int base) {
450 for (llvm::StringRef x : llvm::split(comma_separated_register_numbers,
',')) {
452 if (llvm::to_integer(x, reg, base))
453 regnums.push_back(reg);
455 return regnums.size();
467 const auto host_packet_timeout =
m_gdb_comm.GetHostDefaultPacketTimeout();
468 if (host_packet_timeout > std::chrono::seconds(0)) {
486 if (target_definition_fspec) {
492 target_definition_fspec.
GetPath() +
503 if (remote_process_arch.
IsValid())
504 arch_to_use = remote_process_arch;
506 arch_to_use = remote_host_arch;
509 arch_to_use = target_arch;
512 if (!register_info_err) {
519 "Failed to read register information from target XML: {0}");
520 LLDB_LOG(log,
"Now trying to use qRegisterInfo instead.");
523 std::vector<DynamicRegisterInfo::Register> registers;
524 uint32_t reg_num = 0;
528 const int packet_len =
529 ::snprintf(packet,
sizeof(packet),
"qRegisterInfo%x", reg_num);
530 assert(packet_len < (
int)
sizeof(packet));
533 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
537 llvm::StringRef name;
538 llvm::StringRef value;
542 if (name ==
"name") {
544 }
else if (name ==
"alt-name") {
546 }
else if (name ==
"bitsize") {
549 }
else if (name ==
"offset") {
551 }
else if (name ==
"encoding") {
555 }
else if (name ==
"format") {
559 llvm::StringSwitch<Format>(value)
601 }
else if (name ==
"set") {
603 }
else if (name ==
"gcc" || name ==
"ehframe") {
605 }
else if (name ==
"dwarf") {
607 }
else if (name ==
"generic") {
609 }
else if (name ==
"container-regs") {
611 }
else if (name ==
"invalidate-regs") {
617 registers.push_back(reg_info);
630 "the debug server supports Target Description XML but LLDB does "
631 "not have XML parsing enabled. Using \"qRegisterInfo\" was also "
632 "not possible. Register information may be incorrect or missing",
642 if (registers.empty()) {
644 if (!registers.empty())
647 "All other methods failed, using fallback register information.");
662 bool wait_for_launch) {
694 if (
m_gdb_comm.GetProcessArchitecture().IsValid()) {
697 if (
m_gdb_comm.GetHostArchitecture().IsValid()) {
708 "Process %" PRIu64
" was reported after connecting to "
709 "'%s', but state was not stopped: %s",
713 "Process %" PRIu64
" was reported after connecting to '%s', "
714 "but no stop reply packet was received",
715 pid, remote_url.str().c_str());
719 "ProcessGDBRemote::%s pid %" PRIu64
720 ": normalizing target architecture initial triple: %s "
721 "(GetTarget().GetArchitecture().IsValid() %s, "
722 "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
723 __FUNCTION__,
GetID(),
724 GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
726 m_gdb_comm.GetHostArchitecture().IsValid() ?
"true" :
"false");
732 if (
m_gdb_comm.GetProcessArchitecture().IsValid())
739 "ProcessGDBRemote::%s pid %" PRIu64
740 ": normalized target architecture triple: %s",
741 __FUNCTION__,
GetID(),
742 GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
759 LLDB_LOGF(log,
"ProcessGDBRemote::%s() entered", __FUNCTION__);
761 uint32_t launch_flags = launch_info.
GetFlags().
Get();
784 if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
786 "ProcessGDBRemote::%s provided with STDIO paths via "
787 "launch_info: stdin=%s, stdout=%s, stderr=%s",
789 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
790 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
791 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
793 LLDB_LOGF(log,
"ProcessGDBRemote::%s no STDIO paths given via launch_info",
796 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
797 if (stdin_file_spec || disable_stdio) {
812 if (
error.Success()) {
814 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
819 if (!stdin_file_spec)
821 FileSpec::Style::native);
822 if (!stdout_file_spec)
824 FileSpec::Style::native);
825 if (!stderr_file_spec)
827 FileSpec::Style::native);
828 }
else if (platform_sp && platform_sp->IsHost()) {
833 if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
837 if (!stdin_file_spec)
838 stdin_file_spec = secondary_name;
840 if (!stdout_file_spec)
841 stdout_file_spec = secondary_name;
843 if (!stderr_file_spec)
844 stderr_file_spec = secondary_name;
848 "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
849 "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
852 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
853 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
854 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
858 "ProcessGDBRemote::%s final STDIO paths after all "
859 "adjustments: stdin=%s, stdout=%s, stderr=%s",
861 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
862 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
863 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
867 if (stdout_file_spec)
869 if (stderr_file_spec)
872 if (launch_flags & eLaunchFlagUsePipes) {
875 auto [terminal_cols, terminal_rows] = GetClientTerminalSize();
876 m_gdb_comm.SetSTDIOWindowSize(terminal_cols, terminal_rows);
879 m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
880 m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
883 GetTarget().GetArchitecture().GetArchitectureName());
886 if (launch_event_data !=
nullptr && *launch_event_data !=
'\0')
887 m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
899 std::chrono::seconds(10));
905 const llvm::Triple &remote_triple =
907 if (remote_triple.getOS() != llvm::Triple::UnknownOS) {
908 FileSpec remote_exe_file(exe_file.GetPath(
false),
911 0, remote_exe_file.
GetPath(
true));
914 exe_file.GetPath(
true));
917 if (llvm::Error err =
m_gdb_comm.LaunchProcess(args)) {
920 llvm::fmt_consume(std::move(err)));
927 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
949 if (!disable_stdio) {
963 std::make_shared<IOHandlerProcessSTDIOWindows>(
this);
969 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
error.AsCString());
979 if (!connect_url.empty()) {
980 LLDB_LOGF(log,
"ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
981 connect_url.str().c_str());
982 std::unique_ptr<ConnectionFileDescriptor> conn_up(
985 const uint32_t max_retry_count = 50;
986 uint32_t retry_count = 0;
995 if (retry_count >= max_retry_count)
998 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1004 if (
error.Success())
1015 if (
error.Success())
1022 m_gdb_comm.GetListThreadsInStopReplySupported();
1032 auto handle_cmds = [&] (
const Args &args) ->
void {
1036 entry.c_str(), response);
1042 handle_cmds(platform_sp->GetExtraStartupCommands());
1059 if (remote_process_arch.
IsValid()) {
1060 process_arch = remote_process_arch;
1061 LLDB_LOG(log,
"gdb-remote had process architecture, using {0} {1}",
1065 process_arch =
m_gdb_comm.GetHostArchitecture();
1067 "gdb-remote did not have process architecture, using gdb-remote "
1068 "host architecture {0} {1}",
1079 LLDB_LOG(log,
"analyzing target arch, currently {0} {1}",
1091 if ((process_arch.
GetMachine() == llvm::Triple::arm ||
1092 process_arch.
GetMachine() == llvm::Triple::thumb) &&
1093 process_arch.
GetTriple().getVendor() == llvm::Triple::Apple) {
1096 "remote process is ARM/Apple, "
1097 "setting target arch to {0} {1}",
1102 const llvm::Triple &remote_triple = process_arch.
GetTriple();
1103 llvm::Triple new_target_triple = target_arch.
GetTriple();
1104 if (new_target_triple.getVendorName().size() == 0) {
1105 new_target_triple.setVendor(remote_triple.getVendor());
1107 if (new_target_triple.getOSName().size() == 0) {
1108 new_target_triple.setOS(remote_triple.getOS());
1110 if (new_target_triple.getEnvironmentName().size() == 0)
1111 new_target_triple.setEnvironment(remote_triple.getEnvironment());
1114 ArchSpec new_target_arch = target_arch;
1115 new_target_arch.
SetTriple(new_target_triple);
1121 "final target arch after adjustments for remote architecture: "
1140 m_gdb_comm.GetSupportedStructuredDataPlugins())
1149 if (platform_sp && platform_sp->IsConnected())
1157 llvm::Expected<std::vector<AcceleratorActions>> init_actions =
1158 m_gdb_comm.GetAcceleratorInitializeActions();
1159 if (!init_actions) {
1161 "failed to get accelerator initialize actions: {0}");
1166 "failed to handle accelerator actions: {0}");
1176 UUID standalone_uuid;
1178 bool standalone_value_is_offset;
1179 if (
m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value,
1180 standalone_value_is_offset)) {
1181 if (standalone_uuid.
IsValid()) {
1183 bin_spec.
uuid = standalone_uuid;
1184 bin_spec.
value = standalone_value;
1190 llvm::Expected<ModuleSP> module =
1194 << llvm::toString(module.takeError()) <<
"\n";
1206 std::vector<addr_t> bin_addrs =
m_gdb_comm.GetProcessStandaloneBinaries();
1207 if (bin_addrs.size()) {
1208 for (
addr_t addr : bin_addrs) {
1209 const bool notify =
true;
1216 .LoadPlatformBinaryAndSetup(
this, addr, notify))
1221 bin_spec.
value = addr;
1223 bin_spec.
notify = notify;
1225 llvm::Expected<ModuleSP> module =
1229 << llvm::toString(module.takeError()) <<
"\n";
1239 std::optional<QOffsets> offsets =
m_gdb_comm.GetQOffsets();
1244 size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==
1245 offsets->offsets.size();
1249 bool changed =
false;
1250 module_sp->SetLoadAddress(
GetTarget(), offsets->offsets[0],
1255 m_process->GetTarget().ModulesDidLoad(list);
1269 LLDB_LOGF(log,
"ProcessGDBRemote::%s()", __FUNCTION__);
1275 if (
error.Success()) {
1279 const int packet_len =
1280 ::snprintf(packet,
sizeof(packet),
"vAttach;%" PRIx64, attach_pid);
1283 std::make_shared<EventDataBytes>(llvm::StringRef(packet, packet_len));
1298 if (process_name && process_name[0]) {
1300 if (
error.Success()) {
1306 if (!
m_gdb_comm.GetVAttachOrWaitSupported()) {
1321 auto data_sp = std::make_shared<EventDataBytes>(packet.
GetString());
1342llvm::Expected<std::string>
1347llvm::Expected<std::vector<uint8_t>>
1359 process_arch.
Clear();
1375 return m_gdb_comm.GetReverseStepSupported() ||
1382 LLDB_LOGF(log,
"ProcessGDBRemote::Resume(%s)",
1387 if (listener_sp->StartListeningForEvents(
1389 listener_sp->StartListeningForEvents(
1396 bool continue_packet_error =
false;
1410 std::string pid_prefix;
1412 pid_prefix = llvm::formatv(
"p{0:x-}.",
GetID());
1414 if (num_continue_c_tids == num_threads ||
1419 continue_packet.
Format(
"vCont;c:{0}-1", pid_prefix);
1427 for (tid_collection::const_iterator
1430 t_pos != t_end; ++t_pos)
1431 continue_packet.
Format(
";c:{0}{1:x-}", pid_prefix, *t_pos);
1433 continue_packet_error =
true;
1438 for (tid_sig_collection::const_iterator
1441 s_pos != s_end; ++s_pos)
1442 continue_packet.
Format(
";C{0:x-2}:{1}{2:x-}", s_pos->second,
1443 pid_prefix, s_pos->first);
1445 continue_packet_error =
true;
1450 for (tid_collection::const_iterator
1453 t_pos != t_end; ++t_pos)
1454 continue_packet.
Format(
";s:{0}{1:x-}", pid_prefix, *t_pos);
1456 continue_packet_error =
true;
1461 for (tid_sig_collection::const_iterator
1464 s_pos != s_end; ++s_pos)
1465 continue_packet.
Format(
";S{0:x-2}:{1}{2:x-}", s_pos->second,
1466 pid_prefix, s_pos->first);
1468 continue_packet_error =
true;
1471 if (continue_packet_error)
1472 continue_packet.
Clear();
1475 continue_packet_error =
true;
1481 if (num_continue_c_tids > 0) {
1482 if (num_continue_c_tids == num_threads) {
1486 continue_packet_error =
false;
1487 }
else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
1488 num_continue_s_tids == 0 && num_continue_S_tids == 0) {
1492 continue_packet_error =
false;
1496 if (continue_packet_error && num_continue_C_tids > 0) {
1497 if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
1498 num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
1499 num_continue_S_tids == 0) {
1502 if (num_continue_C_tids > 1) {
1507 if (num_continue_C_tids > 1) {
1508 continue_packet_error =
false;
1511 continue_packet_error =
true;
1514 if (!continue_packet_error)
1518 continue_packet_error =
false;
1521 if (!continue_packet_error) {
1523 continue_packet.
Printf(
"C%2.2x", continue_signo);
1528 if (continue_packet_error && num_continue_s_tids > 0) {
1529 if (num_continue_s_tids == num_threads) {
1535 continue_packet_error =
false;
1536 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1537 num_continue_s_tids == 1 && num_continue_S_tids == 0) {
1541 continue_packet_error =
false;
1545 if (!continue_packet_error && num_continue_S_tids > 0) {
1546 if (num_continue_S_tids == num_threads) {
1549 continue_packet_error =
false;
1550 if (num_continue_S_tids > 1) {
1551 for (
size_t i = 1; i < num_threads; ++i) {
1553 continue_packet_error =
true;
1556 if (!continue_packet_error) {
1559 continue_packet.
Printf(
"S%2.2x", step_signo);
1561 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1562 num_continue_s_tids == 0 && num_continue_S_tids == 1) {
1566 continue_packet_error =
false;
1572 if (num_continue_s_tids > 0 || num_continue_S_tids > 0) {
1574 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1575 "support reverse-stepping");
1577 "target does not support reverse-stepping");
1580 if (num_continue_S_tids > 0) {
1583 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1585 "can't deliver signals while running in reverse");
1588 if (num_continue_s_tids > 1) {
1589 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: can't step multiple "
1590 "threads in reverse");
1592 "can't step multiple threads while reverse-stepping");
1598 if (!
m_gdb_comm.GetReverseContinueSupported()) {
1599 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1600 "support reverse-continue");
1602 "target does not support reverse execution of processes");
1605 if (num_continue_C_tids > 0) {
1608 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1610 "can't deliver signals while running in reverse");
1618 continue_packet_error =
false;
1621 if (continue_packet_error) {
1623 "can't make continue packet for this resume");
1628 "Trying to resume but the async thread is dead.");
1629 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Trying to resume but the "
1630 "async thread is dead.");
1635 std::make_shared<EventDataBytes>(continue_packet.
GetString());
1638 if (!listener_sp->GetEvent(event_sp, ResumeTimeout())) {
1640 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Resume timed out.");
1643 "Broadcast continue, but the async thread was "
1644 "killed before we got an ack back.");
1646 "ProcessGDBRemote::DoResume: Broadcast continue, but the "
1647 "async thread was killed before we got an ack back.");
1663 llvm::StringRef value) {
1669 auto pid_tid = thread_ids.
GetPidTid(pid);
1670 if (pid_tid && pid_tid->first == pid) {
1676 }
while (thread_ids.
GetChar() ==
',');
1682 llvm::StringRef value) {
1684 for (llvm::StringRef x : llvm::split(value,
',')) {
1686 if (llvm::to_integer(x,
pc, 16))
1696 if (threads_info_sp) {
1699 if (thread_infos && thread_infos->
GetSize() > 0) {
1723 const llvm::StringRef stop_info_str = stop_info.
GetStringRef();
1726 const size_t thread_pcs_pos = stop_info_str.find(
";thread-pcs:");
1727 if (thread_pcs_pos != llvm::StringRef::npos) {
1728 const size_t start = thread_pcs_pos + strlen(
";thread-pcs:");
1729 const size_t end = stop_info_str.find(
';', start);
1730 if (end != llvm::StringRef::npos) {
1731 llvm::StringRef value = stop_info_str.substr(start, end - start);
1736 const size_t threads_pos = stop_info_str.find(
";threads:");
1737 if (threads_pos != llvm::StringRef::npos) {
1738 const size_t start = threads_pos + strlen(
";threads:");
1739 const size_t end = stop_info_str.find(
';', start);
1740 if (end != llvm::StringRef::npos) {
1741 llvm::StringRef value = stop_info_str.substr(start, end - start);
1749 bool sequence_mutex_unavailable =
false;
1751 if (sequence_mutex_unavailable) {
1766 if (num_thread_ids == 0) {
1772 ThreadList old_thread_list_copy(old_thread_list);
1773 if (num_thread_ids > 0) {
1774 for (
size_t i = 0; i < num_thread_ids; ++i) {
1781 thread_sp.get(), thread_sp->GetID());
1784 thread_sp.get(), thread_sp->GetID());
1794 size_t old_num_thread_ids = old_thread_list_copy.
GetSize(
false);
1795 for (
size_t i = 0; i < old_num_thread_ids; i++) {
1797 if (old_thread_sp) {
1798 lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
1813 uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1838 return std::nullopt;
1846 if (thread_infos_sp) {
1850 const size_t n = thread_infos->
GetSize();
1851 for (
size_t i = 0; i < n; ++i) {
1857 if (tid == thread->GetID())
1859 thread->shared_from_this());
1884 addr_t pc = thread->GetRegisterContext()->GetPC();
1886 thread->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1888 thread->SetThreadStoppedAtUnexecutedBP(
pc);
1896 if (
GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
1906 for (
const auto &pair : expedited_register_map) {
1907 uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1917 reg_value_extractor.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
1925 uint8_t signo,
const std::string &thread_name,
const std::string &reason,
1926 const std::string &description, uint32_t exc_type,
1927 const std::vector<addr_t> &exc_data,
addr_t thread_dispatch_qaddr,
1928 bool queue_vars_valid,
1930 LazyBool associated_with_dispatch_queue,
addr_t dispatch_queue_t,
1931 std::string &queue_name,
QueueKind queue_kind, uint64_t queue_serial,
1932 std::vector<lldb::addr_t> &added_binaries,
1940 if (!thread_sp || thread_sp->GetProtocolID() != tid) {
1957 reg_ctx_sp->InvalidateIfNeeded(
true);
1964 if (reg_ctx_sp->ReconfigureRegisterInfo()) {
1967 reg_ctx_sp->InvalidateAllRegisters();
1974 thread_sp->SetName(thread_name.empty() ?
nullptr : thread_name.c_str());
1979 if (queue_vars_valid)
1980 gdb_thread->
SetQueueInfo(std::move(queue_name), queue_kind, queue_serial,
1981 dispatch_queue_t, associated_with_dispatch_queue);
1995 StopInfoSP current_stop_info_sp = thread_sp->GetPrivateStopInfo(
false);
1997 current_stop_info_sp) {
1998 thread_sp->SetStopInfo(current_stop_info_sp);
2002 if (!thread_sp->StopInfoIsUpToDate()) {
2005 addr_t pc = thread_sp->GetRegisterContext()->GetPC();
2007 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
2009 thread_sp->SetThreadStoppedAtUnexecutedBP(
pc);
2011 if (exc_type != 0) {
2019 if (interrupt_thread)
2020 thread_sp = interrupt_thread;
2022 const size_t exc_data_size = exc_data.size();
2023 thread_sp->SetStopInfo(
2025 *thread_sp, exc_type, exc_data_size,
2026 exc_data_size >= 1 ? exc_data[0] : 0,
2027 exc_data_size >= 2 ? exc_data[1] : 0,
2028 exc_data_size >= 3 ? exc_data[2] : 0));
2031 bool handled =
false;
2032 bool did_exec =
false;
2035 if (!reason.empty() && reason !=
"none") {
2036 if (reason ==
"trace") {
2039 }
else if (reason ==
"breakpoint") {
2040 thread_sp->SetThreadHitBreakpointSite();
2048 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2049 thread_sp->SetStopInfo(
2051 *thread_sp, bp_site_sp->GetID()));
2054 thread_sp->SetStopInfo(invalid_stop_info_sp);
2057 }
else if (reason ==
"trap") {
2059 }
else if (reason ==
"watchpoint") {
2095 bool silently_continue =
false;
2105 silently_continue =
true;
2109 if (!wp_resource_sp) {
2111 LLDB_LOGF(log,
"failed to find watchpoint");
2118 watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
2121 *thread_sp, watch_id, silently_continue));
2123 }
else if (reason ==
"exception") {
2125 *thread_sp, description.c_str()));
2127 }
else if (reason ==
"history boundary") {
2129 *thread_sp, description.c_str()));
2131 }
else if (reason ==
"exec") {
2133 thread_sp->SetStopInfo(
2136 }
else if (reason ==
"processor trace") {
2138 *thread_sp, description.c_str()));
2139 }
else if (reason ==
"fork") {
2144 thread_sp->SetStopInfo(
2147 }
else if (reason ==
"vfork") {
2153 *thread_sp, child_pid, child_tid));
2155 }
else if (reason ==
"vforkdone") {
2156 thread_sp->SetStopInfo(
2159 }
else if (reason ==
"dyld") {
2163 "failed to load modules: {0}");
2165 thread_sp->SetStopInfo(
2171 if (!handled && signo && !did_exec) {
2192 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
2202 thread_sp->SetThreadHitBreakpointSite();
2204 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2206 thread_sp->GetRegisterContext()->SetPC(
pc);
2207 thread_sp->SetStopInfo(
2209 *thread_sp, bp_site_sp->GetID()));
2212 thread_sp->SetStopInfo(invalid_stop_info_sp);
2218 thread_sp->SetStopInfo(
2222 *thread_sp, signo, description.c_str()));
2233 if (interrupt_thread)
2234 thread_sp = interrupt_thread;
2237 *thread_sp, signo, description.c_str()));
2241 if (!description.empty()) {
2244 const char *stop_info_desc = stop_info_sp->GetDescription();
2245 if (!stop_info_desc || !stop_info_desc[0])
2246 stop_info_sp->SetDescription(description.c_str());
2249 *thread_sp, description.c_str()));
2259 const std::string &description) {
2268 *thread_sp, signo, description.c_str()));
2278 static constexpr llvm::StringLiteral g_key_tid(
"tid");
2279 static constexpr llvm::StringLiteral g_key_name(
"name");
2280 static constexpr llvm::StringLiteral g_key_reason(
"reason");
2281 static constexpr llvm::StringLiteral g_key_metype(
"metype");
2282 static constexpr llvm::StringLiteral g_key_medata(
"medata");
2283 static constexpr llvm::StringLiteral g_key_qaddr(
"qaddr");
2284 static constexpr llvm::StringLiteral g_key_dispatch_queue_t(
2285 "dispatch_queue_t");
2286 static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(
2287 "associated_with_dispatch_queue");
2288 static constexpr llvm::StringLiteral g_key_queue_name(
"qname");
2289 static constexpr llvm::StringLiteral g_key_queue_kind(
"qkind");
2290 static constexpr llvm::StringLiteral g_key_queue_serial_number(
"qserialnum");
2291 static constexpr llvm::StringLiteral g_key_registers(
"registers");
2292 static constexpr llvm::StringLiteral g_key_memory(
"memory");
2293 static constexpr llvm::StringLiteral g_key_description(
"description");
2294 static constexpr llvm::StringLiteral g_key_signal(
"signal");
2295 static constexpr llvm::StringLiteral g_key_added_binaries(
"added-binaries");
2296 static constexpr llvm::StringLiteral g_key_detailed_binaries_info(
2297 "detailed-binaries-info");
2302 std::string thread_name;
2304 std::string description;
2305 uint32_t exc_type = 0;
2306 std::vector<addr_t> exc_data;
2309 bool queue_vars_valid =
false;
2312 std::string queue_name;
2314 uint64_t queue_serial_number = 0;
2315 std::vector<addr_t> added_binaries;
2321 thread_dict->
ForEach([
this, &tid, &expedited_register_map, &thread_name,
2322 &signo, &reason, &description, &exc_type, &exc_data,
2323 &thread_dispatch_qaddr, &queue_vars_valid,
2324 &associated_with_dispatch_queue, &dispatch_queue_t,
2325 &queue_name, &queue_kind, &queue_serial_number,
2326 &added_binaries, &detailed_binaries_info](
2327 llvm::StringRef key,
2329 if (key == g_key_tid) {
2332 }
else if (key == g_key_metype) {
2334 exc_type =
object->GetUnsignedIntegerValue(0);
2335 }
else if (key == g_key_medata) {
2340 exc_data.push_back(object->GetUnsignedIntegerValue());
2344 }
else if (key == g_key_name) {
2345 thread_name = std::string(object->GetStringValue());
2346 }
else if (key == g_key_qaddr) {
2347 thread_dispatch_qaddr =
2349 }
else if (key == g_key_queue_name) {
2350 queue_vars_valid =
true;
2351 queue_name = std::string(object->GetStringValue());
2352 }
else if (key == g_key_queue_kind) {
2353 std::string queue_kind_str = std::string(object->GetStringValue());
2354 if (queue_kind_str ==
"serial") {
2355 queue_vars_valid =
true;
2357 }
else if (queue_kind_str ==
"concurrent") {
2358 queue_vars_valid =
true;
2361 }
else if (key == g_key_queue_serial_number) {
2362 queue_serial_number =
object->GetUnsignedIntegerValue(0);
2363 if (queue_serial_number != 0)
2364 queue_vars_valid =
true;
2365 }
else if (key == g_key_dispatch_queue_t) {
2366 dispatch_queue_t =
object->GetUnsignedIntegerValue(0);
2368 queue_vars_valid =
true;
2369 }
else if (key == g_key_associated_with_dispatch_queue) {
2370 queue_vars_valid =
true;
2371 bool associated =
object->GetBooleanValue();
2376 }
else if (key == g_key_reason) {
2377 reason = std::string(object->GetStringValue());
2378 }
else if (key == g_key_description) {
2379 description = std::string(object->GetStringValue());
2380 }
else if (key == g_key_registers) {
2383 if (registers_dict) {
2385 [&expedited_register_map](llvm::StringRef key,
2388 if (llvm::to_integer(key, reg))
2389 expedited_register_map[reg] =
2390 std::string(object->GetStringValue());
2394 }
else if (key == g_key_memory) {
2400 if (mem_cache_dict) {
2403 "address", mem_cache_addr)) {
2405 llvm::StringRef str;
2410 const size_t byte_size = bytes.
GetStringRef().size() / 2;
2413 const size_t bytes_copied =
2415 if (bytes_copied == byte_size)
2424 }
else if (key == g_key_signal)
2426 else if (key == g_key_added_binaries) {
2429 array->
ForEach([&added_binaries](
2432 object->GetAsUnsignedInteger();
2436 added_binaries.push_back(value);
2441 }
else if (key == g_key_detailed_binaries_info) {
2446 if (object->GetAsDictionary()) {
2448 object->Dump(json_str);
2449 detailed_binaries_info =
2457 tid, expedited_register_map, signo, thread_name, reason, description,
2458 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2459 associated_with_dispatch_queue, dispatch_queue_t, queue_name, queue_kind,
2460 queue_serial_number, added_binaries, detailed_binaries_info,
2461 std::move(thread_sp));
2467 const char stop_type = stop_packet.
GetChar();
2468 switch (stop_type) {
2487 const uint8_t signo = stop_packet.
GetHexU8();
2488 llvm::StringRef key;
2489 llvm::StringRef value;
2490 std::string thread_name;
2492 std::string description;
2493 std::vector<addr_t> added_binaries;
2495 uint32_t exc_type = 0;
2496 std::vector<addr_t> exc_data;
2498 bool queue_vars_valid =
2502 std::string queue_name;
2504 uint64_t queue_serial_number = 0;
2508 if (key.compare(
"metype") == 0) {
2510 value.getAsInteger(
BASE_16, exc_type);
2511 }
else if (key.compare(
"medata") == 0) {
2514 value.getAsInteger(
BASE_16, x);
2515 exc_data.push_back(x);
2516 }
else if (key.compare(
"thread") == 0) {
2519 auto pid_tid = thread_id.
GetPidTid(pid);
2521 stop_pid = pid_tid->first;
2522 tid = pid_tid->second;
2525 }
else if (key.compare(
"threads") == 0) {
2526 std::lock_guard<std::recursive_mutex> guard(
2529 }
else if (key.compare(
"thread-pcs") == 0) {
2534 while (!value.empty()) {
2535 llvm::StringRef pc_str;
2536 std::tie(pc_str, value) = value.split(
',');
2541 }
else if (key.compare(
"jstopinfo") == 0) {
2550 }
else if (key.compare(
"hexname") == 0) {
2554 }
else if (key.compare(
"name") == 0) {
2555 thread_name = std::string(value);
2556 }
else if (key.compare(
"qaddr") == 0) {
2557 value.getAsInteger(
BASE_16, thread_dispatch_qaddr);
2558 }
else if (key.compare(
"dispatch_queue_t") == 0) {
2559 queue_vars_valid =
true;
2560 value.getAsInteger(
BASE_16, dispatch_queue_t);
2561 }
else if (key.compare(
"qname") == 0) {
2562 queue_vars_valid =
true;
2566 }
else if (key.compare(
"qkind") == 0) {
2567 queue_kind = llvm::StringSwitch<QueueKind>(value)
2572 }
else if (key.compare(
"qserialnum") == 0) {
2573 if (!value.getAsInteger(
BASE_10, queue_serial_number))
2574 queue_vars_valid =
true;
2575 }
else if (key.compare(
"reason") == 0) {
2576 reason = std::string(value);
2577 }
else if (key.compare(
"description") == 0) {
2581 }
else if (key.compare(
"memory") == 0) {
2595 llvm::StringRef addr_str, bytes_str;
2596 std::tie(addr_str, bytes_str) = value.split(
'=');
2597 if (!addr_str.empty() && !bytes_str.empty()) {
2604 const size_t bytes_copied =
2606 if (bytes_copied == byte_size)
2610 }
else if (key.compare(
"watch") == 0 || key.compare(
"rwatch") == 0 ||
2611 key.compare(
"awatch") == 0) {
2614 value.getAsInteger(
BASE_16, wp_addr);
2622 reason =
"watchpoint";
2624 ostr.
Printf(
"%" PRIu64, wp_addr);
2625 description = std::string(ostr.
GetString());
2626 }
else if (key.compare(
"swbreak") == 0 || key.compare(
"hwbreak") == 0) {
2627 reason =
"breakpoint";
2628 }
else if (key.compare(
"replaylog") == 0) {
2629 reason =
"history boundary";
2630 }
else if (key.compare(
"library") == 0) {
2636 }
else if (key.compare(
"fork") == 0 || key.compare(
"vfork") == 0) {
2642 LLDB_LOG(log,
"Invalid PID/TID to fork: {0}", value);
2648 ostr.
Printf(
"%" PRIu64
" %" PRIu64, pid_tid->first, pid_tid->second);
2649 description = std::string(ostr.
GetString());
2650 }
else if (key.compare(
"addressing_bits") == 0) {
2651 uint64_t addressing_bits;
2652 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2655 }
else if (key.compare(
"low_mem_addressing_bits") == 0) {
2656 uint64_t addressing_bits;
2657 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2660 }
else if (key.compare(
"high_mem_addressing_bits") == 0) {
2661 uint64_t addressing_bits;
2662 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2665 }
else if (key ==
"added-binaries") {
2669 while (!value.empty()) {
2670 llvm::StringRef pc_str;
2671 std::tie(pc_str, value) = value.split(
',');
2674 added_binaries.push_back(
pc);
2676 }
else if (key ==
"detailed-binaries-info") {
2684 }
else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
2686 if (!key.getAsInteger(
BASE_16, reg))
2687 expedited_register_map[reg] = std::string(std::move(value));
2697 "Received stop for incorrect PID = {0} (inferior PID = {1})",
2719 tid, expedited_register_map, signo, thread_name, reason, description,
2720 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2721 associated_with_dispatch_queue, dispatch_queue_t, queue_name,
2722 queue_kind, queue_serial_number, added_binaries,
2723 detailed_binaries_info);
2771 if (!selected_thread_sp ||
2772 selected_thread_sp->GetID() != primary_thread_sp->GetID())
2773 m_thread_list.SetSelectedThreadByID(primary_thread_sp->GetID());
2800 LLDB_LOGF(log,
"ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
2804 if (
error.Success())
2806 "ProcessGDBRemote::DoDetach() detach packet sent successfully");
2809 "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
2810 error.AsCString() ?
error.AsCString() :
"<unknown error>");
2813 if (!
error.Success())
2828 LLDB_LOGF(log,
"ProcessGDBRemote::DoDestroy()");
2831 int exit_status = SIGABRT;
2832 std::string exit_string;
2839 exit_status = kill_res.get();
2840#if defined(__APPLE__)
2852 if (platform_sp && platform_sp->IsHost()) {
2855 reap_pid = waitpid(
GetID(), &status, WNOHANG);
2856 LLDB_LOGF(log,
"Reaped pid: %d, status: %d.\n", reap_pid, status);
2860 exit_string.assign(
"killed");
2862 exit_string.assign(llvm::toString(kill_res.takeError()));
2865 exit_string.assign(
"killed or interrupted while attaching.");
2871 exit_string.assign(
"destroying when not connected to debugserver");
2892 const bool did_exec =
2893 response.
GetStringRef().find(
";reason:exec;") != std::string::npos;
2896 LLDB_LOGF(log,
"ProcessGDBRemote::SetLastStopPacket () - detected exec");
2901 m_gdb_comm.ResetDiscoverableSettings(did_exec);
2926 LLDB_LOG_ERROR(log, list.takeError(),
"Failed to read module list: {0}.");
2928 addr = list->m_link_map;
2944 if (threads_info_sp) {
2949 std::unordered_map<lldb::tid_t, ThreadSP> threads;
2951 threads.try_emplace(thread_sp->GetProtocolID(), thread_sp);
2952 const size_t n = thread_infos->
GetSize();
2953 for (
size_t i = 0; i < n; ++i) {
2960 auto thread = threads.find(tid);
2962 thread == threads.end() ?
nullptr : thread->second);
2982 xPacketState x_state =
m_gdb_comm.GetxPacketState();
2985 size_t max_memory_size = x_state != xPacketState::Unimplemented
2988 if (size > max_memory_size) {
2992 size = max_memory_size;
3005 llvm::formatv(
";address_space:{0};", llvm::utohexstr(addr_space,
true));
3006 if (info->is_thread_specific) {
3007 std::optional<lldb::tid_t> tid = process_addr.
GetThreadID();
3010 "address space \"%s\" is thread specific, but no thread was "
3012 info->name.c_str());
3015 suffix += llvm::formatv(
"thread:{0};", llvm::utohexstr(*tid,
true));
3021 ::snprintf(packet,
sizeof(packet),
"%c%" PRIx64
",%" PRIx64
"%s",
3022 x_state != xPacketState::Unimplemented ?
'x' :
'm',
3023 (uint64_t)addr, (uint64_t)size, suffix.c_str());
3024 assert(packet_len + 1 < (
int)
sizeof(packet));
3027 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
3032 if (x_state != xPacketState::Unimplemented) {
3037 llvm::StringRef data_received = response.
GetStringRef();
3038 if (x_state == xPacketState::Prefixed &&
3039 !data_received.consume_front(
"b")) {
3041 "unexpected response to GDB server memory read packet '{0}': "
3043 packet, data_received);
3048 size_t memcpy_size = std::min(size, data_received.size());
3049 memcpy(buf, data_received.data(), memcpy_size);
3053 llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size),
'\xdd');
3057 "memory read failed for 0x%" PRIx64, addr);
3060 "GDB server does not support reading memory");
3063 "unexpected response to GDB server memory read packet '%s': '%s'",
3075 uint64_t max_packet_size,
3079 constexpr uint64_t range_overhead = 33;
3080 uint64_t current_size = 0;
3081 for (
auto [idx, range] : llvm::enumerate(ranges)) {
3082 uint64_t potential_size = current_size + range.size + range_overhead;
3083 if (potential_size > max_packet_size) {
3086 "MultiMemRead input has a range (base = {0:x}, size = {1}) "
3087 "bigger than the maximum allowed by remote",
3088 range.base, range.size);
3092 return ranges.size();
3095llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>
3098 llvm::MutableArrayRef<uint8_t> buffer) {
3102 const llvm::ArrayRef<Range<lldb::addr_t, size_t>> original_ranges = ranges;
3103 llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> memory_regions;
3105 while (!ranges.empty()) {
3106 uint64_t num_ranges =
3108 if (num_ranges == 0)
3111 auto ranges_for_request = ranges.take_front(num_ranges);
3112 ranges = ranges.drop_front(num_ranges);
3114 llvm::Expected<StringExtractorGDBRemote> response =
3118 "MultiMemRead error response: {0}");
3122 llvm::StringRef response_str = response->GetStringRef();
3123 const unsigned expected_num_ranges = ranges_for_request.size();
3125 response_str, buffer, expected_num_ranges, memory_regions)) {
3127 "MultiMemRead error parsing response: {0}");
3131 return memory_regions;
3134llvm::Expected<StringExtractorGDBRemote>
3137 std::string packet_str;
3138 llvm::raw_string_ostream stream(packet_str);
3139 stream <<
"MultiMemRead:ranges:";
3141 auto range_to_stream = [&](
auto range) {
3143 stream << llvm::formatv(
"{0:x-},{1:x-}", range.base, range.size);
3145 llvm::interleave(ranges, stream, range_to_stream,
",");
3150 m_gdb_comm.SendPacketAndWaitForResponse(packet_str.data(), response,
3153 return llvm::createStringErrorV(
"MultiMemRead failed to send packet: '{0}'",
3157 return llvm::createStringErrorV(
"MultiMemRead failed: '{0}'",
3161 return llvm::createStringErrorV(
"MultiMemRead unexpected response: '{0}'",
3168 llvm::StringRef response_str, llvm::MutableArrayRef<uint8_t> buffer,
3169 unsigned expected_num_ranges,
3172 auto [sizes_str, memory_data] = response_str.split(
';');
3173 if (sizes_str.size() == response_str.size())
3174 return llvm::createStringErrorV(
3175 "MultiMemRead response missing field separator ';' in: '{0}'",
3179 unsigned num_sizes = 0;
3180 for (llvm::StringRef size_str : llvm::split(sizes_str,
',')) {
3182 if (size_str.getAsInteger(
BASE_16, read_size))
3183 return llvm::createStringErrorV(
3184 "MultiMemRead response has invalid size string: {0}", size_str);
3186 if (memory_data.size() < read_size)
3187 return llvm::createStringErrorV(
"MultiMemRead response did not have "
3188 "enough data, requested sizes: {0}",
3191 if (read_size > buffer.size())
3192 return llvm::createStringErrorV(
3193 "MultiMemRead response size {0} exceeds remaining buffer {1}",
3194 read_size, buffer.size());
3196 llvm::StringRef region_to_read = memory_data.take_front(read_size);
3197 memory_data = memory_data.drop_front(read_size);
3199 llvm::MutableArrayRef<uint8_t> region_to_write =
3200 buffer.take_front(read_size);
3201 buffer = buffer.drop_front(read_size);
3203 memcpy(region_to_write.data(), region_to_read.data(), read_size);
3204 memory_regions.push_back(region_to_write);
3208 if (num_sizes != expected_num_ranges)
3209 return llvm::createStringErrorV(
3210 "MultiMemRead response had {0} sizes, expected {1}", num_sizes,
3211 expected_num_ranges);
3213 return llvm::Error::success();
3217 return m_gdb_comm.GetMemoryTaggingSupported();
3220llvm::Expected<std::vector<uint8_t>>
3227 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3228 "Error reading memory tags from remote");
3232 llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
3233 std::vector<uint8_t> got;
3234 got.reserve(tag_data.size());
3235 std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
3241 const std::vector<uint8_t> &tags) {
3244 return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
3248 std::vector<ObjectFile::LoadableData> entries) {
3258 if (
error.Success())
3272 for (
size_t i = 0; i < size; ++i)
3297 if (blocksize == 0) {
3305 lldb::addr_t block_start_addr = addr - (addr % blocksize);
3306 size += (addr - block_start_addr);
3307 if ((size % blocksize) != 0)
3308 size += (blocksize - size % blocksize);
3324 auto overlap = last_range.GetRangeEnd() - range.
GetRangeBase();
3345 "flash erase failed for 0x%" PRIx64, addr);
3348 "GDB server does not support flashing");
3351 "unexpected response to GDB server flash erase packet '%s': '%s'",
3368 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"vFlashDone", response,
3378 "GDB server does not support flashing");
3381 "unexpected response to GDB server flash done packet: '%s'",
3396 if (size > max_memory_size) {
3400 size = max_memory_size;
3420 if (!
error.Success())
3422 packet.
Printf(
"vFlashWrite:%" PRIx64
":", addr);
3425 packet.
Printf(
"M%" PRIx64
",%" PRIx64
":", addr, (uint64_t)size);
3438 "memory write failed for 0x%" PRIx64, addr);
3441 "GDB server does not support writing memory");
3444 "unexpected response to GDB server memory write packet '%s': '%s'",
3457 ePermissionsWritable |
3458 ePermissionsExecutable);
3470 ConstString(
"mmap"), eFunctionNameTypeFull, options, sc_list);
3475 uint32_t permissions,
3481 allocated_addr =
m_gdb_comm.AllocateMemory(size, permissions);
3484 return allocated_addr;
3490 if (permissions & lldb::ePermissionsReadable)
3492 if (permissions & lldb::ePermissionsWritable)
3494 if (permissions & lldb::ePermissionsExecutable)
3503 "ProcessGDBRemote::%s no direct stub support for memory "
3504 "allocation, and InferiorCallMmap also failed - is stub "
3505 "missing register context save/restore capability?",
3512 "unable to allocate %" PRIu64
" bytes of memory with permissions %s",
3516 return allocated_addr;
3531 return m_gdb_comm.GetWatchpointReportedAfter();
3538 switch (supported) {
3543 "tried to deallocate memory without ever allocating memory");
3549 "unable to deallocate memory at 0x%" PRIx64, addr);
3561 "unable to deallocate memory at 0x%" PRIx64, addr);
3594 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3596 if (error_no == 0) {
3599 return llvm::Error::success();
3602 if (error_no != UINT8_MAX)
3603 return llvm::createStringErrorV(
3604 "error sending the breakpoint request: {0}", error_no);
3605 return llvm::createStringError(
"error sending the breakpoint request");
3607 LLDB_LOG(log,
"Software breakpoints are unsupported");
3612 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3614 if (error_no == 0) {
3617 return llvm::Error::success();
3620 if (error_no != UINT8_MAX)
3621 return llvm::createStringErrorV(
3622 "error sending the hardware breakpoint request: {0} "
3623 "(hardware breakpoint resources might be exhausted or unavailable)",
3625 return llvm::createStringError(
3626 "error sending the hardware breakpoint request "
3627 "(hardware breakpoint resources might be exhausted or unavailable)");
3629 LLDB_LOG(log,
"Hardware breakpoints are unsupported");
3633 return llvm::createStringError(
"hardware breakpoints are not supported");
3649 return error.takeError();
3655 return llvm::createStringError(
"unknown error");
3660 return llvm::createStringError(
"unknown error");
3664 return llvm::Error::success();
3668 assert(bp_site !=
nullptr);
3679 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3680 ") address = 0x%" PRIx64,
3681 site_id, (uint64_t)addr);
3686 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3687 ") address = 0x%" PRIx64
" -- SUCCESS (already enabled)",
3688 site_id, (uint64_t)addr);
3696 assert(bp_site !=
nullptr);
3701 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3702 ") addr = 0x%8.8" PRIx64,
3703 site_id, (uint64_t)addr);
3707 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3708 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3709 site_id, (uint64_t)addr);
3720 bool read = wp_res_sp->WatchpointResourceRead();
3721 bool write = wp_res_sp->WatchpointResourceWrite();
3723 assert((read || write) &&
3724 "WatchpointResource type is neither read nor write");
3740 addr_t addr = wp_sp->GetLoadAddress();
3742 LLDB_LOGF(log,
"ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
")",
3744 if (wp_sp->IsEnabled()) {
3746 "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
3747 ") addr = 0x%8.8" PRIx64
": watchpoint already enabled.",
3748 watchID, (uint64_t)addr);
3752 bool read = wp_sp->WatchpointRead();
3753 bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
3754 size_t size = wp_sp->GetByteSize();
3757 WatchpointHardwareFeature supported_features =
3760 std::vector<WatchpointResourceSP> resources =
3762 addr, size, read, write, supported_features, target_arch);
3787 bool set_all_resources =
true;
3788 std::vector<WatchpointResourceSP> succesfully_set_resources;
3789 for (
const auto &wp_res_sp : resources) {
3790 addr_t addr = wp_res_sp->GetLoadAddress();
3791 size_t size = wp_res_sp->GetByteSize();
3793 if (!
m_gdb_comm.SupportsGDBStoppointPacket(type) ||
3794 m_gdb_comm.SendGDBStoppointTypePacket(type,
true, addr, size,
3796 set_all_resources =
false;
3799 succesfully_set_resources.push_back(wp_res_sp);
3802 if (set_all_resources) {
3803 wp_sp->SetEnabled(
true, notify);
3804 for (
const auto &wp_res_sp : resources) {
3807 wp_res_sp->AddConstituent(wp_sp);
3815 for (
const auto &wp_res_sp : succesfully_set_resources) {
3816 addr_t addr = wp_res_sp->GetLoadAddress();
3817 size_t size = wp_res_sp->GetByteSize();
3819 m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3823 "Setting one of the watchpoint resources failed");
3839 addr_t addr = wp_sp->GetLoadAddress();
3842 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3843 ") addr = 0x%8.8" PRIx64,
3844 watchID, (uint64_t)addr);
3846 if (!wp_sp->IsEnabled()) {
3848 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3849 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3850 watchID, (uint64_t)addr);
3854 wp_sp->SetEnabled(
false, notify);
3858 if (wp_sp->IsHardware()) {
3859 bool disabled_all =
true;
3861 std::vector<WatchpointResourceSP> unused_resources;
3863 if (wp_res_sp->ConstituentsContains(wp_sp)) {
3865 addr_t addr = wp_res_sp->GetLoadAddress();
3866 size_t size = wp_res_sp->GetByteSize();
3867 if (
m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3869 disabled_all =
false;
3871 wp_res_sp->RemoveConstituent(wp_sp);
3872 if (wp_res_sp->GetNumberOfConstituents() == 0)
3873 unused_resources.push_back(wp_res_sp);
3877 for (
auto &wp_res_sp : unused_resources)
3880 wp_sp->SetEnabled(
false, notify);
3883 "Failure disabling one of the watchpoint locations");
3896 LLDB_LOGF(log,
"ProcessGDBRemote::DoSignal (signal = %d)", signo);
3911 if (platform_sp && !platform_sp->IsHost())
3916 const char *error_string =
error.AsCString();
3917 if (error_string ==
nullptr)
3926 static FileSpec g_debugserver_file_spec;
3933 std::string env_debugserver_path = host_env.lookup(
"LLDB_DEBUGSERVER_PATH");
3934 if (!env_debugserver_path.empty()) {
3935 debugserver_file_spec.
SetFile(env_debugserver_path,
3936 FileSpec::Style::native);
3937 LLDB_LOG(log,
"gdb-remote stub exe path set from environment variable: {0}",
3938 env_debugserver_path);
3940 debugserver_file_spec = g_debugserver_file_spec;
3942 return debugserver_file_spec;
3945 debugserver_file_spec = HostInfo::GetSupportExeDir();
3946 if (debugserver_file_spec) {
3949 LLDB_LOG(log,
"found gdb-remote stub exe '{0}'", debugserver_file_spec);
3951 g_debugserver_file_spec = debugserver_file_spec;
3954 if (!debugserver_file_spec) {
3957 LLDB_LOG(log,
"could not find gdb-remote stub exe '{0}'",
3958 debugserver_file_spec);
3962 g_debugserver_file_spec.
Clear();
3965 return debugserver_file_spec;
3970 using namespace std::placeholders;
3980 const std::weak_ptr<ProcessGDBRemote> this_wp =
3981 std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3988#if defined(__APPLE__)
3992 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
3994 struct kinfo_proc processInfo;
3995 size_t bufsize =
sizeof(processInfo);
3996 if (sysctl(mib, (
unsigned)(
sizeof(mib) /
sizeof(
int)), &processInfo, &bufsize,
3999 if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
4000 debugserver_path =
FileSpec(
"/Library/Apple/usr/libexec/oah/debugserver");
4007 "'. Please ensure it is properly installed "
4008 "and available in your PATH");
4023 debugserver_launch_info,
nullptr);
4028 LLDB_LOGF(log,
"failed to start debugserver process: %s",
4038 m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>(
4039 std::move(socket_pair->second)));
4053 std::weak_ptr<ProcessGDBRemote> process_wp,
lldb::pid_t debugserver_pid,
4062 "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
4063 ", signo=%i (0x%x), exit_status=%i)",
4064 __FUNCTION__, debugserver_pid, signo, signo, exit_status);
4066 std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
4067 LLDB_LOGF(log,
"ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
4068 static_cast<void *
>(process_sp.get()));
4069 if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
4075 std::this_thread::sleep_for(std::chrono::milliseconds(500));
4079 const StateType state = process_sp->GetState();
4088 llvm::StringRef signal_name =
4089 process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);
4091 if (!signal_name.empty())
4092 stream.
Format(format_str, signal_name);
4094 stream.
Format(format_str, signo);
4096 process_sp->SetExitStatus(-1, stream.
GetString());
4119 debugger, PluginProperties::GetSettingName())) {
4120 const bool is_global_setting =
true;
4123 "Properties for the gdb-remote process plug-in.", is_global_setting);
4130 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
4137 llvm::Expected<HostThread> async_thread =
4141 if (!async_thread) {
4143 "failed to launch host thread: {0}");
4149 "ProcessGDBRemote::%s () - Called when Async thread was "
4159 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
4174 "ProcessGDBRemote::%s () - Called when Async thread was not running.",
4180 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread starting...",
4181 __FUNCTION__,
GetID());
4199 "ProcessGDBRemote::%s(pid = %" PRIu64
4200 ") listener.WaitForEvent (NULL, event_sp)...",
4201 __FUNCTION__,
GetID());
4204 const uint32_t event_type = event_sp->GetType();
4207 "ProcessGDBRemote::%s(pid = %" PRIu64
4208 ") Got an event of type: %d...",
4209 __FUNCTION__,
GetID(), event_type);
4211 switch (event_type) {
4216 if (continue_packet) {
4217 const char *continue_cstr =
4218 (
const char *)continue_packet->
GetBytes();
4219 const size_t continue_cstr_len = continue_packet->
GetByteSize();
4221 "ProcessGDBRemote::%s(pid = %" PRIu64
4222 ") got eBroadcastBitAsyncContinue: %s",
4223 __FUNCTION__,
GetID(), continue_cstr);
4225 if (::strstr(continue_cstr,
"vAttach") ==
nullptr)
4232 llvm::StringRef(continue_cstr, continue_cstr_len),
4243 switch (stop_state) {
4256 int exit_status = response.
GetHexU8();
4257 std::string desc_string;
4259 llvm::StringRef desc_str;
4260 llvm::StringRef desc_token;
4262 if (desc_token !=
"description")
4277 if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4280 "System Integrity Protection");
4281 }
else if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4301 "ProcessGDBRemote::%s(pid = %" PRIu64
4302 ") got eBroadcastBitAsyncThreadShouldExit...",
4303 __FUNCTION__,
GetID());
4309 "ProcessGDBRemote::%s(pid = %" PRIu64
4310 ") got unknown event 0x%8.8x",
4311 __FUNCTION__,
GetID(), event_type);
4318 "ProcessGDBRemote::%s(pid = %" PRIu64
4319 ") listener.WaitForEvent (NULL, event_sp) => false",
4320 __FUNCTION__,
GetID());
4325 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread exiting...",
4326 __FUNCTION__,
GetID());
4358 LLDB_LOGF(log,
"Hit New Thread Notification breakpoint.");
4365class AcceleratorBreakpointCallbackBaton
4366 :
public TypedBaton<AcceleratorBreakpointHitArgs> {
4368 explicit AcceleratorBreakpointCallbackBaton(
4369 std::unique_ptr<AcceleratorBreakpointHitArgs> data)
4388 "ProcessGDBRemote::HandleAcceleratorActions skipping already "
4389 "processed actions for plugin '{0}' with identifier {1}",
4391 return llvm::Error::success();
4408 return llvm::Error::success();
4418 std::string exe_path = connect_info.
exe_path.value_or(
"");
4422 &platform_options, accelerator_target_sp);
4424 return error.takeError();
4425 if (!accelerator_target_sp)
4426 return llvm::createStringError(
"failed to create accelerator target");
4428 llvm::scope_exit delete_accelerator_target([&] {
4430 accelerator_target_sp->Destroy();
4433 PlatformSP platform_sp = accelerator_target_sp->GetPlatform();
4435 return llvm::createStringErrorV(
4436 "no platform '{0}' compatible with triple '{1}' for the accelerator "
4441 std::shared_ptr<TargetGroupCPUAndAccelerators> group_sp =
4445 bool created_group = !group_sp;
4446 if (created_group) {
4449 "CPU and accelerator targets");
4452 llvm::scope_exit restore_target_group([&] {
4453 group_sp->RemoveTarget(accelerator_target_sp);
4454 if (created_group) {
4455 group_sp->RemoveTarget(native_target_sp);
4460 if (llvm::Error membership_error =
4462 return membership_error;
4463 if (llvm::Error membership_error = group_sp->AddTarget(
4465 return membership_error;
4469 ? platform_sp->ConnectProcessSynchronous(
4473 : platform_sp->ConnectProcess(connect_info.
connect_url,
4475 accelerator_target_sp.get(),
error);
4477 return error.takeError();
4479 return llvm::createStringError(
"failed to connect to the accelerator");
4481 restore_target_group.release();
4482 delete_accelerator_target.release();
4483 accelerator_target_sp->SetTargetSessionName(actions.
session_name);
4486 auto event_sp = std::make_shared<Event>(
4489 accelerator_target_sp));
4491 return llvm::Error::success();
4497 llvm::Error
error = llvm::Error::success();
4501 auto args_up = std::make_unique<AcceleratorBreakpointHitArgs>();
4503 args_up->breakpoint = bp;
4510 error = llvm::joinErrors(
4512 llvm::createStringErrorV(
4513 "accelerator breakpoint {0} specifies both a by_name and a "
4514 "by_address specification",
4522 bp_modules.
GetSize() ? &bp_modules :
nullptr,
4524 bp.
by_name->function_name.c_str(),
4525 eFunctionNameTypeFull,
4537 error = llvm::joinErrors(
4539 llvm::createStringErrorV(
4540 "accelerator breakpoint {0} has neither a by_name nor a "
4541 "by_address specification",
4547 error = llvm::joinErrors(
4549 llvm::createStringErrorV(
"failed to set accelerator breakpoint {0}",
4557 llvm::formatv(
"accelerator-plugin ({0})", actions.
plugin_name);
4558 bp_sp->SetBreakpointKind(kind.c_str());
4559 auto baton_sp = std::make_shared<AcceleratorBreakpointCallbackBaton>(
4560 std::move(args_up));
4588 for (
size_t i = 0; i < symbol_names.size(); ++i) {
4596 addr_t load_addr = sc.symbol->GetAddress().GetLoadAddress(&target);
4605 llvm::Expected<AcceleratorBreakpointHitResponse> response =
4609 "accelerator breakpoint hit notification failed: {0}");
4617 if (response->disable_bp) {
4619 bp_sp->SetEnabled(
false);
4624 if (response->actions) {
4628 std::string message = llvm::toString(std::move(
error));
4629 LLDB_LOG(log,
"failed to handle accelerator actions: {0}", message);
4631 "error: accelerator plugin '%s': %s\n",
4632 response->actions->plugin_name.c_str(), message.c_str());
4637 return !response->auto_resume_native;
4642 LLDB_LOG(log,
"Check if need to update ignored signals");
4656 LLDB_LOG(log,
"Signals' version hasn't changed. version={0}",
4661 auto signals_to_ignore =
4666 "Signals' version changed. old version={0}, new version={1}, "
4667 "signals ignored={2}, update result={3}",
4669 signals_to_ignore.size(),
error);
4671 if (
error.Success())
4686 platform_sp->SetThreadCreationBreakpoint(
GetTarget());
4689 log,
"Successfully created new thread notification breakpoint %i",
4694 LLDB_LOGF(log,
"Failed to create new thread notification breakpoint.");
4713 std::string plugin_name;
4714 if (std::optional<LLDBSettings> settings =
m_gdb_comm.GetLLDBSettings())
4715 plugin_name = settings->dyld_plugin_name;
4727 return_value =
m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
4728 if (return_value != 0) {
4731 "Sending events is not supported for this process.");
4741 if (
m_gdb_comm.GetQXferAuxvReadSupported()) {
4742 llvm::Expected<std::string> response =
m_gdb_comm.ReadExtFeature(
"auxv",
"");
4744 buf = std::make_shared<DataBufferHeap>(response->c_str(),
4745 response->length());
4756 if (
m_gdb_comm.GetThreadExtendedInfoSupported()) {
4762 args_dict->GetAsDictionary()->AddIntegerItem(
"thread", tid);
4765 packet <<
"jThreadExtendedInfo:";
4766 args_dict->Dump(packet,
false);
4773 packet << (char)(0x7d ^ 0x20);
4782 if (!response.
Empty()) {
4795 args_dict->GetAsDictionary()->AddIntegerItem(
"image_list_address",
4796 image_list_address);
4797 args_dict->GetAsDictionary()->AddIntegerItem(
"image_count", image_count);
4804 std::string info_level_str;
4806 info_level_str =
"address-only";
4808 info_level_str =
"address-name";
4810 info_level_str =
"address-name-uuid";
4812 info_level_str =
"full";
4814 return info_level_str;
4821 args_dict->GetAsDictionary()->AddBooleanItem(
"fetch_all_solibs",
true);
4823 args_dict->GetAsDictionary()->AddBooleanItem(
"report_load_commands",
false);
4825 if (!info_level_str.empty())
4826 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4827 info_level_str.c_str());
4834 const std::vector<lldb::addr_t> &load_addresses) {
4838 for (
auto addr : load_addresses)
4839 addresses->AddIntegerItem(addr);
4841 args_dict->GetAsDictionary()->AddItem(
"solib_addresses", addresses);
4844 if (!info_level_str.empty())
4845 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4846 info_level_str.c_str());
4856 if (
m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
4859 std::chrono::seconds(10));
4862 packet <<
"jGetLoadedDynamicLibrariesInfos:";
4863 args_dict->Dump(packet,
false);
4870 packet << (char)(0x7d ^ 0x20);
4879 if (!response.
Empty()) {
4892 if (
m_gdb_comm.GetDynamicLoaderProcessStateSupported()) {
4895 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"jGetDyldProcessState",
4901 if (!response.
Empty()) {
4916 if (*shared_cache_info || !
m_gdb_comm.GetSharedCacheInfoSupported())
4917 return *shared_cache_info;
4920 packet <<
"jGetSharedCacheInfo:";
4921 args_dict->Dump(packet,
false);
4930 if (response.
Empty())
4939 if (!dict->
HasKey(
"shared_cache_uuid"))
4941 llvm::StringRef uuid_str;
4943 uuid_str ==
"00000000-0000-0000-0000-000000000000")
4945 if (dict->
HasKey(
"shared_cache_path")) {
4959 HostInfo::SharedCacheIndexFiles(sc_path, uuid, sc_mode);
4962 *shared_cache_info = response_sp;
4965 return *shared_cache_info;
4970 return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
4983 const uint64_t reasonable_largeish_default = 128 * 1024;
4984 const uint64_t conservative_default = 512;
4987 uint64_t stub_max_size =
m_gdb_comm.GetRemoteMaxPacketSize();
4988 if (stub_max_size !=
UINT64_MAX && stub_max_size != 0) {
4994 if (stub_max_size > reasonable_largeish_default) {
4995 stub_max_size = reasonable_largeish_default;
5001 if (stub_max_size > 70)
5002 stub_max_size -= 32 + 32 + 6;
5007 LLDB_LOG(log,
"warning: Packet size is too small. "
5008 "LLDB may face problems while writing memory");
5019 uint64_t user_specified_max) {
5020 if (user_specified_max != 0) {
5048 module_spec = cached->second;
5049 return bool(module_spec);
5052 if (!
m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
5053 LLDB_LOGF(log,
"ProcessGDBRemote::%s - failed to get module info for %s:%s",
5054 __FUNCTION__, module_file_spec.
GetPath().c_str(),
5061 module_spec.
Dump(stream);
5062 LLDB_LOGF(log,
"ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
5063 __FUNCTION__, module_file_spec.
GetPath().c_str(),
5072 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
5073 auto module_specs =
m_gdb_comm.GetModulesInfo(module_file_specs, triple);
5075 for (
const FileSpec &spec : module_file_specs)
5080 triple.getTriple())] = spec;
5094typedef std::vector<std::string> stringVec;
5096typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
5097struct RegisterSetInfo {
5101typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
5103struct GdbServerTargetInfo {
5107 RegisterSetMap reg_set_map;
5110using RegisterTypeMap = llvm::StringMap<const RegisterType *>;
5113ParseEnumEvalues(
const XMLNode &enum_node) {
5127 std::map<uint64_t, RegisterTypeEnum::Enumerator> enumerators;
5130 "evalue", [&enumerators, &log](
const XMLNode &enumerator_node) {
5131 std::optional<llvm::StringRef> name;
5132 std::optional<uint64_t> value;
5135 [&name, &value, &log](
const llvm::StringRef &attr_name,
5136 const llvm::StringRef &attr_value) {
5137 if (attr_name ==
"name") {
5138 if (attr_value.size())
5141 LLDB_LOG(log,
"ProcessGDBRemote::ParseEnumEvalues "
5142 "Ignoring empty name in evalue");
5143 }
else if (attr_name ==
"value") {
5144 uint64_t parsed_value = 0;
5145 if (llvm::to_integer(attr_value, parsed_value))
5146 value = parsed_value;
5149 "ProcessGDBRemote::ParseEnumEvalues "
5150 "Invalid value \"{0}\" in "
5155 "ProcessGDBRemote::ParseEnumEvalues Ignoring "
5156 "unknown attribute "
5157 "\"{0}\" in evalue",
5165 enumerators.insert_or_assign(
5166 *value, RegisterTypeEnum::Enumerator(*value, name->str()));
5173 for (
auto [_, enumerator] : enumerators)
5174 final_enumerators.push_back(enumerator);
5176 return final_enumerators;
5180ParseEnums(XMLNode feature_node, RegisterTypeMap &feature_register_types,
5181 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5186 "enum", [log, &feature_register_types,
5187 &owned_register_types](
const XMLNode &enum_node) {
5191 const llvm::StringRef &attr_value) {
5192 if (attr_name ==
"id")
5210 ParseEnumEvalues(enum_node);
5211 if (!enumerators.empty()) {
5213 "ProcessGDBRemote::ParseEnums Found enum type \"{0}\"",
5216 std::make_unique<RegisterTypeEnum>(
id, enumerators);
5217 const RegisterTypeEnum *enum_type_ptr = enum_type.get();
5218 auto [it, inserted] =
5219 feature_register_types.try_emplace(
id, enum_type_ptr);
5221 owned_register_types.push_back(std::move(enum_type));
5222 }
else if (llvm::isa<RegisterTypeEnum>(it->second)) {
5227 owned_register_types.push_back(std::move(enum_type));
5228 it->second = enum_type_ptr;
5232 "ProcessGDBRemote::ParseEnums Ignoring enum type \"{0}\" "
5233 "because another type with that id already exists",
5244static std::vector<RegisterTypeFlags::Field>
5245ParseFlagsFields(XMLNode flags_node,
unsigned size,
5246 const RegisterTypeMap &feature_register_types) {
5248 const unsigned max_start_bit = size * 8 - 1;
5251 std::vector<RegisterTypeFlags::Field> fields;
5253 &feature_register_types](
5256 std::optional<llvm::StringRef> name;
5257 std::optional<unsigned> start;
5258 std::optional<unsigned> end;
5259 std::optional<llvm::StringRef> type;
5262 &log](
const llvm::StringRef &attr_name,
5263 const llvm::StringRef &attr_value) {
5266 if (attr_name ==
"name") {
5269 "ProcessGDBRemote::ParseFlagsFields Found field node name \"{0}\"",
5272 }
else if (attr_name ==
"start") {
5273 unsigned parsed_start = 0;
5274 if (llvm::to_integer(attr_value, parsed_start)) {
5275 if (parsed_start > max_start_bit) {
5277 "ProcessGDBRemote::ParseFlagsFields Invalid start {0} in "
5280 parsed_start, max_start_bit);
5282 start = parsed_start;
5286 "ProcessGDBRemote::ParseFlagsFields Invalid start \"{0}\" in "
5290 }
else if (attr_name ==
"end") {
5291 unsigned parsed_end = 0;
5292 if (llvm::to_integer(attr_value, parsed_end))
5293 if (parsed_end > max_start_bit) {
5295 "ProcessGDBRemote::ParseFlagsFields Invalid end {0} in "
5298 parsed_end, max_start_bit);
5303 "ProcessGDBRemote::ParseFlagsFields Invalid end \"{0}\" in "
5307 }
else if (attr_name ==
"type") {
5312 "ProcessGDBRemote::ParseFlagsFields Ignoring unknown attribute "
5313 "\"{0}\" in field node",
5320 if (name && start && end) {
5324 "ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
5325 "\"{2}\", ignoring",
5326 *start, *end, name->data());
5330 "ProcessGDBRemote::ParseFlagsFields Ignoring field \"{}\" "
5331 "that has size > 64 bits, this is not supported",
5335 const RegisterTypeEnum *enum_type =
nullptr;
5336 if (type && !type->empty()) {
5337 auto found = feature_register_types.find(*type);
5338 if (found != feature_register_types.end()) {
5339 enum_type = llvm::dyn_cast<RegisterTypeEnum>(found->second);
5343 "ProcessGDBRemote::ParseFlagsFields Type \"{0}\" for "
5344 "field \"{1}\" is not an enum, ignoring",
5345 type->data(), name->data());
5350 uint64_t max_value =
5353 if (enumerator.m_value > max_value) {
5354 enum_type =
nullptr;
5357 "ProcessGDBRemote::ParseFlagsFields In enum \"{0}\" "
5358 "evalue \"{1}\" with value {2} exceeds the maximum "
5359 "value of field \"{3}\" ({4}), ignoring enum",
5360 type->data(), enumerator.m_name, enumerator.m_value,
5361 name->data(), max_value);
5368 "ProcessGDBRemote::ParseFlagsFields Could not find type "
5370 "for field \"{1}\", ignoring",
5371 type->data(), name->data());
5376 RegisterTypeFlags::Field(name->str(), *start, *end, enum_type));
5387 XMLNode feature_node, RegisterTypeMap &feature_register_types,
5388 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5393 [&log, &feature_register_types,
5394 &owned_register_types](
const XMLNode &flags_node) ->
bool {
5395 LLDB_LOG(log,
"ProcessGDBRemote::ParseFlags Found flags node \"{0}\"",
5398 std::optional<llvm::StringRef>
id;
5399 std::optional<unsigned> size;
5401 [&
id, &size, &log](
const llvm::StringRef &name,
5402 const llvm::StringRef &value) {
5405 }
else if (name ==
"size") {
5406 unsigned parsed_size = 0;
5407 if (llvm::to_integer(value, parsed_size))
5411 "ProcessGDBRemote::ParseFlags Invalid size \"{0}\" "
5417 "ProcessGDBRemote::ParseFlags Ignoring unknown "
5418 "attribute \"{0}\" in flags node",
5426 std::vector<RegisterTypeFlags::Field> fields =
5427 ParseFlagsFields(flags_node, *size, feature_register_types);
5428 if (fields.size()) {
5430 std::sort(fields.rbegin(), fields.rend());
5431 std::vector<RegisterTypeFlags::Field>::const_iterator overlap =
5432 std::adjacent_find(fields.begin(), fields.end(),
5433 [](
const RegisterTypeFlags::Field &lhs,
5434 const RegisterTypeFlags::Field &rhs) {
5435 return lhs.Overlaps(rhs);
5439 if (overlap == fields.end()) {
5440 if (feature_register_types.contains(*
id)) {
5445 "ProcessGDBRemote::ParseFlags Definition of flags \"{0}\" "
5446 "conflicts with an existing type, ignoring this "
5450 auto flags_type = std::make_unique<RegisterTypeFlags>(
5451 id->str(), *size, std::move(fields));
5452 feature_register_types.try_emplace(*
id, flags_type.get());
5453 owned_register_types.push_back(std::move(flags_type));
5457 std::vector<RegisterTypeFlags::Field>::const_iterator next =
5461 "ProcessGDBRemote::ParseFlags Ignoring flags because fields "
5462 "{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) "
5464 overlap->GetName().c_str(), overlap->GetStart(),
5465 overlap->GetEnd(), next->GetName().c_str(), next->GetStart(),
5471 "ProcessGDBRemote::ParseFlags Ignoring definition of flags "
5472 "\"{0}\" because it contains no fields.",
5481static const RegisterTypeBuiltin *
5482ResolveGDBBuiltinType(llvm::StringRef type_name) {
5486 static const RegisterTypeBuiltin bool_type(
"bool",
eEncodingUint,
5488 static const RegisterTypeBuiltin int8_type(
"int8",
eEncodingSint,
5490 static const RegisterTypeBuiltin int16_type(
"int16",
eEncodingSint,
5492 static const RegisterTypeBuiltin int32_type(
"int32",
eEncodingSint,
5494 static const RegisterTypeBuiltin int64_type(
"int64",
eEncodingSint,
5496 static const RegisterTypeBuiltin int128_type(
"int128",
eEncodingSint,
5498 static const RegisterTypeBuiltin uint8_type(
"uint8",
eEncodingUint,
5500 static const RegisterTypeBuiltin uint16_type(
"uint16",
eEncodingUint,
5502 static const RegisterTypeBuiltin uint32_type(
"uint32",
eEncodingUint,
5504 static const RegisterTypeBuiltin uint64_type(
"uint64",
eEncodingUint,
5506 static const RegisterTypeBuiltin uint128_type(
"uint128",
eEncodingUint,
5508 static const RegisterTypeBuiltin code_ptr_type(
5510 static const RegisterTypeBuiltin data_ptr_type(
5512 static const RegisterTypeBuiltin ieee_half_type(
"ieee_half",
eEncodingIEEE754,
5514 static const RegisterTypeBuiltin ieee_single_type(
5516 static const RegisterTypeBuiltin ieee_double_type(
5518 static const RegisterTypeBuiltin i387_ext_type(
"i387_ext",
eEncodingIEEE754,
5520 static const RegisterTypeBuiltin bfloat16_type(
"bfloat16",
eEncodingIEEE754,
5523 return llvm::StringSwitch<const RegisterTypeBuiltin *>(type_name)
5524 .Case(
"bool", &bool_type)
5525 .Case(
"int8", &int8_type)
5526 .Case(
"int16", &int16_type)
5527 .Case(
"int32", &int32_type)
5528 .Case(
"int64", &int64_type)
5529 .Case(
"int128", &int128_type)
5530 .Case(
"uint8", &uint8_type)
5531 .Case(
"uint16", &uint16_type)
5532 .Case(
"uint32", &uint32_type)
5533 .Case(
"uint64", &uint64_type)
5534 .Case(
"uint128", &uint128_type)
5535 .Case(
"code_ptr", &code_ptr_type)
5536 .Case(
"data_ptr", &data_ptr_type)
5537 .Case(
"ieee_half", &ieee_half_type)
5538 .Case(
"ieee_single", &ieee_single_type)
5539 .Case(
"ieee_double", &ieee_double_type)
5540 .Case(
"i387_ext", &i387_ext_type)
5541 .Case(
"bfloat16", &bfloat16_type)
5545static const RegisterType *
5546ResolveGDBType(llvm::StringRef type_name,
5547 const RegisterTypeMap &feature_register_types) {
5548 auto type_it = feature_register_types.find(type_name);
5549 if (type_it != feature_register_types.end())
5550 return type_it->second;
5551 return ResolveGDBBuiltinType(type_name);
5555ParseVector(
const XMLNode &vector_node, RegisterTypeMap &feature_register_types,
5556 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5558 std::optional<llvm::StringRef>
id;
5559 std::optional<llvm::StringRef> element_type_name;
5560 std::optional<uint32_t> count;
5563 [&
id, &element_type_name, &count, log](llvm::StringRef name,
5564 llvm::StringRef value) {
5567 }
else if (name ==
"type") {
5568 element_type_name = value;
5569 }
else if (name ==
"count") {
5570 uint32_t parsed_count = 0;
5571 if (llvm::to_integer(value, parsed_count))
5572 count = parsed_count;
5574 LLDB_LOG(log,
"ProcessGDBRemote::ParseVector Invalid count \"{0}\"",
5578 "ProcessGDBRemote::ParseVector Ignoring unknown attribute "
5588 if (!
id ||
id->empty() || !element_type_name || element_type_name->empty() ||
5589 !count || *count == 0 || *count > max_vector_count) {
5590 LLDB_LOG(log,
"ProcessGDBRemote::ParseVector Ignoring vector with invalid "
5591 "id, type, or count");
5595 if (feature_register_types.contains(*
id)) {
5597 "ProcessGDBRemote::ParseVector Ignoring duplicate type \"{0}\"",
5602 const RegisterType *element_type =
5603 ResolveGDBType(*element_type_name, feature_register_types);
5604 if (!element_type) {
5606 "ProcessGDBRemote::ParseVector Could not resolve element type "
5607 "\"{0}\" for vector \"{1}\"",
5608 *element_type_name, *
id);
5612 if (!llvm::isa<RegisterTypeBuiltin, RegisterTypeVector, RegisterTypeUnion>(
5615 "ProcessGDBRemote::ParseVector Found element type \"{0}\" for "
5616 "vector \"{1}\", but it is not a builtin, vector, or union "
5618 *element_type_name, *
id);
5622 std::optional<uint64_t> element_size = element_type->
GetByteSize();
5626 "ProcessGDBRemote::ParseVector Size of vector \"{0}\" is too "
5633 std::make_unique<RegisterTypeVector>(
id->str(), element_type, *count);
5634 feature_register_types.try_emplace(*
id, vector_type.get());
5635 owned_register_types.push_back(std::move(vector_type));
5638static std::vector<RegisterTypeUnion::Field>
5639ParseUnionFields(
const XMLNode &union_node, llvm::StringRef union_id,
5640 const RegisterTypeMap &feature_register_types) {
5642 std::vector<RegisterTypeUnion::Field> fields;
5643 bool invalid_field =
false;
5646 "field", [&fields, &invalid_field, log, &feature_register_types,
5647 union_id](
const XMLNode &field_node) {
5648 std::optional<llvm::StringRef> name;
5649 std::optional<llvm::StringRef> type_name;
5652 [&name, &type_name, log, union_id](llvm::StringRef attribute,
5653 llvm::StringRef value) {
5654 if (attribute ==
"name")
5656 else if (attribute ==
"type")
5660 "ProcessGDBRemote::ParseUnionFields Ignoring unknown "
5661 "attribute \"{0}\" in a field of union \"{1}\"",
5662 attribute, union_id);
5666 if (!name || name->empty() || !type_name || type_name->empty()) {
5668 "ProcessGDBRemote::ParseUnionFields Union \"{0}\" has a "
5669 "field missing a non-empty name or type",
5671 invalid_field =
true;
5675 const RegisterType *field_type =
5676 ResolveGDBType(*type_name, feature_register_types);
5679 "ProcessGDBRemote::ParseUnionFields Could not resolve type "
5680 "\"{0}\" for field \"{1}\" of union \"{2}\"",
5681 *type_name, *name, union_id);
5682 invalid_field =
true;
5686 if (!llvm::isa<RegisterTypeBuiltin, RegisterTypeVector,
5687 RegisterTypeUnion>(field_type)) {
5689 "ProcessGDBRemote::ParseUnionFields Found type \"{0}\" "
5690 "for field \"{1}\", but it is not a builtin, vector, or "
5691 "union type. Union \"{2}\" will be ignored.",
5692 *type_name, *name, union_id);
5693 invalid_field =
true;
5697 fields.emplace_back(name->str(), field_type);
5703 if (invalid_field) {
5705 "ProcessGDBRemote::ParseUnionFields Ignoring union \"{0}\" "
5706 "because it contains an invalid field",
5709 }
else if (fields.empty()) {
5711 "ProcessGDBRemote::ParseUnionFields Ignoring union \"{0}\" "
5712 "because it has no fields",
5719ParseUnion(
const XMLNode &union_node, RegisterTypeMap &feature_register_types,
5720 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5722 std::optional<llvm::StringRef>
id;
5725 [&
id, log](llvm::StringRef name, llvm::StringRef value) {
5730 "ProcessGDBRemote::ParseUnion Ignoring unknown attribute "
5736 if (!
id ||
id->empty()) {
5737 LLDB_LOG(log,
"ProcessGDBRemote::ParseUnion Ignoring union without an id");
5741 if (feature_register_types.contains(*
id)) {
5743 "ProcessGDBRemote::ParseUnion Ignoring duplicate type \"{0}\"",
5748 std::vector<RegisterTypeUnion::Field> fields =
5749 ParseUnionFields(union_node, *
id, feature_register_types);
5754 std::make_unique<RegisterTypeUnion>(
id->str(), std::move(fields));
5755 feature_register_types.try_emplace(*
id, union_type.get());
5756 owned_register_types.push_back(std::move(union_type));
5759static void ParseCompositeTypes(
5760 XMLNode feature_node, RegisterTypeMap &feature_register_types,
5761 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5763 [&feature_register_types,
5764 &owned_register_types](
const XMLNode &type_node) {
5765 if (type_node.
NameIs(
"vector"))
5766 ParseVector(type_node, feature_register_types, owned_register_types);
5767 else if (type_node.
NameIs(
"union"))
5768 ParseUnion(type_node, feature_register_types, owned_register_types);
5774 XMLNode feature_node, GdbServerTargetInfo &target_info,
5775 std::vector<DynamicRegisterInfo::Register> ®isters,
5776 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5781 RegisterTypeMap feature_register_types;
5784 ParseEnums(feature_node, feature_register_types, owned_register_types);
5785 for (
const auto ®ister_type : feature_register_types)
5786 if (
const auto *enum_type =
5787 llvm::dyn_cast<RegisterTypeEnum>(register_type.second))
5790 ParseFlags(feature_node, feature_register_types, owned_register_types);
5791 for (
const auto ®ister_type : feature_register_types)
5792 if (
const auto *flags_type =
5793 llvm::dyn_cast<RegisterTypeFlags>(register_type.second))
5794 flags_type->DumpToLog(log);
5799 ParseCompositeTypes(feature_node, feature_register_types,
5800 owned_register_types);
5801 for (
const auto ®ister_type : feature_register_types)
5802 if (
const auto *vector_type =
5803 llvm::dyn_cast<RegisterTypeVector>(register_type.second))
5804 vector_type->DumpToLog(log);
5805 for (
const auto ®ister_type : feature_register_types)
5806 if (
const auto *union_type =
5807 llvm::dyn_cast<RegisterTypeUnion>(register_type.second))
5808 union_type->DumpToLog(log);
5812 [&target_info, ®isters, &feature_register_types,
5813 log](
const XMLNode ®_node) ->
bool {
5814 std::string gdb_group;
5815 std::string gdb_type;
5816 DynamicRegisterInfo::Register reg_info;
5817 bool encoding_set =
false;
5818 bool format_set =
false;
5822 &encoding_set, &format_set, ®_info,
5823 log](
const llvm::StringRef &name,
5824 const llvm::StringRef &value) ->
bool {
5825 if (name ==
"name") {
5827 }
else if (name ==
"bitsize") {
5828 if (llvm::to_integer(value, reg_info.
byte_size))
5830 llvm::divideCeil(reg_info.
byte_size, CHAR_BIT);
5831 }
else if (name ==
"type") {
5832 gdb_type = value.str();
5833 }
else if (name ==
"group") {
5834 gdb_group = value.str();
5835 }
else if (name ==
"regnum") {
5837 }
else if (name ==
"offset") {
5839 }
else if (name ==
"altname") {
5841 }
else if (name ==
"encoding") {
5842 encoding_set =
true;
5844 }
else if (name ==
"format") {
5850 llvm::StringSwitch<lldb::Format>(value)
5861 }
else if (name ==
"group_id") {
5863 llvm::to_integer(value, set_id);
5864 RegisterSetMap::const_iterator pos =
5865 target_info.reg_set_map.find(set_id);
5866 if (pos != target_info.reg_set_map.end())
5867 reg_info.
set_name = pos->second.name;
5868 }
else if (name ==
"gcc_regnum" || name ==
"ehframe_regnum") {
5870 }
else if (name ==
"dwarf_regnum") {
5872 }
else if (name ==
"generic") {
5874 }
else if (name ==
"value_regnums") {
5877 }
else if (name ==
"invalidate_regnums") {
5882 "ProcessGDBRemote::ParseRegisters unhandled reg "
5883 "attribute %s = %s",
5884 name.data(), value.data());
5889 if (!gdb_type.empty()) {
5891 auto it = feature_register_types.find(gdb_type);
5892 if (it != feature_register_types.end()) {
5893 if (
const auto *vector_type =
5894 llvm::dyn_cast<RegisterTypeVector>(it->second)) {
5895 std::optional<uint64_t> type_size = vector_type->GetByteSize();
5898 "ProcessGDBRemote::ParseRegisters Register {0} is "
5899 "too large for vector type {1}",
5900 reg_info.
name, vector_type->GetID());
5901 }
else if (!vector_type->IsByteSizeCompatible(
5905 "ProcessGDBRemote::ParseRegisters Size of register "
5906 "{0} is incompatible with vector type {1}",
5907 reg_info.
name, vector_type->GetID());
5911 "ProcessGDBRemote::ParseRegisters Size of register type "
5912 "{0} ({1} bytes) for register {2} does not match the "
5913 "register size ({3} bytes). Ignoring this type.",
5914 vector_type->GetID(), *type_size, reg_info.
name,
5919 if (!encoding_set) {
5921 encoding_set =
true;
5928 }
else if (
const auto *union_type =
5929 llvm::dyn_cast<RegisterTypeUnion>(it->second)) {
5932 "ProcessGDBRemote::ParseRegisters Register {0} is "
5933 "too large for union type {1}",
5934 reg_info.
name, union_type->GetID());
5935 }
else if (!union_type->IsByteSizeCompatible(
5938 "ProcessGDBRemote::ParseRegisters Size of register "
5939 "{0} is incompatible with union type {1}",
5940 reg_info.
name, union_type->GetID());
5943 if (!encoding_set) {
5945 encoding_set =
true;
5952 }
else if (
const auto *flags_type =
5953 llvm::dyn_cast<RegisterTypeFlags>(it->second)) {
5954 if (reg_info.
byte_size == flags_type->GetSize())
5959 "ProcessGDBRemote::ParseRegisters Size of register flags "
5960 "{0} ({1} bytes) for register {2} does not match the "
5961 "register size ({3} bytes). Ignoring this set of flags.",
5962 flags_type->GetID().c_str(), flags_type->GetSize(),
5970 if (!gdb_type.empty() && !(encoding_set || format_set)) {
5971 if (llvm::StringRef(gdb_type).starts_with(
"int")) {
5974 }
else if (gdb_type ==
"data_ptr" || gdb_type ==
"code_ptr") {
5977 }
else if (gdb_type ==
"float" || gdb_type ==
"ieee_single" ||
5978 gdb_type ==
"ieee_double") {
5981 }
else if (gdb_type ==
"aarch64v" ||
5982 llvm::StringRef(gdb_type).starts_with(
"vec") ||
5983 gdb_type ==
"i387_ext" || gdb_type ==
"uint128" ||
5996 "ProcessGDBRemote::ParseRegisters Could not determine lldb"
5997 "format and encoding for gdb type %s",
6007 if (!gdb_group.empty()) {
6018 "ProcessGDBRemote::{0} Skipping zero bitsize register {1}",
6019 __FUNCTION__, reg_info.
name);
6021 registers.push_back(reg_info);
6036 ArchSpec &arch_to_use, std::string xml_filename,
6037 std::vector<DynamicRegisterInfo::Register> ®isters) {
6039 llvm::Expected<std::string> raw =
m_gdb_comm.ReadExtFeature(
"features", xml_filename);
6040 if (errorToBool(raw.takeError()))
6045 if (xml_document.
ParseMemory(raw->c_str(), raw->size(),
6046 xml_filename.c_str())) {
6047 GdbServerTargetInfo target_info;
6048 std::vector<XMLNode> feature_nodes;
6054 const XMLNode &node) ->
bool {
6055 llvm::StringRef name = node.
GetName();
6056 if (name ==
"architecture") {
6058 }
else if (name ==
"osabi") {
6060 }
else if (name ==
"xi:include" || name ==
"include") {
6063 target_info.includes.push_back(href);
6064 }
else if (name ==
"feature") {
6065 feature_nodes.push_back(node);
6066 }
else if (name ==
"groups") {
6068 "group", [&target_info](
const XMLNode &node) ->
bool {
6070 RegisterSetInfo set_info;
6073 [&set_id, &set_info](
const llvm::StringRef &name,
6074 const llvm::StringRef &value) ->
bool {
6077 llvm::to_integer(value, set_id);
6084 target_info.reg_set_map[set_id] = set_info;
6097 feature_nodes.push_back(feature_node);
6099 const XMLNode &node) ->
bool {
6100 llvm::StringRef name = node.
GetName();
6101 if (name ==
"xi:include" || name ==
"include") {
6104 target_info.includes.push_back(href);
6118 if (!arch_to_use.
IsValid() && !target_info.arch.empty()) {
6120 arch_to_use.
SetTriple(llvm::StringSwitch<std::string>(target_info.arch)
6121 .Case(
"i386:x86-64",
"x86_64")
6122 .Case(
"riscv:rv64",
"riscv64")
6123 .Case(
"riscv:rv32",
"riscv32")
6124 .Default(target_info.arch) +
6132 for (
auto &feature_node : feature_nodes) {
6136 for (
const auto &include : target_info.includes) {
6148 std::vector<DynamicRegisterInfo::Register> ®isters,
6150 std::map<uint32_t, uint32_t> remote_to_local_map;
6151 uint32_t remote_regnum = 0;
6152 for (
auto it : llvm::enumerate(registers)) {
6160 remote_to_local_map[remote_reg_info.
regnum_remote] = it.index();
6166 auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) {
6167 auto lldb_regit = remote_to_local_map.find(process_regnum);
6168 return lldb_regit != remote_to_local_map.end() ? lldb_regit->second
6172 llvm::transform(remote_reg_info.value_regs,
6173 remote_reg_info.value_regs.begin(), proc_to_lldb);
6174 llvm::transform(remote_reg_info.invalidate_regs,
6175 remote_reg_info.invalidate_regs.begin(), proc_to_lldb);
6182 abi_sp->AugmentRegisterInfo(registers);
6192 if (!
m_gdb_comm.GetQXferFeaturesReadSupported())
6193 return llvm::createStringError(
6194 llvm::inconvertibleErrorCode(),
6195 "the debug server does not support \"qXfer:features:read\"");
6198 return llvm::createStringError(
6199 llvm::inconvertibleErrorCode(),
6200 "the debug server supports \"qXfer:features:read\", but LLDB does not "
6201 "have XML parsing enabled (check LLLDB_ENABLE_LIBXML2)");
6203 std::vector<DynamicRegisterInfo::Register> registers;
6211 ? llvm::ErrorSuccess()
6212 : llvm::createStringError(
6213 llvm::inconvertibleErrorCode(),
6214 "the debug server did not describe any registers");
6220 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6221 "XML parsing not available");
6224 LLDB_LOGF(log,
"ProcessGDBRemote::%s", __FUNCTION__);
6233 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries-svr4",
"");
6235 return raw.takeError();
6238 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
6241 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
6242 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6243 "Error reading noname.xml");
6247 return llvm::createStringError(
6248 llvm::inconvertibleErrorCode(),
6249 "Error finding library-list-svr4 xml element");
6254 if (!main_lm.empty())
6258 "library", [log, &list](
const XMLNode &library) ->
bool {
6263 [&module](
const llvm::StringRef &name,
6264 const llvm::StringRef &value) ->
bool {
6267 module.set_name(value.str());
6268 else if (name ==
"lm") {
6270 llvm::to_integer(value, uint_value);
6271 module.set_link_map(uint_value);
6272 }
else if (name ==
"l_addr") {
6275 llvm::to_integer(value, uint_value);
6276 module.set_base(uint_value);
6279 module.set_base_is_offset(true);
6280 }
else if (name ==
"l_ld") {
6282 llvm::to_integer(value, uint_value);
6283 module.set_dynamic(uint_value);
6292 bool base_is_offset;
6294 module.get_name(name);
6295 module.get_link_map(lm);
6296 module.get_base(base);
6297 module.get_base_is_offset(base_is_offset);
6298 module.get_dynamic(ld);
6301 "found (link_map:0x%08" PRIx64
", base:0x%08" PRIx64
6302 "[%s], ld:0x%08" PRIx64
", name:'%s')",
6303 lm, base, (base_is_offset ?
"offset" :
"absolute"), ld,
6312 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
6313 (
int)list.
m_list.size());
6317 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries",
"");
6320 return raw.takeError();
6322 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
6325 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
6326 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6327 "Error reading noname.xml");
6331 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6332 "Error finding library-list xml element");
6336 "library", [log, &list](
const XMLNode &library) ->
bool {
6340 module.set_name(name);
6349 llvm::to_integer(address, address_value);
6350 module.set_base(address_value);
6352 module.set_base_is_offset(false);
6357 bool base_is_offset;
6358 module.get_name(name);
6359 module.get_base(base);
6360 module.get_base_is_offset(base_is_offset);
6362 LLDB_LOGF(log,
"found (base:0x%08" PRIx64
"[%s], name:'%s')", base,
6363 (base_is_offset ?
"offset" :
"absolute"), name.c_str());
6371 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
6372 (
int)list.
m_list.size());
6375 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6376 "Remote libraries not supported");
6383 bool value_is_offset) {
6396 return llvm::ErrorSuccess();
6401 return module_list.takeError();
6407 std::string mod_name;
6410 bool mod_base_is_offset;
6413 valid &= modInfo.
get_name(mod_name);
6414 valid &= modInfo.
get_base(mod_base);
6427 if (module_sp.get())
6428 new_modules.
Append(module_sp);
6431 if (new_modules.
GetSize() > 0) {
6436 for (
size_t i = 0; i < loaded_modules.
GetSize(); ++i) {
6440 for (
size_t j = 0; j < new_modules.
GetSize(); ++j) {
6449 removed_modules.
Append(loaded_module);
6453 loaded_modules.
Remove(removed_modules);
6454 m_process->GetTarget().ModulesDidUnload(removed_modules,
false);
6473 m_process->GetTarget().ModulesDidLoad(new_modules);
6476 return llvm::ErrorSuccess();
6485 std::string file_path = file.
GetPath(
false);
6486 if (file_path.empty())
6507 "Fetching file load address from remote server returned an error");
6517 "Unknown error happened during sending the load address packet");
6538 std::string input = data.str();
6545 size_t found, pos = 0, len = input.length();
6546 while ((found = input.find(
end_delimiter, pos)) != std::string::npos) {
6548 input.substr(pos, found).c_str());
6549 std::string profile_data =
6564 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
6566 llvm::raw_string_ostream output_stream(output);
6567 llvm::StringRef name, value;
6571 if (name.compare(
"thread_used_id") == 0) {
6573 uint64_t thread_id = threadIDHexExtractor.
GetHexMaxU64(
false, 0);
6575 bool has_used_usec =
false;
6576 uint32_t curr_used_usec = 0;
6577 llvm::StringRef usec_name, usec_value;
6578 uint32_t input_file_pos = profileDataExtractor.
GetFilePos();
6580 if (usec_name ==
"thread_used_usec") {
6581 has_used_usec =
true;
6582 usec_value.getAsInteger(
BASE_10, curr_used_usec);
6586 profileDataExtractor.
SetFilePos(input_file_pos);
6590 if (has_used_usec) {
6591 uint32_t prev_used_usec = 0;
6592 std::map<uint64_t, uint32_t>::iterator iterator =
6595 prev_used_usec = iterator->second;
6597 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
6599 bool good_first_time =
6600 (prev_used_usec == 0) && (real_used_usec > 250000);
6601 bool good_subsequent_time =
6602 (prev_used_usec > 0) &&
6605 if (good_first_time || good_subsequent_time) {
6609 output_stream << name <<
":";
6611 output_stream << index_id <<
";";
6613 output_stream << usec_name <<
":" << usec_value <<
";";
6616 llvm::StringRef local_name, local_value;
6622 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
6625 output_stream << name <<
":" << value <<
";";
6628 output_stream << name <<
":" << value <<
";";
6663 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6664 "qSaveCore returned an error");
6669 for (
auto x : llvm::split(response.
GetStringRef(),
';')) {
6670 if (x.consume_front(
"core-path:"))
6676 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6677 "qSaveCore returned no core path");
6679 FileSpec remote_core{llvm::StringRef(path)};
6683 if (!platform.
IsRemote() && remote_core == local_core)
6689 platform.
Unlink(remote_core);
6691 return error.ToError();
6696 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6697 "Unable to send qSaveCore");
6709 "GDBRemoteCommunicationClientBase::%s() received $J packet "
6710 "but was not a StructuredData packet: packet starts with "
6722 json_sp->Dump(json_str,
true);
6725 "ProcessGDBRemote::%s() "
6726 "received Async StructuredData packet: %s",
6727 __FUNCTION__, json_str.
GetData());
6730 "ProcessGDBRemote::%s"
6731 "() received StructuredData packet:"
6741 if (structured_data_sp)
6749 "Tests packet speeds of various sizes to determine "
6750 "the performance characteristics of the GDB remote "
6755 "The number of packets to send of each varying size "
6756 "(default is 1000).",
6759 "The maximum number of bytes to send in a packet. Sizes "
6760 "increase in powers of 2 while the size is less than or "
6761 "equal to this option value. (default 1024).",
6764 "The maximum number of bytes to receive in a packet. Sizes "
6765 "increase in powers of 2 while the size is less than or "
6766 "equal to this option value. (default 1024).",
6769 "Print the output as JSON data for easy parsing.", false, true) {
6789 if (!output_stream_sp)
6790 output_stream_sp =
m_interpreter.GetDebugger().GetAsyncOutputStream();
6793 const uint32_t num_packets =
6795 const uint64_t max_send =
m_max_send.GetOptionValue().GetCurrentValue();
6796 const uint64_t max_recv =
m_max_recv.GetOptionValue().GetCurrentValue();
6797 const bool json =
m_json.GetOptionValue().GetCurrentValue();
6798 const uint64_t k_recv_amount =
6801 num_packets, max_send, max_recv, k_recv_amount, json,
6826 "Dumps the packet history buffer. ", nullptr) {}
6847 interpreter,
"process plugin packet xfer-size",
6848 "Maximum size that lldb will try to read/write one one chunk.",
6859 "amount to be transferred when "
6870 uint64_t user_specified_max = strtoul(packet_size,
nullptr, 10);
6871 if (errno == 0 && user_specified_max != 0) {
6886 "Send a custom packet through the GDB remote "
6887 "protocol and print the answer. "
6888 "The packet header and footer will automatically "
6889 "be added to the packet prior to sending and "
6890 "stripped from the result.",
6901 "'%s' takes a one or more packet content arguments",
6909 for (
size_t i = 0; i < argc; ++i) {
6916 output_strm.
Printf(
" packet: %s\n", packet_cstr);
6917 std::string response_str = std::string(response.
GetStringRef());
6919 if (strstr(packet_cstr,
"qGetProfileData") !=
nullptr) {
6923 if (response_str.empty())
6924 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6937 "Send a qRcmd packet through the GDB remote protocol "
6938 "and print the response. "
6939 "The argument passed to this command will be hex "
6940 "encoded into a valid 'qRcmd' packet, sent and the "
6941 "response will be printed.") {}
6947 if (command.empty()) {
6964 [&output_strm](llvm::StringRef output) { output_strm << output; });
6967 const std::string &response_str = std::string(response.
GetStringRef());
6969 if (response_str.empty())
6970 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6982 "Commands that deal with GDB remote packets.",
7011 interpreter,
"process plugin",
7012 "Commands for operating on a ProcessGDBRemote process.",
7013 "process plugin <subcommand> [<subcommand-options>]") {
7024 m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(
7025 GetTarget().GetDebugger().GetCommandInterpreter());
7030 bool enable,
bool is_expression_fork) {
7036 if (!enable && is_expression_fork) {
7037 if (
auto entry =
GetTarget().GetEntryPointAddress())
7038 entry_addr = entry->GetOpcodeLoadAddress(&
GetTarget());
7052 "DidForkSwitchSoftwareBreakpoints: retaining expression-"
7053 "return trap at {0:x} in forked child",
7077 addr_t addr = wp_res_sp->GetLoadAddress();
7078 size_t size = wp_res_sp->GetByteSize();
7080 m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,
7086 bool is_expression_fork) {
7095 bool overrode_follow_mode =
false;
7098 if (is_expression_fork) {
7099 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
7100 "to parent during expression evaluation");
7102 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
7103 "to parent during expression evaluation. Child process "
7104 "{0} is available for manual attachment.",
7108 overrode_follow_mode =
true;
7119 switch (follow_fork_mode) {
7121 follow_pid = parent_pid;
7122 follow_tid = parent_tid;
7123 detach_pid = child_pid;
7124 detach_tid = child_tid;
7127 follow_pid = child_pid;
7128 follow_tid = child_tid;
7129 detach_pid = parent_pid;
7130 detach_tid = parent_tid;
7135 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
7136 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to set pid/tid");
7150 if (!
m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) ||
7151 !
m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) {
7152 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to reset pid/tid");
7156 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
7159 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
7161 if (
error.Fail() && keep_stopped) {
7162 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach-and-stay-stopped not "
7163 "supported, falling back to normal detach");
7164 keep_stopped =
false;
7168 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach packet send failed: {0}",
7169 error.AsCString() ?
error.AsCString() :
"<unknown error>");
7175 if (overrode_follow_mode && !is_expression_fork) {
7179 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
7180 "'parent' because an expression is being evaluated.\n"
7181 "Child process %" PRIu64
7182 " has been detached%s.\n"
7183 "You can attach to it with: process attach -p %" PRIu64
7186 keep_stopped ?
" and stopped" :
" (running)",
7202 bool is_expression_fork) {
7207 "ProcessGDBRemote::DidVFork() called for child_pid: {0}, child_tid {1}",
7208 child_pid, child_tid);
7214 bool overrode_follow_mode =
false;
7217 if (is_expression_fork) {
7218 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
7219 "to parent during expression evaluation");
7221 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
7222 "to parent during expression evaluation. Child process "
7223 "{0} is available for manual attachment.",
7227 overrode_follow_mode =
true;
7237 switch (follow_fork_mode) {
7239 detach_pid = child_pid;
7240 detach_tid = child_tid;
7243 detach_pid =
m_gdb_comm.GetCurrentProcessID();
7249 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
7250 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to set pid/tid");
7258 if (!
m_gdb_comm.SetCurrentThread(child_tid, child_pid) ||
7259 !
m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) {
7260 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to reset pid/tid");
7266 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
7267 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
7269 if (
error.Fail() && keep_stopped) {
7270 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() detach-and-stay-stopped not "
7271 "supported, falling back to normal detach");
7272 keep_stopped =
false;
7277 "ProcessGDBRemote::DidVFork() detach packet send failed: {0}",
7278 error.AsCString() ?
error.AsCString() :
"<unknown error>");
7282 if (overrode_follow_mode && !is_expression_fork) {
7286 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
7287 "'parent' because an expression is being evaluated.\n"
7288 "Child process %" PRIu64
7289 " has been detached%s.\n"
7290 "You can attach to it with: process attach -p %" PRIu64
7293 keep_stopped ?
" and stopped" :
" (running)",
7326 llvm::Error joined = llvm::Error::success();
7327 for (
auto &[site, action] : site_to_action) {
7331 joined = llvm::joinErrors(std::move(joined), std::move(
error));
7339static llvm::SmallVector<std::optional<uint8_t>>
7341 llvm::SmallVector<std::optional<uint8_t>> results;
7345 parsed ? parsed->GetAsDictionary() :
nullptr;
7353 llvm::StringRef token;
7354 if (
auto *
string = object->GetAsString())
7355 token =
string->GetValue();
7356 if (token ==
"OK") {
7357 results.push_back(std::nullopt);
7360 if (token.size() != 3 || !token.starts_with(
"E")) {
7361 results.push_back(uint8_t(0xff));
7364 uint8_t error_code = 0;
7365 if (token.drop_front(1).getAsInteger(
BASE_16, error_code))
7366 results.push_back(0xff);
7368 results.push_back(error_code);
7377static std::optional<GDBStoppointType>
7386 return std::nullopt;
7395 return std::nullopt;
7397 llvm_unreachable(
"unhandled BreakpointSite type");
7401struct BreakpointPacketInfo {
7402 BreakpointSite &site;
7403 size_t trap_opcode_size;
7408std::string to_string(
const BreakpointPacketInfo &info) {
7409 char packet = info.is_enable ?
'Z' :
'z';
7410 return llvm::formatv(
"{0}{1},{2:x-},{3:x-}", packet,
7412 info.trap_opcode_size)
7419 if (site_to_action.empty())
7420 return llvm::Error::success();
7421 if (!
m_gdb_comm.GetMultiBreakpointSupported())
7426 std::vector<BreakpointPacketInfo> breakpoint_infos;
7427 for (
auto [site, action] : site_to_action) {
7429 std::optional<GDBStoppointType> type =
7433 LLDB_LOG(log,
"MultiBreakpoint: site {0} at {1:x} can't be batched",
7434 site->GetID(), site->GetLoadAddress());
7438 breakpoint_infos.push_back(
7443 stream <<
"jMultiBreakpoint:";
7445 auto args_array = std::make_shared<StructuredData::Array>();
7446 for (
auto &bp_info : breakpoint_infos)
7447 args_array->AddStringItem(to_string(bp_info));
7450 packet_dict.
AddItem(
"breakpoint_requests", args_array);
7451 packet_dict.
Dump(stream,
false);
7455 llvm::Expected<StringExtractorGDBRemote> response =
7460 LLDB_LOG_ERROR(log, response.takeError(),
"jMultiBreakpoint failed: {0}");
7464 llvm::SmallVector<std::optional<uint8_t>> results =
7468 if (results.size() != breakpoint_infos.size())
7469 return llvm::createStringErrorV(
7470 "MultiBreakpoint response count mismatch (expected {0}, got {1})",
7471 site_to_action.size(), results.size());
7473 llvm::Error joined = llvm::Error::success();
7474 for (
auto [error_code, bp_info] :
7475 llvm::zip_equal(results, breakpoint_infos)) {
7478 auto error = llvm::createStringErrorV(
7479 "MultiBreakpoint: site {0} at {1:x} failed with E{2}",
7480 bp_info.site.GetID(), bp_info.site.GetLoadAddress(), error_code);
7481 joined = llvm::joinErrors(std::move(joined), std::move(
error));
7485 if (bp_info.is_enable)
static llvm::raw_ostream & error(Stream &strm)
static PluginProperties & GetGlobalPluginProperties()
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF_VERBOSE(log,...)
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_LOG_VERBOSE(log,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
static PluginProperties & GetGlobalPluginProperties()
static const char *const s_async_json_packet_prefix
#define DEBUGSERVER_BASENAME
static size_t SplitCommaSeparatedRegisterNumberString(const llvm::StringRef &comma_separated_register_numbers, std::vector< uint32_t > ®nums, int base)
static const char * end_delimiter
static GDBStoppointType GetGDBStoppointType(const WatchpointResourceSP &wp_res_sp)
static StructuredData::ObjectSP ParseStructuredDataPacket(llvm::StringRef packet)
static std::string BinaryInformationLevelToJSONKey(BinaryInformationLevel info_level)
static uint64_t ComputeNumRangesMultiMemRead(uint64_t max_packet_size, llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges)
Returns the number of ranges that is safe to request using MultiMemRead while respecting max_packet_s...
static std::optional< GDBStoppointType > GetStoppointType(BreakpointSite &site, bool insert, GDBRemoteCommunicationClient &gdb_comm)
Determine the GDB stoppoint type for a breakpoint site by checking which packet types the remote supp...
static FileSpec GetDebugserverPath(Platform &platform)
static llvm::SmallVector< std::optional< uint8_t > > ParseMultiBreakpointResponse(llvm::StringRef response_str)
Parse a MultiBreakpoint response into per-request results.
static const int end_delimiter_len
CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
~CommandObjectMultiwordProcessGDBRemote() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectProcessGDBRemotePacketHistory() override=default
CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter)
~CommandObjectProcessGDBRemotePacketMonitor() override=default
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override
CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter)
CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter)
~CommandObjectProcessGDBRemotePacketSend() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectProcessGDBRemotePacketXferSize() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter)
~CommandObjectProcessGDBRemotePacket() override=default
CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter)
Options * GetOptions() override
OptionGroupBoolean m_json
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectProcessGDBRemoteSpeedTest() override=default
OptionGroupOptions m_option_group
OptionGroupUInt64 m_max_send
OptionGroupUInt64 m_num_packets
CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter)
OptionGroupUInt64 m_max_recv
static lldb::ABISP FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch)
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetHighmemAddressableBits(uint32_t highmem_addressing_bits)
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
void SetLowmemAddressableBits(uint32_t lowmem_addressing_bits)
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
void Clear()
Clears the object state.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
A command line argument class.
static lldb::Encoding StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value=lldb::eEncodingInvalid)
static uint32_t StringToGenericRegister(llvm::StringRef s)
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
void ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char='\0')
Replaces the argument value at index idx to arg_str if idx is a valid argument index.
const char * GetArgumentAtIndex(size_t idx) const
Gets the null-terminated C string argument pointer for the argument at index idx.
Class that manages the actual breakpoint that will be inserted into the running program.
BreakpointSite::Type GetType() const
void SetType(BreakpointSite::Type type)
void BroadcastEvent(lldb::EventSP &event_sp)
Broadcast an event which has no associated data.
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
friend class CommandInterpreter
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help="", llvm::StringRef syntax="", uint32_t flags=0)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
CommandInterpreter & m_interpreter
void SetStatus(lldb::ReturnStatus status)
void SetImmediateOutputStream(const lldb::StreamSP &stream_sp)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
lldb::StreamSP GetImmediateOutputStream() const
Stream & GetOutputStream()
A uniqued constant string class.
void SetCString(const char *cstr)
Set the C string value.
void SetString(llvm::StringRef s)
A subclass of DataBuffer that stores a data buffer on the heap.
lldb::StreamUP GetAsyncErrorStream()
TargetList & GetTargetList()
Get accessor for the target list.
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
TargetGroupList & GetTargetGroupList()
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
lldb::StreamUP GetAsyncOutputStream()
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
ArtifactProviderID AddArtifactProvider(std::string name, ArtifactProvider provider)
Register provider to contribute file name.
void RemoveArtifactProvider(ArtifactProviderID id)
Unregister a provider. Thread-safe.
static Diagnostics & Instance()
static llvm::Expected< lldb::ModuleSP > LocateAndLoadBinary(Process *process, BinarySpec &bin_spec)
Find a binary and load it into a Target.
virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Locates or creates a module given by file and updates/loads the resulting module at the virtual base ...
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
const void * GetBytes() const
static const EventDataBytes * GetEventDataFromEvent(const Event *event_ptr)
size_t GetByteSize() const
lldb::ProcessSP GetProcessSP() const
Get accessor that creates a strong reference from the weak process reference contained in this object...
Represents a file descriptor action to be performed during process launch.
Action GetAction() const
Get the type of action.
const FileSpec & GetFileSpec() const
Get the file specification for open actions.
void Append(const FileSpec &file)
Append a FileSpec object to the list.
size_t GetSize() const
Get the number of files in the file list.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
void AppendPathComponent(llvm::StringRef component)
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Clear()
Clears the object state.
static const char * DEV_NULL
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
ValueType Get() const
Get accessor for all flags.
static Environment GetEnvironment()
static void Kill(lldb::pid_t pid, int signo)
static lldb::ListenerSP MakeListener(llvm::StringRef name)
bool get_name(std::string &out) const
bool get_link_map(lldb::addr_t &out) const
bool get_base_is_offset(bool &out) const
bool get_base(lldb::addr_t &out) const
void add(const LoadedModuleInfo &mod)
std::vector< LoadedModuleInfo > m_list
void PutCString(const char *cstr)
LazyBool GetFlash() const
lldb::offset_t GetBlocksize() const
lldb::SymbolSharedCacheUse GetSharedCacheBinaryLoading() const
A collection class for Module objects.
void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
static ModuleListProperties & GetGlobalModuleListProperties()
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
size_t GetSize() const
Gets the size of the module list.
void ForEach(std::function< IterationAction(const lldb::ModuleSP &module_sp)> const &callback) const
Applies 'callback' to each module in this ModuleList.
void Dump(Stream &strm) const
A class that describes an executable image and its associated object and symbol files.
virtual ObjectFile * GetObjectFile()
Get the object file representation for the current architecture.
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
A plug-in interface definition class for object file parsers.
@ eTypeExecutable
A normal executable.
@ eTypeDebugInfo
An object file that contains only debug information.
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
@ eTypeObjectFile
An intermediate object file.
@ eTypeDynamicLinker
The platform's dynamic linker executable.
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
@ eTypeSharedLibrary
A shared library that can be used during execution.
@ eTypeJIT
JIT code that has symbols, sections and possibly debug info.
A command line option parsing protocol class.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool CreateSettingForProcessPlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, llvm::StringRef description, bool is_global_property)
static lldb::OptionValuePropertiesSP GetSettingForProcessPlugin(Debugger &debugger, llvm::StringRef setting_name)
static bool UnregisterPlugin(ABICreateInstance create_callback)
An address in a process, qualified by an address space.
lldb::addr_t GetValue() const
std::optional< lldb::tid_t > GetThreadID() const
lldb::addr_space_t GetAddressSpace() const
bool GetIgnoreExisting() const
bool GetDetachOnError() const
bool GetWaitForLaunch() const
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
lldb::pid_t GetProcessID() const
FileSpec & GetExecutableFile()
uint32_t GetUserID() const
Environment & GetEnvironment()
void SetUserID(uint32_t uid)
const char * GetLaunchEventData() const
const FileAction * GetFileActionForFD(int fd) const
void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback)
void SetLaunchInSeparateProcessGroup(bool separate)
const FileSpec & GetWorkingDirectory() const
Args GetExtraStartupCommands() const
FollowForkMode GetFollowForkMode() const
std::chrono::seconds GetInterruptTimeout() const
A plug-in interface definition class for debugging a process.
lldb::IOHandlerSP m_process_input_reader
std::mutex m_process_input_reader_mutex
StopPointSiteList< lldb_private::BreakpointSite > & GetBreakpointSiteList()
virtual Status DisableSoftwareBreakpoint(BreakpointSite *bp_site)
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
ThreadList & GetThreadList()
void SetAddressableBitMasks(AddressableBits bit_masks)
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
void SetUnixSignals(lldb::UnixSignalsSP &&signals_sp)
void SetSTDIOFileDescriptor(int file_descriptor, std::optional< int > secondary_fd=std::nullopt)
Associates a file descriptor with the process' STDIO handling and configures an asynchronous reading ...
virtual void ModulesDidLoad(ModuleList &module_list)
virtual llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buffer)
Reads each range individually via ReadMemoryFromInferior, bypassing the memory cache.
void ResumePrivateStateThread()
void MapSupportedStructuredDataPlugins(const StructuredData::Array &supported_type_names)
Loads any plugins associated with asynchronous structured data and maps the relevant supported type n...
std::map< lldb::BreakpointSiteSP, BreakpointAction, SiteIDCmp > BreakpointSiteToActionMap
virtual SystemRuntime * GetSystemRuntime()
Get the system runtime plug-in for this process.
std::map< uint64_t, uint32_t > m_thread_id_to_index_id_map
lldb::StateType GetPrivateState() const
void SetBreakpointSiteEnabled(BreakpointSite &site, bool is_enabled=true)
lldb::DynamicLoaderUP m_dyld_up
virtual Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries)
StopPointSiteList< lldb_private::WatchpointResource > m_watchpoint_resource_list
Watchpoint resources currently in use.
bool IsBreakpointSitePhysicallyEnabled(const BreakpointSite &site)
std::vector< AddressSpaceInfo > m_address_spaces
A list of address spaces for this process.
void AppendSTDOUT(const char *s, size_t len)
bool HasAssignedIndexIDToThread(uint64_t sb_thread_id)
lldb::ByteOrder GetByteOrder() const
void UpdateThreadListIfNeeded()
bool IsValid() const
Return whether this object is valid (i.e.
virtual void DidExec()
Called after a process re-execs itself.
void BroadcastAsyncProfileData(const std::string &one_profile_data)
lldb::UnixSignalsSP m_unix_signals_sp
lldb::tid_t m_interrupt_tid
void AddCacheData(lldb::addr_t addr, const lldb::WritableDataBufferSP &data_buffer_sp)
Cache memory, restoring the original bytes under any breakpoint.
virtual Status EnableSoftwareBreakpoint(BreakpointSite *bp_site)
bool RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp)
Route the incoming structured data dictionary to the right plugin.
virtual bool IsAlive()
Check if a process is still alive.
ThreadList m_thread_list_real
The threads for this process as are known to the protocol we are debugging with.
lldb::StateType m_last_broadcast_state
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
uint32_t AssignIndexIDToThread(uint64_t thread_id)
virtual bool SetExitStatus(int exit_status, llvm::StringRef exit_string)
Set accessor for the process exit status (return code).
uint32_t GetAddressByteSize() const
uint32_t GetStopID() const
void SetPrivateState(lldb::StateType state)
llvm::Expected< AddressSpaceInfo > GetAddressSpaceInfo(llvm::StringRef address_space_name)
lldb::StateType GetPublicState() const
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
void SetSTDIOPseudoTerminal(PseudoTerminal &pty)
Associates the primary side of pty with the process' STDIO handling.
ThreadList m_thread_list
The threads for this process as the user will see them.
const lldb::UnixSignalsSP & GetUnixSignals()
std::weak_ptr< Target > m_target_wp
The target that owns this process.
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
friend class DynamicLoader
size_t GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site)
const ProcessModID & GetModIDRef() const
ThreadedCommunication m_stdio_communication
Target & GetTarget()
Get the target object pointer for this module.
lldb::OptionValuePropertiesSP GetValueProperties() const
A pseudo terminal helper class.
llvm::Error OpenFirstAvailablePrimary(int oflag)
Open the first available pseudo terminal.
@ invalid_fd
Invalid file descriptor value.
int GetPrimaryFileDescriptor() const
The primary file descriptor accessor.
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
std::string GetSecondaryName() const
Get the name of the secondary pseudo terminal.
std::vector< Enumerator > Enumerators
const Enumerators & GetEnumerators() const
void DumpToLog(Log *log) const
unsigned GetSizeInBits() const
Get size of the field in bits. Will always be at least 1.
uint64_t GetMaxValue() const
The maximum unsigned value that could be contained in this field.
virtual std::optional< uint64_t > GetByteSize() const
Return this type's fixed size in bytes, if it has one.
virtual StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Status &error)
virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error)
Status CompleteSending(lldb::pid_t child_pid)
shared_fd_t GetSendableFD()
static llvm::Expected< Pair > CreatePair(std::optional< SocketProtocol > protocol=std::nullopt)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
static lldb::StopInfoSP CreateStopReasonWithMachException(Thread &thread, uint32_t exc_type, uint32_t exc_data_count, uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, bool pc_already_adjusted=true, bool adjust_pc_if_needed=false)
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread)
static lldb::StopInfoSP CreateStopReasonVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonWithInterrupt(Thread &thread, int signo, const char *description)
static lldb::StopInfoSP CreateStopReasonWithSignal(Thread &thread, int signo, const char *description=nullptr, std::optional< int > code=std::nullopt)
static lldb::StopInfoSP CreateStopReasonFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonVForkDone(Thread &thread)
static lldb::StopInfoSP CreateStopReasonWithWatchpointID(Thread &thread, lldb::break_id_t watch_id, bool silently_continue=false)
static lldb::StopInfoSP CreateStopReasonWithException(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(Thread &thread, lldb::break_id_t break_id)
static lldb::StopInfoSP CreateStopReasonHistoryBoundary(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonDyld(Thread &thread, const char *description=nullptr)
static lldb::StopInfoSP CreateStopReasonProcessorTrace(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread)
void ForEach(std::function< void(StopPointSite *)> const &callback)
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
ExecutionContextRef exe_ctx_ref
lldb::break_id_t GetID() const
virtual lldb::addr_t GetLoadAddress() const
bool HardwareRequired() const
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
const char * GetData() const
void Flush() override
Flush the stream.
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
size_t PutStringAsRawHex8(llvm::StringRef s)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
ObjectSP GetItemAtIndex(size_t idx) const
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
ObjectSP GetValueForKey(llvm::StringRef key) const
bool HasKey(llvm::StringRef key) const
void AddItem(llvm::StringRef key, ObjectSP value_sp)
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
void ForEach(std::function< bool(llvm::StringRef key, Object *object)> const &callback) const
Dictionary * GetAsDictionary()
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
uint64_t GetUnsignedIntegerValue(uint64_t fail_value=0)
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
std::shared_ptr< Array > ArraySP
Integer< uint64_t > UnsignedInteger
Defines a list of symbol context objects.
Defines a symbol context baton that can be handed other debug core functions.
A plug-in interface definition class for system runtimes.
virtual void AddThreadExtendedInfoPacketHints(lldb_private::StructuredData::ObjectSP dict)
Add key-value pairs to the StructuredData dictionary object with information debugserver may need whe...
A group that accepts a CPU target as its first member, followed by accelerator targets.
lldb::TargetGroupSP CreateTargetGroup(llvm::StringRef description)
Create and register a target group.
bool DeleteTargetGroup(const lldb::TargetGroupSP &group_sp)
Remove group_sp from this list.
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
bool DeleteTarget(lldb::TargetSP &target_sp)
Delete a Target object from the list.
Module * GetExecutableModulePointer()
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Debugger & GetDebugger() const
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
lldb::PlatformSP GetPlatform()
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
@ eBroadcastBitNewTargetCreated
void RebuildModuleListWithExecutable(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Clear the module list and rebuild it around a new main executable.
bool MergeArchitecture(const ArchSpec &arch_spec)
void AddThreadSortedByIndexID(const lldb::ThreadSP &thread_sp)
static llvm::Expected< HostThread > LaunchThread(llvm::StringRef name, std::function< lldb::thread_result_t()> thread_function, size_t min_stack_byte_size=0)
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid, bool can_update=true)
Represents UUID's of various sizes.
bool SetFromStringRef(llvm::StringRef str)
static lldb::UnixSignalsSP Create(const ArchSpec &arch)
static std::vector< lldb::WatchpointResourceSP > AtomizeWatchpointRequest(lldb::addr_t addr, size_t size, bool read, bool write, WatchpointHardwareFeature supported_features, ArchSpec &arch)
Convert a user's watchpoint request into an array of memory regions, each region watched by one hardw...
XMLNode GetRootElement(const char *required_name=nullptr)
bool ParseMemory(const char *xml, size_t xml_length, const char *url="untitled.xml")
void ForEachChildElement(NodeCallback const &callback) const
llvm::StringRef GetName() const
bool GetElementText(std::string &text) const
std::string GetAttributeValue(const char *name, const char *fail_value=nullptr) const
bool NameIs(const char *name) const
void ForEachChildElementWithName(const char *name, NodeCallback const &callback) const
XMLNode FindFirstChildElementWithName(const char *name) const
void ForEachAttribute(AttributeCallback const &callback) const
@ eBroadcastBitRunPacketSent
PacketResult SendPacketAndReceiveResponseWithOutputSupport(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout, llvm::function_ref< void(llvm::StringRef)> output_callback)
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0), bool sync_on_timeout=true)
lldb::StateType SendContinuePacketAndWaitForResponse(ContinueDelegate &delegate, const UnixSignals &signals, llvm::StringRef payload, std::chrono::seconds interrupt_timeout, StringExtractorGDBRemote &response)
bool SupportsGDBStoppointPacket(GDBStoppointType type)
llvm::Expected< std::string > ReadExtFeature(llvm::StringRef object, llvm::StringRef annex)
void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm)
bool GetQXferLibrariesSVR4ReadSupported()
bool GetQXferLibrariesReadSupported()
void DumpHistory(Stream &strm)
Status FlashErase(lldb::addr_t addr, size_t size)
Status DisableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buf) override
Override of DoReadMemoryRanges that uses MultiMemRead to perform this operation in a single packet.
friend class ThreadGDBRemote
DataExtractor GetAuxvData() override
GDBRemoteCommunicationClient & GetGDBRemote()
static bool AcceleratorBreakpointHitCallback(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
Breakpoint callback invoked when an accelerator-plugin-requested breakpoint is hit.
Status DoConnectRemote(llvm::StringRef remote_url) override
Attach to a remote system via a URL.
void HandleAsyncStructuredDataPacket(llvm::StringRef data) override
Process asynchronously-received structured data.
void KillDebugserverProcess()
Status DoDestroy() override
llvm::Error DoDisableBreakpointSite(BreakpointSite &bp_site)
Disable a single breakpoint site directly by sending the appropriate z packet or restoring the origin...
std::vector< std::unique_ptr< RegisterType > > m_register_types
Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info)
virtual std::shared_ptr< ThreadGDBRemote > CreateThread(lldb::tid_t tid)
StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(lldb::addr_t image_list_address, lldb::addr_t image_count) override
Retrieve the list of shared libraries that are loaded for this process This method is used on pre-mac...
llvm::Error HandleAcceleratorActions(const AcceleratorActions &actions)
Handle a set of actions requested by an accelerator plugin.
lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet)
static void MonitorDebugserverProcess(std::weak_ptr< ProcessGDBRemote > process_wp, lldb::pid_t pid, int signo, int exit_status)
StructuredData::ObjectSP GetSharedCacheInfo() override
Status DisableBreakpointSite(BreakpointSite *bp_site) override
Status EnableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
Status DoSignal(int signal) override
Sends a process a UNIX signal signal.
Status DoDeallocateMemory(lldb::addr_t ptr) override
Actually deallocate memory in the process.
Broadcaster m_async_broadcaster
bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec)
llvm::Error UpdateBreakpointSitesNotBatched(const BreakpointSiteToActionMap &site_to_action)
bool StopNoticingNewThreads() override
Call this to turn off the stop & notice new threads mode.
static bool NewThreadNotifyBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid, bool is_expression_fork=false) override
Called after a reported fork.
void DumpPluginHistory(Stream &s) override
The underlying plugin might store the low-level communication history for this session.
FlashRangeVector m_erased_flash_ranges
Guarded< StructuredData::ObjectSP, std::mutex > m_shared_cache_info
Shared cache image list from the "jGetSharedCacheInfo" packet.
Status DoDetach(bool keep_stopped) override
Detaches from a running or stopped process.
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) override
Actually allocate memory in the process.
tid_sig_collection m_continue_C_tids
bool HasErased(FlashRange range)
std::optional< bool > DoGetWatchpointReportedAfter() override
Provide an override value in the subclass for lldb's CPU-based logic for whether watchpoint exception...
void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid, bool is_expression_fork=false) override
Called after a reported vfork.
Status WillLaunchOrAttach()
std::optional< uint32_t > GetWatchpointSlotCount() override
Get the number of watchpoints supported by this target.
GDBRemoteCommunicationClient m_gdb_comm
llvm::Expected< std::vector< uint8_t > > DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) override
Does the final operation to read memory tags.
llvm::DenseMap< ModuleCacheKey, ModuleSpec, ModuleCacheInfo > m_cached_module_specs
Status DoWillAttachToProcessWithID(lldb::pid_t pid) override
Called before attaching to a process.
friend class GDBRemoteCommunicationClient
void DidForkSwitchSoftwareBreakpoints(bool enable, bool is_expression_fork=false)
Status DoResume(lldb::RunDirection direction) override
Resumes all of a process's threads as configured using the Thread run control functions.
std::unordered_map< lldb::tid_t, size_t > m_thread_id_positions
The position of each ID in m_thread_ids, for FindThreadIDIndex.
Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo ®ion_info) override
DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has removed non address bits from loa...
void DidLaunchOrAttach(ArchSpec &process_arch)
size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value)
FlashRangeVector::Entry FlashRange
Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded, lldb::addr_t &load_addr) override
Try to find the load address of a file.
MMapMap m_addr_to_mmap_size
bool GetThreadStopInfoFromJSON(ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp)
void DidLaunch() override
Called after launching a process.
void SetUserSpecifiedMaxMemoryTransferSize(uint64_t user_specified_max)
void AddRemoteRegisters(std::vector< DynamicRegisterInfo::Register > ®isters, const ArchSpec &arch_to_use)
Status UpdateAutomaticSignalFiltering() override
void HandleAsyncStdout(llvm::StringRef out) override
static llvm::StringRef GetPluginDescriptionStatic()
tid_sig_collection m_continue_S_tids
bool m_allow_flash_writes
lldb::BreakpointSP m_thread_create_bp_sp
std::map< uint32_t, std::string > ExpeditedRegisterMap
llvm::Error TraceStop(const TraceStopRequest &request) override
Stop tracing a live process or its threads.
StructuredData::ObjectSP GetExtendedInfoForThread(lldb::tid_t tid)
llvm::Error DoEnableBreakpointSite(BreakpointSite &bp_site)
Enable a single breakpoint site by trying Z0 (software), then Z1 (hardware), then manual memory write...
lldb::ThreadSP HandleThreadAsyncInterrupt(uint8_t signo, const std::string &description) override
Handle thread specific async interrupt and return the original thread that requested the async interr...
llvm::Expected< LoadedModuleInfoList > GetLoadedModuleList() override
Query remote GDBServer for a detailed loaded library list.
bool AcceleratorBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
bool m_waiting_for_attach
llvm::Error HandleAcceleratorConnection(const AcceleratorActions &actions)
Create a new target for an accelerator and connect it to the GDB server described by the action's con...
llvm::Error GetGDBServerRegisterInfo(ArchSpec &arch)
Status DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a process ID.
void HandleStopReply() override
Status EstablishConnectionIfNeeded(const ProcessInfo &process_info)
llvm::Error UpdateBreakpointSites(const BreakpointSiteToActionMap &site_to_action) override
bool UpdateThreadIDList()
static llvm::StringRef GetPluginNameStatic()
Status DoHalt(bool &caused_stop) override
Halts a running process.
uint64_t m_last_signals_version
llvm::Expected< TraceSupportedResponse > TraceSupported() override
Get the processor tracing type supported for this process.
std::map< std::string, int64_t > m_processed_accelerator_actions
Tracks the last action identifier handled per accelerator plugin so the same actions are not processe...
llvm::Error TraceStart(const llvm::json::Value &request) override
Start tracing a process or its threads.
void ParseExpeditedRegisters(ExpeditedRegisterMap &expedited_register_map, lldb::ThreadSP thread_sp)
size_t DoReadMemory(const ProcessAddress &process_addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a process.
void WillPublicStop() override
Called when the process is about to broadcast a public stop.
Status SendEventData(const char *data) override
std::optional< size_t > FindThreadIDIndex(lldb::tid_t tid)
bool StartNoticingNewThreads() override
Call this to set the lldb in the mode where it breaks on new thread creations, and then auto-restarts...
DynamicLoader * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
void RemoveNewThreadBreakpoints()
Remove the breakpoints associated with thread creation from the Target.
ArchSpec GetSystemArchitecture() override
Get the system architecture for this process.
Status ConfigureStructuredData(llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) override
Configure asynchronous structured data feature.
bool SupportsReverseDirection() override
Reports whether this process supports reverse execution.
void DidExec() override
Called after a process re-execs itself.
size_t PutSTDIN(const char *buf, size_t buf_size, Status &error) override
Puts data into this process's STDIN.
Guarded< StructuredData::ObjectSP, std::mutex > m_jthreadsinfo
Full stop info, expedited registers and memory for all threads, from the "jThreadsInfo" packet.
static void DebuggerInitialize(Debugger &debugger)
tid_collection m_thread_ids
Status DoAttachToProcessWithName(const char *process_name, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a partial process name.
std::string m_partial_profile_data
StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos_sender(StructuredData::ObjectSP args)
void MaybeLoadExecutableModule()
std::vector< lldb::addr_t > m_thread_pcs
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
void SetThreadPc(const lldb::ThreadSP &thread_sp, uint64_t index)
std::recursive_mutex m_async_thread_state_mutex
bool DoCanAllocateMemory() override
Determines whether DoAllocateMemory is expected to succeed, without running code in the process.
Status ConnectToDebugserver(llvm::StringRef host_port)
void SetUnixSignals(const lldb::UnixSignalsSP &signals_sp)
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
uint64_t m_remote_stub_max_memory_size
std::optional< StringExtractorGDBRemote > m_last_stop_packet
CommandObject * GetPluginCommandObject() override
Return a multi-word command object that can be used to expose plug-in specific commands.
int64_t m_breakpoint_pc_offset
size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, Status &error) override
Actually do the writing of memory to a process.
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override
Launch a new process.
lldb::CommandObjectSP m_command_sp
void DidVForkDone() override
Called after reported vfork completion.
std::string HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &inputStringExtractor)
bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, std::string xml_filename, std::vector< DynamicRegisterInfo::Register > ®isters)
lldb::tid_t m_last_stop_primary_tid
bool m_use_g_packet_for_reading
Status DoWillAttachToProcessWithName(const char *process_name, bool wait_for_launch) override
Called before attaching to a process.
static std::chrono::seconds GetPacketTimeout()
lldb::ListenerSP m_async_listener_sp
std::pair< std::string, std::string > ModuleCacheKey
bool CalculateThreadStopInfo(ThreadGDBRemote *thread)
Guarded< StructuredData::ObjectSP, std::mutex > m_jstopinfo
Stop info caches filled at a stop and reset by WillResume, which runs on another thread.
lldb::DynamicRegisterInfoSP m_register_info_sp
tid_collection m_continue_c_tids
bool SupportsMemoryTagging() override
Check whether the process supports memory tagging.
void BuildDynamicRegisterInfo(bool force)
tid_collection m_continue_s_tids
size_t UpdateThreadPCsFromStopReplyThreadsValue(llvm::StringRef value)
~ProcessGDBRemote() override
llvm::VersionTuple GetHostOSVersion() override
Sometimes the connection to a process can detect the host OS version that the process is running on.
lldb::tid_t m_initial_tid
llvm::Expected< StringExtractorGDBRemote > SendMultiMemReadPacket(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges)
std::map< uint64_t, uint32_t > m_thread_id_to_used_usec_map
Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, const std::vector< uint8_t > &tags) override
Does the final operation to write memory tags.
llvm::Error ParseMultiMemReadPacket(llvm::StringRef response_str, llvm::MutableArrayRef< uint8_t > buffer, unsigned expected_num_ranges, llvm::SmallVectorImpl< llvm::MutableArrayRef< uint8_t > > &memory_regions)
llvm::Expected< std::vector< uint8_t > > TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override
Get binary data given a trace technology and a data identifier.
llvm::Error HandleAcceleratorBreakpoints(const AcceleratorActions &actions)
Set the breakpoints requested by an accelerator plugin as internal breakpoints with a callback that n...
Status EnableBreakpointSite(BreakpointSite *bp_site) override
void ModulesDidLoad(ModuleList &module_list) override
ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
uint32_t m_vfork_in_progress_count
@ eBroadcastBitAsyncContinue
@ eBroadcastBitAsyncThreadShouldExit
@ eBroadcastBitAsyncThreadDidExit
Status WillResume() override
Called before resuming to a process.
lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr, bool value_is_offset)
void SetLastStopPacket(const StringExtractorGDBRemote &response)
lldb::thread_result_t AsyncThread()
Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries) override
static std::chrono::milliseconds GetPacketTestDelay()
llvm::Error LoadModules() override
Sometimes processes know how to retrieve and load shared libraries.
uint64_t m_max_memory_size
void HandleAsyncMisc(llvm::StringRef data) override
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path, bool can_connect)
void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple) override
llvm::VersionTuple GetHostMacCatalystVersion() override
void DidForkSwitchHardwareTraps(bool enable)
HostThread m_async_thread
StructuredData::ObjectSP GetDynamicLoaderProcessState() override
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override
Try to fetch the module specification for a module with the given file name and architecture.
Status DoWillLaunch(Module *module) override
Called before launching to a process.
void DidAttach(ArchSpec &process_arch) override
Called after attaching a process.
llvm::Expected< bool > SaveCore(llvm::StringRef outfile) override
Save core dump into the specified file.
std::atomic< lldb::pid_t > m_debugserver_pid
std::optional< Diagnostics::ArtifactProviderID > m_diagnostics_artifact_id
Registration for the packet-history diagnostics provider, if enabled.
llvm::Expected< std::string > TraceGetState(llvm::StringRef type) override
Get the current tracing state of the process and its threads.
bool IsAlive() override
Check if a process is still alive.
void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override
void SetQueueInfo(std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue)
void SetNewlyAddedBinaries(const std::vector< lldb::addr_t > &added_binaries)
void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr)
void PrivateSetRegisterUnavailable(uint32_t reg)
lldb::RegisterContextSP GetRegisterContext() override
void SetDetailedBinariesInfo(StructuredData::ObjectSP &detailed_info)
void SetAssociatedWithLibdispatchQueue(lldb_private::LazyBool associated_with_libdispatch_queue) override
bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef< uint8_t > data)
#define LLDB_INVALID_SITE_ID
#define LLDB_INVALID_WATCH_ID
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_THREAD_ID
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_INVALID_PROCESS_ID
#define LLDB_DEFAULT_ADDRESS_SPACE_ID
#define LLDB_REGNUM_GENERIC_PC
lldb::ByteOrder InlHostByteOrder()
std::vector< DynamicRegisterInfo::Register > GetFallbackRegisters(const ArchSpec &arch_to_use)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length)
bool StateIsRunningState(lldb::StateType state)
Check if a state represents a state where the process or thread is running.
bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr, lldb::addr_t addr, lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset)
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
const char * GetPermissionsAsCString(uint32_t permissions)
void DumpProcessGDBRemotePacketHistory(void *p, const char *path)
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::BreakpointSite > BreakpointSiteSP
RunDirection
Execution directions.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
ConnectionStatus
Connection Status Types.
@ eConnectionStatusSuccess
Success.
std::shared_ptr< lldb_private::UnixSignals > UnixSignalsSP
@ eFormatCString
Null-terminated C strings.
@ eFormatCharArray
Print characters with no single quotes, used for character arrays that can contain non printable char...
@ eFormatInstruction
Disassemble an opcode.
@ eFormatVoid
Do not print this.
@ eFormatComplex
Floating point complex type.
@ eFormatHexFloat
ISO C99 hex float string.
@ eFormatOSType
OS character codes encoded into an integer 'PICT' 'text' etc...
@ eFormatAddressInfo
Describe what an address points to (func + offset with file/line, symbol + offset,...
@ eFormatCharPrintable
Only printable characters, '.' if not printable.
@ eFormatComplexInteger
Integer complex type.
@ eFormatFloat128
Disambiguate between 128-bit long double (which uses eFormatFloat) and __float128 (which uses eFormat...
std::shared_ptr< lldb_private::Platform > PlatformSP
StateType
Process and Thread States.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ eStateConnected
Process is connected to remote debug services, but not launched or attached to anything yet.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateAttaching
Process is currently trying to attach.
@ eStateExited
Process has exited and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eSymbolSharedCacheUseInferiorSharedCacheOnly
@ eSymbolSharedCacheUseHostAndInferiorSharedCache
std::shared_ptr< lldb_private::Stream > StreamSP
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::Process > ProcessSP
Encoding
Register encoding definitions.
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
@ eEncodingSint
signed integer
std::shared_ptr< lldb_private::Event > EventSP
@ eReturnStatusSuccessFinishResult
@ eArgTypeUnsignedInteger
std::shared_ptr< lldb_private::Watchpoint > WatchpointSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::WatchpointResource > WatchpointResourceSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
BinaryInformationLevel
When the Process plugin can retrieve information about all binaries loaded in the target process,...
@ eBinaryInformationLevelAddrName
@ eBinaryInformationLevelAddrNameUUID
@ eBinaryInformationLevelFull
@ eBinaryInformationLevelAddrOnly
std::shared_ptr< lldb_private::Target > TargetSP
std::unique_ptr< lldb_private::Stream > StreamUP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindProcessPlugin
num used by the process plugin - e.g.
Actions to be performed in the native process on behalf of an accelerator plugin.
std::vector< AcceleratorBreakpointInfo > breakpoints
New breakpoints to set. Nothing to set if this is empty.
int64_t identifier
Unique identifier for this action within the plugin.
std::string plugin_name
Unique name identifying the accelerator plugin.
std::optional< AcceleratorConnectionInfo > connect_info
If set, the client should create a new target and connect to the accelerator GDB server described her...
std::string session_name
Human-readable label for the accelerator target.
Sent by the client when a plugin-requested breakpoint is hit.
AcceleratorBreakpointInfo breakpoint
std::vector< SymbolValue > symbol_values
int64_t identifier
Unique breakpoint ID used to identify this breakpoint in the BreakpointWasHit callback.
std::vector< std::string > symbol_names
Symbol names whose values should be supplied when the breakpoint is hit.
std::optional< AcceleratorBreakpointByAddress > by_address
Breakpoint by load address.
std::optional< AcceleratorBreakpointByName > by_name
Breakpoint by function name.
Information the client needs to connect to an accelerator GDB server.
std::string triple
Target triple for the accelerator target.
bool synchronous
If true, connect synchronously: the client blocks until the accelerator process is connected and stop...
std::optional< std::string > exe_path
Path to the executable to use when creating the accelerator target.
std::string connect_url
Connection URL the client should connect to (as in "process connect<url>").
std::string platform_name
Name of the platform to select when creating the accelerator target.
A binary to find and load into a Target.
lldb::addr_t value
Address where the binary should be loaded, or read out of memory.
UUID uuid
UUID of the binary to be loaded.
bool is_main_executable
Whether this is the process' main executable.
bool force_symbol_search
Allow the search to do a possibly expensive external search for the ObjectFile and/or SymbolFile.
bool set_address_in_target
Whether the address of the binary should be set in the Target if it is added.
bool notify
Whether ModulesDidLoad should be called once the binary has been added to the Target.
bool value_is_offset
A flag indicating that value is an address, or an offset to be applied to the file addresses.
const RegisterType * register_type
std::vector< uint32_t > value_regs
std::vector< uint32_t > invalidate_regs
Options used by Module::FindFunctions.
bool include_inlines
Include inlined functions.
bool include_symbols
Include the symbol table.
static Status ToFormat(const char *s, lldb::Format &format, size_t *byte_size_ptr)
BaseType GetRangeBase() const
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
BaseType GetRangeEnd() const
void SetByteSize(SizeType s)
jLLDBTraceGetBinaryData gdb-remote packet
jLLDBTraceStop gdb-remote packet