9#include "lldb/Host/Config.h"
14#include <netinet/in.h>
16#include <sys/socket.h>
21#include <sys/sysctl.h>
89#include "llvm/ADT/STLExtras.h"
90#include "llvm/ADT/ScopeExit.h"
91#include "llvm/ADT/StringMap.h"
92#include "llvm/ADT/StringSwitch.h"
93#include "llvm/Support/ErrorExtras.h"
94#include "llvm/Support/FormatAdapters.h"
95#include "llvm/Support/Threading.h"
96#include "llvm/Support/raw_ostream.h"
99#define DEBUGSERVER_BASENAME "debugserver"
101#define DEBUGSERVER_BASENAME "lldb-server.exe"
103#define DEBUGSERVER_BASENAME "lldb-server"
123 llvm::consumeError(file.takeError());
127 ((
Process *)p)->DumpPluginHistory(stream);
133#define LLDB_PROPERTIES_processgdbremote
134#include "ProcessGDBRemoteProperties.inc"
137#define LLDB_PROPERTIES_processgdbremote
138#include "ProcessGDBRemotePropertiesEnum.inc"
143 static llvm::StringRef GetSettingName() {
147 PluginProperties() : Properties() {
148 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
149 m_collection_sp->Initialize(g_processgdbremote_properties_def);
152 ~PluginProperties()
override =
default;
154 uint64_t GetPacketTimeout() {
155 const uint32_t idx = ePropertyPacketTimeout;
156 return GetPropertyAtIndexAs<uint64_t>(
157 idx, g_processgdbremote_properties[idx].default_uint_value);
160 bool SetPacketTimeout(uint64_t timeout) {
161 const uint32_t idx = ePropertyPacketTimeout;
162 return SetPropertyAtIndex(idx, timeout);
165 FileSpec GetTargetDefinitionFile()
const {
166 const uint32_t idx = ePropertyTargetDefinitionFile;
167 return GetPropertyAtIndexAs<FileSpec>(idx, {});
170 bool GetUseSVR4()
const {
171 const uint32_t idx = ePropertyUseSVR4;
172 return GetPropertyAtIndexAs<bool>(
173 idx, g_processgdbremote_properties[idx].default_uint_value != 0);
176 bool GetUseGPacketForReading()
const {
177 const uint32_t idx = ePropertyUseGPacketForReading;
178 return GetPropertyAtIndexAs<bool>(idx,
true);
182std::chrono::seconds ResumeTimeout() {
return std::chrono::seconds(5); }
187 static PluginProperties g_settings;
195#if defined(__APPLE__)
196#define LOW_PORT (IPPORT_RESERVED)
197#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
199#define LOW_PORT (1024u)
200#define HIGH_PORT (49151u)
204 return "GDB Remote protocol based debugging plug-in.";
213 const FileSpec *crash_file_path,
bool can_connect) {
233 bool plugin_specified_by_name) {
234 if (plugin_specified_by_name)
238 Module *exe_module = target_sp->GetExecutableModulePointer();
242 switch (exe_objfile->
GetType()) {
266 :
Process(target_sp, listener_sp),
270 Listener::MakeListener(
"lldb.process.gdb-remote.async-listener")),
281 "async thread should exit");
283 "async thread continue");
285 "async thread did exit");
289 const uint32_t async_event_mask =
295 "ProcessGDBRemote::%s failed to listen for "
296 "m_async_broadcaster events",
300 const uint64_t timeout_seconds =
302 if (timeout_seconds > 0)
303 m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
327std::shared_ptr<ThreadGDBRemote>
329 return std::make_shared<ThreadGDBRemote>(*
this, tid);
333 const FileSpec &target_definition_fspec) {
339 if (module_object_sp) {
342 "gdb-server-target-definition",
error));
344 if (target_definition_sp) {
346 target_definition_sp->GetValueForKey(
"host-info"));
348 if (
auto host_info_dict = target_object->GetAsDictionary()) {
350 host_info_dict->GetValueForKey(
"triple");
351 if (
auto triple_string_value = triple_value->GetAsString()) {
352 std::string triple_string =
353 std::string(triple_string_value->GetValue());
354 ArchSpec host_arch(triple_string.c_str());
363 target_definition_sp->GetValueForKey(
"breakpoint-pc-offset");
364 if (breakpoint_pc_offset_value) {
365 if (
auto breakpoint_pc_int_value =
366 breakpoint_pc_offset_value->GetAsSignedInteger())
371 *target_definition_sp,
GetTarget().GetArchitecture()) > 0) {
380 const llvm::StringRef &comma_separated_register_numbers,
381 std::vector<uint32_t> ®nums,
int base) {
383 for (llvm::StringRef x : llvm::split(comma_separated_register_numbers,
',')) {
385 if (llvm::to_integer(x, reg, base))
386 regnums.push_back(reg);
388 return regnums.size();
400 const auto host_packet_timeout =
m_gdb_comm.GetHostDefaultPacketTimeout();
401 if (host_packet_timeout > std::chrono::seconds(0)) {
419 if (target_definition_fspec) {
425 target_definition_fspec.
GetPath() +
436 if (remote_process_arch.
IsValid())
437 arch_to_use = remote_process_arch;
439 arch_to_use = remote_host_arch;
442 arch_to_use = target_arch;
445 if (!register_info_err) {
452 "Failed to read register information from target XML: {0}");
453 LLDB_LOG(log,
"Now trying to use qRegisterInfo instead.");
456 std::vector<DynamicRegisterInfo::Register> registers;
457 uint32_t reg_num = 0;
461 const int packet_len =
462 ::snprintf(packet,
sizeof(packet),
"qRegisterInfo%x", reg_num);
463 assert(packet_len < (
int)
sizeof(packet));
466 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
470 llvm::StringRef name;
471 llvm::StringRef value;
475 if (name ==
"name") {
477 }
else if (name ==
"alt-name") {
479 }
else if (name ==
"bitsize") {
480 if (!value.getAsInteger(0, reg_info.
byte_size))
482 }
else if (name ==
"offset") {
484 }
else if (name ==
"encoding") {
488 }
else if (name ==
"format") {
492 llvm::StringSwitch<Format>(value)
534 }
else if (name ==
"set") {
536 }
else if (name ==
"gcc" || name ==
"ehframe") {
538 }
else if (name ==
"dwarf") {
540 }
else if (name ==
"generic") {
542 }
else if (name ==
"container-regs") {
544 }
else if (name ==
"invalidate-regs") {
550 registers.push_back(reg_info);
563 "the debug server supports Target Description XML but LLDB does "
564 "not have XML parsing enabled. Using \"qRegisterInfo\" was also "
565 "not possible. Register information may be incorrect or missing",
575 if (registers.empty()) {
577 if (!registers.empty())
580 "All other methods failed, using fallback register information.");
595 bool wait_for_launch) {
627 if (
m_gdb_comm.GetProcessArchitecture().IsValid()) {
630 if (
m_gdb_comm.GetHostArchitecture().IsValid()) {
641 "Process %" PRIu64
" was reported after connecting to "
642 "'%s', but state was not stopped: %s",
646 "Process %" PRIu64
" was reported after connecting to '%s', "
647 "but no stop reply packet was received",
648 pid, remote_url.str().c_str());
652 "ProcessGDBRemote::%s pid %" PRIu64
653 ": normalizing target architecture initial triple: %s "
654 "(GetTarget().GetArchitecture().IsValid() %s, "
655 "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
656 __FUNCTION__,
GetID(),
657 GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
659 m_gdb_comm.GetHostArchitecture().IsValid() ?
"true" :
"false");
665 if (
m_gdb_comm.GetProcessArchitecture().IsValid())
672 "ProcessGDBRemote::%s pid %" PRIu64
673 ": normalized target architecture triple: %s",
674 __FUNCTION__,
GetID(),
675 GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
692 LLDB_LOGF(log,
"ProcessGDBRemote::%s() entered", __FUNCTION__);
694 uint32_t launch_flags = launch_info.
GetFlags().
Get();
717 if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
719 "ProcessGDBRemote::%s provided with STDIO paths via "
720 "launch_info: stdin=%s, stdout=%s, stderr=%s",
722 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
723 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
724 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
726 LLDB_LOGF(log,
"ProcessGDBRemote::%s no STDIO paths given via launch_info",
729 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
730 if (stdin_file_spec || disable_stdio) {
745 if (
error.Success()) {
747 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
752 if (!stdin_file_spec)
754 FileSpec::Style::native);
755 if (!stdout_file_spec)
757 FileSpec::Style::native);
758 if (!stderr_file_spec)
760 FileSpec::Style::native);
761 }
else if (platform_sp && platform_sp->IsHost()) {
766 if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
770 if (!stdin_file_spec)
771 stdin_file_spec = secondary_name;
773 if (!stdout_file_spec)
774 stdout_file_spec = secondary_name;
776 if (!stderr_file_spec)
777 stderr_file_spec = secondary_name;
781 "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
782 "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
785 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
786 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
787 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
791 "ProcessGDBRemote::%s final STDIO paths after all "
792 "adjustments: stdin=%s, stdout=%s, stderr=%s",
794 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
795 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
796 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
800 if (stdout_file_spec)
802 if (stderr_file_spec)
805 m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
806 m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
809 GetTarget().GetArchitecture().GetArchitectureName());
812 if (launch_event_data !=
nullptr && *launch_event_data !=
'\0')
813 m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
825 std::chrono::seconds(10));
832 if (llvm::Error err =
m_gdb_comm.LaunchProcess(args)) {
835 llvm::fmt_consume(std::move(err)));
842 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
864 if (!disable_stdio) {
870 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
error.AsCString());
880 if (!connect_url.empty()) {
881 LLDB_LOGF(log,
"ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
882 connect_url.str().c_str());
883 std::unique_ptr<ConnectionFileDescriptor> conn_up(
886 const uint32_t max_retry_count = 50;
887 uint32_t retry_count = 0;
896 if (retry_count >= max_retry_count)
899 std::this_thread::sleep_for(std::chrono::milliseconds(100));
923 m_gdb_comm.GetListThreadsInStopReplySupported();
930 auto handle_cmds = [&] (
const Args &args) ->
void {
934 entry.c_str(), response);
940 handle_cmds(platform_sp->GetExtraStartupCommands());
957 if (remote_process_arch.
IsValid()) {
958 process_arch = remote_process_arch;
959 LLDB_LOG(log,
"gdb-remote had process architecture, using {0} {1}",
963 process_arch =
m_gdb_comm.GetHostArchitecture();
965 "gdb-remote did not have process architecture, using gdb-remote "
966 "host architecture {0} {1}",
977 LLDB_LOG(log,
"analyzing target arch, currently {0} {1}",
989 if ((process_arch.
GetMachine() == llvm::Triple::arm ||
990 process_arch.
GetMachine() == llvm::Triple::thumb) &&
991 process_arch.
GetTriple().getVendor() == llvm::Triple::Apple) {
994 "remote process is ARM/Apple, "
995 "setting target arch to {0} {1}",
1000 const llvm::Triple &remote_triple = process_arch.
GetTriple();
1001 llvm::Triple new_target_triple = target_arch.
GetTriple();
1002 if (new_target_triple.getVendorName().size() == 0) {
1003 new_target_triple.setVendor(remote_triple.getVendor());
1005 if (new_target_triple.getOSName().size() == 0) {
1006 new_target_triple.setOS(remote_triple.getOS());
1008 if (new_target_triple.getEnvironmentName().size() == 0)
1009 new_target_triple.setEnvironment(remote_triple.getEnvironment());
1012 ArchSpec new_target_arch = target_arch;
1013 new_target_arch.
SetTriple(new_target_triple);
1019 "final target arch after adjustments for remote architecture: "
1038 m_gdb_comm.GetSupportedStructuredDataPlugins())
1047 if (platform_sp && platform_sp->IsConnected())
1059 UUID standalone_uuid;
1061 bool standalone_value_is_offset;
1062 if (
m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value,
1063 standalone_value_is_offset)) {
1066 if (standalone_uuid.
IsValid()) {
1067 const bool force_symbol_search =
true;
1068 const bool notify =
true;
1069 const bool set_address_in_target =
true;
1070 const bool allow_memory_image_last_resort =
false;
1072 this,
"", standalone_uuid, standalone_value,
1073 standalone_value_is_offset, force_symbol_search, notify,
1074 set_address_in_target, allow_memory_image_last_resort);
1086 std::vector<addr_t> bin_addrs =
m_gdb_comm.GetProcessStandaloneBinaries();
1087 if (bin_addrs.size()) {
1089 const bool value_is_slide =
false;
1090 for (
addr_t addr : bin_addrs) {
1091 const bool notify =
true;
1098 .LoadPlatformBinaryAndSetup(
this, addr, notify))
1101 const bool force_symbol_search =
true;
1102 const bool set_address_in_target =
true;
1103 const bool allow_memory_image_last_resort =
false;
1106 this, llvm::StringRef(), uuid, addr, value_is_slide,
1107 force_symbol_search, notify, set_address_in_target,
1108 allow_memory_image_last_resort);
1118 std::optional<QOffsets> offsets =
m_gdb_comm.GetQOffsets();
1123 size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==
1124 offsets->offsets.size();
1128 bool changed =
false;
1129 module_sp->SetLoadAddress(
GetTarget(), offsets->offsets[0],
1134 m_process->GetTarget().ModulesDidLoad(list);
1148 LLDB_LOGF(log,
"ProcessGDBRemote::%s()", __FUNCTION__);
1154 if (
error.Success()) {
1158 const int packet_len =
1159 ::snprintf(packet,
sizeof(packet),
"vAttach;%" PRIx64, attach_pid);
1162 std::make_shared<EventDataBytes>(llvm::StringRef(packet, packet_len));
1177 if (process_name && process_name[0]) {
1179 if (
error.Success()) {
1185 if (!
m_gdb_comm.GetVAttachOrWaitSupported()) {
1200 auto data_sp = std::make_shared<EventDataBytes>(packet.
GetString());
1221llvm::Expected<std::string>
1226llvm::Expected<std::vector<uint8_t>>
1238 process_arch.
Clear();
1254 return m_gdb_comm.GetReverseStepSupported() ||
1261 LLDB_LOGF(log,
"ProcessGDBRemote::Resume(%s)",
1266 if (listener_sp->StartListeningForEvents(
1268 listener_sp->StartListeningForEvents(
1275 bool continue_packet_error =
false;
1289 std::string pid_prefix;
1291 pid_prefix = llvm::formatv(
"p{0:x-}.",
GetID());
1293 if (num_continue_c_tids == num_threads ||
1298 continue_packet.
Format(
"vCont;c:{0}-1", pid_prefix);
1306 for (tid_collection::const_iterator
1309 t_pos != t_end; ++t_pos)
1310 continue_packet.
Format(
";c:{0}{1:x-}", pid_prefix, *t_pos);
1312 continue_packet_error =
true;
1317 for (tid_sig_collection::const_iterator
1320 s_pos != s_end; ++s_pos)
1321 continue_packet.
Format(
";C{0:x-2}:{1}{2:x-}", s_pos->second,
1322 pid_prefix, s_pos->first);
1324 continue_packet_error =
true;
1329 for (tid_collection::const_iterator
1332 t_pos != t_end; ++t_pos)
1333 continue_packet.
Format(
";s:{0}{1:x-}", pid_prefix, *t_pos);
1335 continue_packet_error =
true;
1340 for (tid_sig_collection::const_iterator
1343 s_pos != s_end; ++s_pos)
1344 continue_packet.
Format(
";S{0:x-2}:{1}{2:x-}", s_pos->second,
1345 pid_prefix, s_pos->first);
1347 continue_packet_error =
true;
1350 if (continue_packet_error)
1351 continue_packet.
Clear();
1354 continue_packet_error =
true;
1360 if (num_continue_c_tids > 0) {
1361 if (num_continue_c_tids == num_threads) {
1365 continue_packet_error =
false;
1366 }
else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
1367 num_continue_s_tids == 0 && num_continue_S_tids == 0) {
1371 continue_packet_error =
false;
1375 if (continue_packet_error && num_continue_C_tids > 0) {
1376 if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
1377 num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
1378 num_continue_S_tids == 0) {
1381 if (num_continue_C_tids > 1) {
1386 if (num_continue_C_tids > 1) {
1387 continue_packet_error =
false;
1390 continue_packet_error =
true;
1393 if (!continue_packet_error)
1397 continue_packet_error =
false;
1400 if (!continue_packet_error) {
1402 continue_packet.
Printf(
"C%2.2x", continue_signo);
1407 if (continue_packet_error && num_continue_s_tids > 0) {
1408 if (num_continue_s_tids == num_threads) {
1414 continue_packet_error =
false;
1415 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1416 num_continue_s_tids == 1 && num_continue_S_tids == 0) {
1420 continue_packet_error =
false;
1424 if (!continue_packet_error && num_continue_S_tids > 0) {
1425 if (num_continue_S_tids == num_threads) {
1428 continue_packet_error =
false;
1429 if (num_continue_S_tids > 1) {
1430 for (
size_t i = 1; i < num_threads; ++i) {
1432 continue_packet_error =
true;
1435 if (!continue_packet_error) {
1438 continue_packet.
Printf(
"S%2.2x", step_signo);
1440 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1441 num_continue_s_tids == 0 && num_continue_S_tids == 1) {
1445 continue_packet_error =
false;
1451 if (num_continue_s_tids > 0 || num_continue_S_tids > 0) {
1453 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1454 "support reverse-stepping");
1456 "target does not support reverse-stepping");
1459 if (num_continue_S_tids > 0) {
1462 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1464 "can't deliver signals while running in reverse");
1467 if (num_continue_s_tids > 1) {
1468 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: can't step multiple "
1469 "threads in reverse");
1471 "can't step multiple threads while reverse-stepping");
1477 if (!
m_gdb_comm.GetReverseContinueSupported()) {
1478 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1479 "support reverse-continue");
1481 "target does not support reverse execution of processes");
1484 if (num_continue_C_tids > 0) {
1487 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1489 "can't deliver signals while running in reverse");
1497 continue_packet_error =
false;
1500 if (continue_packet_error) {
1502 "can't make continue packet for this resume");
1507 "Trying to resume but the async thread is dead.");
1508 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Trying to resume but the "
1509 "async thread is dead.");
1514 std::make_shared<EventDataBytes>(continue_packet.
GetString());
1517 if (!listener_sp->GetEvent(event_sp, ResumeTimeout())) {
1519 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Resume timed out.");
1522 "Broadcast continue, but the async thread was "
1523 "killed before we got an ack back.");
1525 "ProcessGDBRemote::DoResume: Broadcast continue, but the "
1526 "async thread was killed before we got an ack back.");
1542 llvm::StringRef value) {
1548 auto pid_tid = thread_ids.
GetPidTid(pid);
1549 if (pid_tid && pid_tid->first == pid) {
1555 }
while (thread_ids.
GetChar() ==
',');
1561 llvm::StringRef value) {
1563 for (llvm::StringRef x : llvm::split(value,
',')) {
1565 if (llvm::to_integer(x,
pc, 16))
1577 if (thread_infos && thread_infos->
GetSize() > 0) {
1601 const llvm::StringRef stop_info_str = stop_info.
GetStringRef();
1604 const size_t thread_pcs_pos = stop_info_str.find(
";thread-pcs:");
1605 if (thread_pcs_pos != llvm::StringRef::npos) {
1606 const size_t start = thread_pcs_pos + strlen(
";thread-pcs:");
1607 const size_t end = stop_info_str.find(
';', start);
1608 if (end != llvm::StringRef::npos) {
1609 llvm::StringRef value = stop_info_str.substr(start, end - start);
1614 const size_t threads_pos = stop_info_str.find(
";threads:");
1615 if (threads_pos != llvm::StringRef::npos) {
1616 const size_t start = threads_pos + strlen(
";threads:");
1617 const size_t end = stop_info_str.find(
';', start);
1618 if (end != llvm::StringRef::npos) {
1619 llvm::StringRef value = stop_info_str.substr(start, end - start);
1627 bool sequence_mutex_unavailable =
false;
1629 if (sequence_mutex_unavailable) {
1644 if (num_thread_ids == 0) {
1650 ThreadList old_thread_list_copy(old_thread_list);
1651 if (num_thread_ids > 0) {
1652 for (
size_t i = 0; i < num_thread_ids; ++i) {
1659 thread_sp.get(), thread_sp->GetID());
1662 thread_sp.get(), thread_sp->GetID());
1672 size_t old_num_thread_ids = old_thread_list_copy.
GetSize(
false);
1673 for (
size_t i = 0; i < old_num_thread_ids; i++) {
1675 if (old_thread_sp) {
1676 lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
1691 uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1704 if (thread_infos_sp) {
1708 const size_t n = thread_infos->
GetSize();
1709 for (
size_t i = 0; i < n; ++i) {
1715 if (tid == thread->GetID())
1744 if (
GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
1754 for (
const auto &pair : expedited_register_map) {
1758 reg_value_extractor.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
1759 uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1767 uint8_t signo,
const std::string &thread_name,
const std::string &reason,
1768 const std::string &description, uint32_t exc_type,
1769 const std::vector<addr_t> &exc_data,
addr_t thread_dispatch_qaddr,
1770 bool queue_vars_valid,
1772 LazyBool associated_with_dispatch_queue,
addr_t dispatch_queue_t,
1773 std::string &queue_name,
QueueKind queue_kind, uint64_t queue_serial,
1774 std::vector<lldb::addr_t> &added_binaries,
1799 reg_ctx_sp->InvalidateIfNeeded(
true);
1807 if (reg_ctx_sp->ReconfigureRegisterInfo()) {
1810 reg_ctx_sp->InvalidateAllRegisters();
1817 thread_sp->SetName(thread_name.empty() ?
nullptr : thread_name.c_str());
1822 if (queue_vars_valid)
1823 gdb_thread->
SetQueueInfo(std::move(queue_name), queue_kind, queue_serial,
1824 dispatch_queue_t, associated_with_dispatch_queue);
1838 StopInfoSP current_stop_info_sp = thread_sp->GetPrivateStopInfo(
false);
1840 current_stop_info_sp) {
1841 thread_sp->SetStopInfo(current_stop_info_sp);
1845 if (!thread_sp->StopInfoIsUpToDate()) {
1848 addr_t pc = thread_sp->GetRegisterContext()->GetPC();
1850 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1852 thread_sp->SetThreadStoppedAtUnexecutedBP(
pc);
1854 if (exc_type != 0) {
1862 if (interrupt_thread)
1863 thread_sp = interrupt_thread;
1865 const size_t exc_data_size = exc_data.size();
1866 thread_sp->SetStopInfo(
1868 *thread_sp, exc_type, exc_data_size,
1869 exc_data_size >= 1 ? exc_data[0] : 0,
1870 exc_data_size >= 2 ? exc_data[1] : 0,
1871 exc_data_size >= 3 ? exc_data[2] : 0));
1874 bool handled =
false;
1875 bool did_exec =
false;
1878 if (!reason.empty() && reason !=
"none") {
1879 if (reason ==
"trace") {
1882 }
else if (reason ==
"breakpoint") {
1883 thread_sp->SetThreadHitBreakpointSite();
1891 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
1892 thread_sp->SetStopInfo(
1894 *thread_sp, bp_site_sp->GetID()));
1897 thread_sp->SetStopInfo(invalid_stop_info_sp);
1900 }
else if (reason ==
"trap") {
1902 }
else if (reason ==
"watchpoint") {
1938 bool silently_continue =
false;
1948 silently_continue =
true;
1952 if (!wp_resource_sp) {
1954 LLDB_LOGF(log,
"failed to find watchpoint");
1961 watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
1964 *thread_sp, watch_id, silently_continue));
1966 }
else if (reason ==
"exception") {
1968 *thread_sp, description.c_str()));
1970 }
else if (reason ==
"history boundary") {
1972 *thread_sp, description.c_str()));
1974 }
else if (reason ==
"exec") {
1976 thread_sp->SetStopInfo(
1979 }
else if (reason ==
"processor trace") {
1981 *thread_sp, description.c_str()));
1982 }
else if (reason ==
"fork") {
1987 thread_sp->SetStopInfo(
1990 }
else if (reason ==
"vfork") {
1996 *thread_sp, child_pid, child_tid));
1998 }
else if (reason ==
"vforkdone") {
1999 thread_sp->SetStopInfo(
2005 if (!handled && signo && !did_exec) {
2026 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
2036 thread_sp->SetThreadHitBreakpointSite();
2038 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2040 thread_sp->GetRegisterContext()->SetPC(
pc);
2041 thread_sp->SetStopInfo(
2043 *thread_sp, bp_site_sp->GetID()));
2046 thread_sp->SetStopInfo(invalid_stop_info_sp);
2052 thread_sp->SetStopInfo(
2056 *thread_sp, signo, description.c_str()));
2067 if (interrupt_thread)
2068 thread_sp = interrupt_thread;
2071 *thread_sp, signo, description.c_str()));
2075 if (!description.empty()) {
2078 const char *stop_info_desc = stop_info_sp->GetDescription();
2079 if (!stop_info_desc || !stop_info_desc[0])
2080 stop_info_sp->SetDescription(description.c_str());
2083 *thread_sp, description.c_str()));
2093 const std::string &description) {
2102 *thread_sp, signo, description.c_str()));
2111 static constexpr llvm::StringLiteral g_key_tid(
"tid");
2112 static constexpr llvm::StringLiteral g_key_name(
"name");
2113 static constexpr llvm::StringLiteral g_key_reason(
"reason");
2114 static constexpr llvm::StringLiteral g_key_metype(
"metype");
2115 static constexpr llvm::StringLiteral g_key_medata(
"medata");
2116 static constexpr llvm::StringLiteral g_key_qaddr(
"qaddr");
2117 static constexpr llvm::StringLiteral g_key_dispatch_queue_t(
2118 "dispatch_queue_t");
2119 static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(
2120 "associated_with_dispatch_queue");
2121 static constexpr llvm::StringLiteral g_key_queue_name(
"qname");
2122 static constexpr llvm::StringLiteral g_key_queue_kind(
"qkind");
2123 static constexpr llvm::StringLiteral g_key_queue_serial_number(
"qserialnum");
2124 static constexpr llvm::StringLiteral g_key_registers(
"registers");
2125 static constexpr llvm::StringLiteral g_key_memory(
"memory");
2126 static constexpr llvm::StringLiteral g_key_description(
"description");
2127 static constexpr llvm::StringLiteral g_key_signal(
"signal");
2128 static constexpr llvm::StringLiteral g_key_added_binaries(
"added-binaries");
2129 static constexpr llvm::StringLiteral g_key_detailed_binaries_info(
2130 "detailed-binaries-info");
2135 std::string thread_name;
2137 std::string description;
2138 uint32_t exc_type = 0;
2139 std::vector<addr_t> exc_data;
2142 bool queue_vars_valid =
false;
2145 std::string queue_name;
2147 uint64_t queue_serial_number = 0;
2148 std::vector<addr_t> added_binaries;
2154 thread_dict->
ForEach([
this, &tid, &expedited_register_map, &thread_name,
2155 &signo, &reason, &description, &exc_type, &exc_data,
2156 &thread_dispatch_qaddr, &queue_vars_valid,
2157 &associated_with_dispatch_queue, &dispatch_queue_t,
2158 &queue_name, &queue_kind, &queue_serial_number,
2159 &added_binaries, &detailed_binaries_info](
2160 llvm::StringRef key,
2162 if (key == g_key_tid) {
2165 }
else if (key == g_key_metype) {
2167 exc_type =
object->GetUnsignedIntegerValue(0);
2168 }
else if (key == g_key_medata) {
2173 exc_data.push_back(object->GetUnsignedIntegerValue());
2177 }
else if (key == g_key_name) {
2178 thread_name = std::string(object->GetStringValue());
2179 }
else if (key == g_key_qaddr) {
2180 thread_dispatch_qaddr =
2182 }
else if (key == g_key_queue_name) {
2183 queue_vars_valid =
true;
2184 queue_name = std::string(object->GetStringValue());
2185 }
else if (key == g_key_queue_kind) {
2186 std::string queue_kind_str = std::string(object->GetStringValue());
2187 if (queue_kind_str ==
"serial") {
2188 queue_vars_valid =
true;
2190 }
else if (queue_kind_str ==
"concurrent") {
2191 queue_vars_valid =
true;
2194 }
else if (key == g_key_queue_serial_number) {
2195 queue_serial_number =
object->GetUnsignedIntegerValue(0);
2196 if (queue_serial_number != 0)
2197 queue_vars_valid =
true;
2198 }
else if (key == g_key_dispatch_queue_t) {
2199 dispatch_queue_t =
object->GetUnsignedIntegerValue(0);
2201 queue_vars_valid =
true;
2202 }
else if (key == g_key_associated_with_dispatch_queue) {
2203 queue_vars_valid =
true;
2204 bool associated =
object->GetBooleanValue();
2209 }
else if (key == g_key_reason) {
2210 reason = std::string(object->GetStringValue());
2211 }
else if (key == g_key_description) {
2212 description = std::string(object->GetStringValue());
2213 }
else if (key == g_key_registers) {
2216 if (registers_dict) {
2218 [&expedited_register_map](llvm::StringRef key,
2221 if (llvm::to_integer(key, reg))
2222 expedited_register_map[reg] =
2223 std::string(object->GetStringValue());
2227 }
else if (key == g_key_memory) {
2233 if (mem_cache_dict) {
2236 "address", mem_cache_addr)) {
2238 llvm::StringRef str;
2243 const size_t byte_size = bytes.
GetStringRef().size() / 2;
2246 const size_t bytes_copied =
2248 if (bytes_copied == byte_size)
2258 }
else if (key == g_key_signal)
2260 else if (key == g_key_added_binaries) {
2263 array->
ForEach([&added_binaries](
2266 object->GetAsUnsignedInteger();
2270 added_binaries.push_back(value);
2275 }
else if (key == g_key_detailed_binaries_info) {
2280 if (object->GetAsDictionary()) {
2282 object->Dump(json_str);
2283 detailed_binaries_info =
2291 tid, expedited_register_map, signo, thread_name, reason, description,
2292 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2293 associated_with_dispatch_queue, dispatch_queue_t, queue_name, queue_kind,
2294 queue_serial_number, added_binaries, detailed_binaries_info);
2300 const char stop_type = stop_packet.
GetChar();
2301 switch (stop_type) {
2320 const uint8_t signo = stop_packet.
GetHexU8();
2321 llvm::StringRef key;
2322 llvm::StringRef value;
2323 std::string thread_name;
2325 std::string description;
2326 std::vector<addr_t> added_binaries;
2328 uint32_t exc_type = 0;
2329 std::vector<addr_t> exc_data;
2331 bool queue_vars_valid =
2335 std::string queue_name;
2337 uint64_t queue_serial_number = 0;
2341 if (key.compare(
"metype") == 0) {
2343 value.getAsInteger(16, exc_type);
2344 }
else if (key.compare(
"medata") == 0) {
2347 value.getAsInteger(16, x);
2348 exc_data.push_back(x);
2349 }
else if (key.compare(
"thread") == 0) {
2352 auto pid_tid = thread_id.
GetPidTid(pid);
2354 stop_pid = pid_tid->first;
2355 tid = pid_tid->second;
2358 }
else if (key.compare(
"threads") == 0) {
2359 std::lock_guard<std::recursive_mutex> guard(
2362 }
else if (key.compare(
"thread-pcs") == 0) {
2367 while (!value.empty()) {
2368 llvm::StringRef pc_str;
2369 std::tie(pc_str, value) = value.split(
',');
2370 if (pc_str.getAsInteger(16,
pc))
2374 }
else if (key.compare(
"jstopinfo") == 0) {
2383 }
else if (key.compare(
"hexname") == 0) {
2387 }
else if (key.compare(
"name") == 0) {
2388 thread_name = std::string(value);
2389 }
else if (key.compare(
"qaddr") == 0) {
2390 value.getAsInteger(16, thread_dispatch_qaddr);
2391 }
else if (key.compare(
"dispatch_queue_t") == 0) {
2392 queue_vars_valid =
true;
2393 value.getAsInteger(16, dispatch_queue_t);
2394 }
else if (key.compare(
"qname") == 0) {
2395 queue_vars_valid =
true;
2399 }
else if (key.compare(
"qkind") == 0) {
2400 queue_kind = llvm::StringSwitch<QueueKind>(value)
2405 }
else if (key.compare(
"qserialnum") == 0) {
2406 if (!value.getAsInteger(0, queue_serial_number))
2407 queue_vars_valid =
true;
2408 }
else if (key.compare(
"reason") == 0) {
2409 reason = std::string(value);
2410 }
else if (key.compare(
"description") == 0) {
2414 }
else if (key.compare(
"memory") == 0) {
2428 llvm::StringRef addr_str, bytes_str;
2429 std::tie(addr_str, bytes_str) = value.split(
'=');
2430 if (!addr_str.empty() && !bytes_str.empty()) {
2432 if (!addr_str.getAsInteger(0, mem_cache_addr)) {
2437 const size_t bytes_copied =
2439 if (bytes_copied == byte_size)
2443 }
else if (key.compare(
"watch") == 0 || key.compare(
"rwatch") == 0 ||
2444 key.compare(
"awatch") == 0) {
2447 value.getAsInteger(16, wp_addr);
2455 reason =
"watchpoint";
2457 ostr.
Printf(
"%" PRIu64, wp_addr);
2458 description = std::string(ostr.
GetString());
2459 }
else if (key.compare(
"swbreak") == 0 || key.compare(
"hwbreak") == 0) {
2460 reason =
"breakpoint";
2461 }
else if (key.compare(
"replaylog") == 0) {
2462 reason =
"history boundary";
2463 }
else if (key.compare(
"library") == 0) {
2469 }
else if (key.compare(
"fork") == 0 || key.compare(
"vfork") == 0) {
2475 LLDB_LOG(log,
"Invalid PID/TID to fork: {0}", value);
2481 ostr.
Printf(
"%" PRIu64
" %" PRIu64, pid_tid->first, pid_tid->second);
2482 description = std::string(ostr.
GetString());
2483 }
else if (key.compare(
"addressing_bits") == 0) {
2484 uint64_t addressing_bits;
2485 if (!value.getAsInteger(0, addressing_bits)) {
2488 }
else if (key.compare(
"low_mem_addressing_bits") == 0) {
2489 uint64_t addressing_bits;
2490 if (!value.getAsInteger(0, addressing_bits)) {
2493 }
else if (key.compare(
"high_mem_addressing_bits") == 0) {
2494 uint64_t addressing_bits;
2495 if (!value.getAsInteger(0, addressing_bits)) {
2498 }
else if (key ==
"added-binaries") {
2502 while (!value.empty()) {
2503 llvm::StringRef pc_str;
2504 std::tie(pc_str, value) = value.split(
',');
2505 if (pc_str.getAsInteger(16,
pc))
2507 added_binaries.push_back(
pc);
2509 }
else if (key ==
"detailed-binaries-info") {
2517 }
else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
2519 if (!key.getAsInteger(16, reg))
2520 expedited_register_map[reg] = std::string(std::move(value));
2530 "Received stop for incorrect PID = {0} (inferior PID = {1})",
2550 tid, expedited_register_map, signo, thread_name, reason, description,
2551 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2552 associated_with_dispatch_queue, dispatch_queue_t, queue_name,
2553 queue_kind, queue_serial_number, added_binaries,
2554 detailed_binaries_info);
2621 LLDB_LOGF(log,
"ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
2625 if (
error.Success())
2627 "ProcessGDBRemote::DoDetach() detach packet sent successfully");
2630 "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
2631 error.AsCString() ?
error.AsCString() :
"<unknown error>");
2634 if (!
error.Success())
2649 LLDB_LOGF(log,
"ProcessGDBRemote::DoDestroy()");
2652 int exit_status = SIGABRT;
2653 std::string exit_string;
2660 exit_status = kill_res.get();
2661#if defined(__APPLE__)
2673 if (platform_sp && platform_sp->IsHost()) {
2676 reap_pid = waitpid(
GetID(), &status, WNOHANG);
2677 LLDB_LOGF(log,
"Reaped pid: %d, status: %d.\n", reap_pid, status);
2681 exit_string.assign(
"killed");
2683 exit_string.assign(llvm::toString(kill_res.takeError()));
2686 exit_string.assign(
"killed or interrupted while attaching.");
2692 exit_string.assign(
"destroying when not connected to debugserver");
2713 const bool did_exec =
2714 response.
GetStringRef().find(
";reason:exec;") != std::string::npos;
2717 LLDB_LOGF(log,
"ProcessGDBRemote::SetLastStopPacket () - detected exec");
2722 m_gdb_comm.ResetDiscoverableSettings(did_exec);
2747 LLDB_LOG_ERROR(log, list.takeError(),
"Failed to read module list: {0}.");
2749 addr = list->m_link_map;
2769 const size_t n = thread_infos->
GetSize();
2770 for (
size_t i = 0; i < n; ++i) {
2786 xPacketState x_state =
m_gdb_comm.GetxPacketState();
2789 size_t max_memory_size = x_state != xPacketState::Unimplemented
2792 if (size > max_memory_size) {
2796 size = max_memory_size;
2801 packet_len = ::snprintf(packet,
sizeof(packet),
"%c%" PRIx64
",%" PRIx64,
2802 x_state != xPacketState::Unimplemented ?
'x' :
'm',
2803 (uint64_t)addr, (uint64_t)size);
2804 assert(packet_len + 1 < (
int)
sizeof(packet));
2807 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
2812 if (x_state != xPacketState::Unimplemented) {
2817 llvm::StringRef data_received = response.
GetStringRef();
2818 if (x_state == xPacketState::Prefixed &&
2819 !data_received.consume_front(
"b")) {
2821 "unexpected response to GDB server memory read packet '{0}': "
2823 packet, data_received);
2828 size_t memcpy_size = std::min(size, data_received.size());
2829 memcpy(buf, data_received.data(), memcpy_size);
2833 llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size),
'\xdd');
2837 "memory read failed for 0x%" PRIx64, addr);
2840 "GDB server does not support reading memory");
2843 "unexpected response to GDB server memory read packet '%s': '%s'",
2855 uint64_t max_packet_size,
2859 constexpr uint64_t range_overhead = 33;
2860 uint64_t current_size = 0;
2861 for (
auto [idx, range] : llvm::enumerate(ranges)) {
2862 uint64_t potential_size = current_size + range.size + range_overhead;
2863 if (potential_size > max_packet_size) {
2866 "MultiMemRead input has a range (base = {0:x}, size = {1}) "
2867 "bigger than the maximum allowed by remote",
2868 range.base, range.size);
2872 return ranges.size();
2875llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>
2878 llvm::MutableArrayRef<uint8_t> buffer) {
2882 const llvm::ArrayRef<Range<lldb::addr_t, size_t>> original_ranges = ranges;
2883 llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> memory_regions;
2885 while (!ranges.empty()) {
2886 uint64_t num_ranges =
2888 if (num_ranges == 0)
2891 auto ranges_for_request = ranges.take_front(num_ranges);
2892 ranges = ranges.drop_front(num_ranges);
2894 llvm::Expected<StringExtractorGDBRemote> response =
2898 "MultiMemRead error response: {0}");
2902 llvm::StringRef response_str = response->GetStringRef();
2903 const unsigned expected_num_ranges = ranges_for_request.size();
2905 response_str, buffer, expected_num_ranges, memory_regions)) {
2907 "MultiMemRead error parsing response: {0}");
2911 return memory_regions;
2914llvm::Expected<StringExtractorGDBRemote>
2917 std::string packet_str;
2918 llvm::raw_string_ostream stream(packet_str);
2919 stream <<
"MultiMemRead:ranges:";
2921 auto range_to_stream = [&](
auto range) {
2923 stream << llvm::formatv(
"{0:x-},{1:x-}", range.base, range.size);
2925 llvm::interleave(ranges, stream, range_to_stream,
",");
2930 m_gdb_comm.SendPacketAndWaitForResponse(packet_str.data(), response,
2933 return llvm::createStringErrorV(
"MultiMemRead failed to send packet: '{0}'",
2937 return llvm::createStringErrorV(
"MultiMemRead failed: '{0}'",
2941 return llvm::createStringErrorV(
"MultiMemRead unexpected response: '{0}'",
2948 llvm::StringRef response_str, llvm::MutableArrayRef<uint8_t> buffer,
2949 unsigned expected_num_ranges,
2952 auto [sizes_str, memory_data] = response_str.split(
';');
2953 if (sizes_str.size() == response_str.size())
2954 return llvm::createStringErrorV(
2955 "MultiMemRead response missing field separator ';' in: '{0}'",
2959 for (llvm::StringRef size_str : llvm::split(sizes_str,
',')) {
2961 if (size_str.getAsInteger(16, read_size))
2962 return llvm::createStringErrorV(
2963 "MultiMemRead response has invalid size string: {0}", size_str);
2965 if (memory_data.size() < read_size)
2966 return llvm::createStringErrorV(
"MultiMemRead response did not have "
2967 "enough data, requested sizes: {0}",
2970 llvm::StringRef region_to_read = memory_data.take_front(read_size);
2971 memory_data = memory_data.drop_front(read_size);
2973 assert(buffer.size() >= read_size);
2974 llvm::MutableArrayRef<uint8_t> region_to_write =
2975 buffer.take_front(read_size);
2976 buffer = buffer.drop_front(read_size);
2978 memcpy(region_to_write.data(), region_to_read.data(), read_size);
2979 memory_regions.push_back(region_to_write);
2982 return llvm::Error::success();
2986 return m_gdb_comm.GetMemoryTaggingSupported();
2989llvm::Expected<std::vector<uint8_t>>
2996 return llvm::createStringError(llvm::inconvertibleErrorCode(),
2997 "Error reading memory tags from remote");
3001 llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
3002 std::vector<uint8_t> got;
3003 got.reserve(tag_data.size());
3004 std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
3010 const std::vector<uint8_t> &tags) {
3013 return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
3017 std::vector<ObjectFile::LoadableData> entries) {
3027 if (
error.Success())
3041 for (
size_t i = 0; i < size; ++i)
3066 if (blocksize == 0) {
3074 lldb::addr_t block_start_addr = addr - (addr % blocksize);
3075 size += (addr - block_start_addr);
3076 if ((size % blocksize) != 0)
3077 size += (blocksize - size % blocksize);
3093 auto overlap = last_range.GetRangeEnd() - range.
GetRangeBase();
3114 "flash erase failed for 0x%" PRIx64, addr);
3117 "GDB server does not support flashing");
3120 "unexpected response to GDB server flash erase packet '%s': '%s'",
3137 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"vFlashDone", response,
3147 "GDB server does not support flashing");
3150 "unexpected response to GDB server flash done packet: '%s'",
3165 if (size > max_memory_size) {
3169 size = max_memory_size;
3189 if (!
error.Success())
3191 packet.
Printf(
"vFlashWrite:%" PRIx64
":", addr);
3194 packet.
Printf(
"M%" PRIx64
",%" PRIx64
":", addr, (uint64_t)size);
3207 "memory write failed for 0x%" PRIx64, addr);
3210 "GDB server does not support writing memory");
3213 "unexpected response to GDB server memory write packet '%s': '%s'",
3223 uint32_t permissions,
3229 allocated_addr =
m_gdb_comm.AllocateMemory(size, permissions);
3232 return allocated_addr;
3238 if (permissions & lldb::ePermissionsReadable)
3240 if (permissions & lldb::ePermissionsWritable)
3242 if (permissions & lldb::ePermissionsExecutable)
3251 "ProcessGDBRemote::%s no direct stub support for memory "
3252 "allocation, and InferiorCallMmap also failed - is stub "
3253 "missing register context save/restore capability?",
3260 "unable to allocate %" PRIu64
" bytes of memory with permissions %s",
3264 return allocated_addr;
3279 return m_gdb_comm.GetWatchpointReportedAfter();
3286 switch (supported) {
3291 "tried to deallocate memory without ever allocating memory");
3297 "unable to deallocate memory at 0x%" PRIx64, addr);
3309 "unable to deallocate memory at 0x%" PRIx64, addr);
3324 m_gdb_comm.SendStdinNotification(src, src_len);
3342 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3344 if (error_no == 0) {
3347 return llvm::Error::success();
3350 if (error_no != UINT8_MAX)
3351 return llvm::createStringErrorV(
3352 "error sending the breakpoint request: {0}", error_no);
3353 return llvm::createStringError(
"error sending the breakpoint request");
3355 LLDB_LOG(log,
"Software breakpoints are unsupported");
3360 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3362 if (error_no == 0) {
3365 return llvm::Error::success();
3368 if (error_no != UINT8_MAX)
3369 return llvm::createStringErrorV(
3370 "error sending the hardware breakpoint request: {0} "
3371 "(hardware breakpoint resources might be exhausted or unavailable)",
3373 return llvm::createStringError(
3374 "error sending the hardware breakpoint request "
3375 "(hardware breakpoint resources might be exhausted or unavailable)");
3377 LLDB_LOG(log,
"Hardware breakpoints are unsupported");
3381 return llvm::createStringError(
"hardware breakpoints are not supported");
3397 return error.takeError();
3403 return llvm::createStringError(
"unknown error");
3408 return llvm::createStringError(
"unknown error");
3412 return llvm::Error::success();
3416 assert(bp_site !=
nullptr);
3427 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3428 ") address = 0x%" PRIx64,
3429 site_id, (uint64_t)addr);
3434 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3435 ") address = 0x%" PRIx64
" -- SUCCESS (already enabled)",
3436 site_id, (uint64_t)addr);
3444 assert(bp_site !=
nullptr);
3449 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3450 ") addr = 0x%8.8" PRIx64,
3451 site_id, (uint64_t)addr);
3455 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3456 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3457 site_id, (uint64_t)addr);
3468 bool read = wp_res_sp->WatchpointResourceRead();
3469 bool write = wp_res_sp->WatchpointResourceWrite();
3471 assert((read || write) &&
3472 "WatchpointResource type is neither read nor write");
3488 addr_t addr = wp_sp->GetLoadAddress();
3490 LLDB_LOGF(log,
"ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
")",
3492 if (wp_sp->IsEnabled()) {
3494 "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
3495 ") addr = 0x%8.8" PRIx64
": watchpoint already enabled.",
3496 watchID, (uint64_t)addr);
3500 bool read = wp_sp->WatchpointRead();
3501 bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
3502 size_t size = wp_sp->GetByteSize();
3505 WatchpointHardwareFeature supported_features =
3508 std::vector<WatchpointResourceSP> resources =
3510 addr, size, read, write, supported_features, target_arch);
3535 bool set_all_resources =
true;
3536 std::vector<WatchpointResourceSP> succesfully_set_resources;
3537 for (
const auto &wp_res_sp : resources) {
3538 addr_t addr = wp_res_sp->GetLoadAddress();
3539 size_t size = wp_res_sp->GetByteSize();
3541 if (!
m_gdb_comm.SupportsGDBStoppointPacket(type) ||
3542 m_gdb_comm.SendGDBStoppointTypePacket(type,
true, addr, size,
3544 set_all_resources =
false;
3547 succesfully_set_resources.push_back(wp_res_sp);
3550 if (set_all_resources) {
3551 wp_sp->SetEnabled(
true, notify);
3552 for (
const auto &wp_res_sp : resources) {
3555 wp_res_sp->AddConstituent(wp_sp);
3563 for (
const auto &wp_res_sp : succesfully_set_resources) {
3564 addr_t addr = wp_res_sp->GetLoadAddress();
3565 size_t size = wp_res_sp->GetByteSize();
3567 m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3571 "Setting one of the watchpoint resources failed");
3587 addr_t addr = wp_sp->GetLoadAddress();
3590 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3591 ") addr = 0x%8.8" PRIx64,
3592 watchID, (uint64_t)addr);
3594 if (!wp_sp->IsEnabled()) {
3596 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3597 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3598 watchID, (uint64_t)addr);
3602 wp_sp->SetEnabled(
false, notify);
3606 if (wp_sp->IsHardware()) {
3607 bool disabled_all =
true;
3609 std::vector<WatchpointResourceSP> unused_resources;
3611 if (wp_res_sp->ConstituentsContains(wp_sp)) {
3613 addr_t addr = wp_res_sp->GetLoadAddress();
3614 size_t size = wp_res_sp->GetByteSize();
3615 if (
m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3617 disabled_all =
false;
3619 wp_res_sp->RemoveConstituent(wp_sp);
3620 if (wp_res_sp->GetNumberOfConstituents() == 0)
3621 unused_resources.push_back(wp_res_sp);
3625 for (
auto &wp_res_sp : unused_resources)
3628 wp_sp->SetEnabled(
false, notify);
3631 "Failure disabling one of the watchpoint locations");
3644 LLDB_LOGF(log,
"ProcessGDBRemote::DoSignal (signal = %d)", signo);
3659 if (platform_sp && !platform_sp->IsHost())
3664 const char *error_string =
error.AsCString();
3665 if (error_string ==
nullptr)
3674 static FileSpec g_debugserver_file_spec;
3681 std::string env_debugserver_path = host_env.lookup(
"LLDB_DEBUGSERVER_PATH");
3682 if (!env_debugserver_path.empty()) {
3683 debugserver_file_spec.
SetFile(env_debugserver_path,
3684 FileSpec::Style::native);
3685 LLDB_LOG(log,
"gdb-remote stub exe path set from environment variable: {0}",
3686 env_debugserver_path);
3688 debugserver_file_spec = g_debugserver_file_spec;
3690 return debugserver_file_spec;
3693 debugserver_file_spec = HostInfo::GetSupportExeDir();
3694 if (debugserver_file_spec) {
3697 LLDB_LOG(log,
"found gdb-remote stub exe '{0}'", debugserver_file_spec);
3699 g_debugserver_file_spec = debugserver_file_spec;
3702 if (!debugserver_file_spec) {
3705 LLDB_LOG(log,
"could not find gdb-remote stub exe '{0}'",
3706 debugserver_file_spec);
3710 g_debugserver_file_spec.
Clear();
3713 return debugserver_file_spec;
3718 using namespace std::placeholders;
3728 const std::weak_ptr<ProcessGDBRemote> this_wp =
3729 std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3736#if defined(__APPLE__)
3740 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
3742 struct kinfo_proc processInfo;
3743 size_t bufsize =
sizeof(processInfo);
3744 if (sysctl(mib, (
unsigned)(
sizeof(mib) /
sizeof(
int)), &processInfo, &bufsize,
3747 if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
3748 debugserver_path =
FileSpec(
"/Library/Apple/usr/libexec/oah/debugserver");
3755 "'. Please ensure it is properly installed "
3756 "and available in your PATH");
3771 debugserver_launch_info,
nullptr);
3776 LLDB_LOGF(log,
"failed to start debugserver process: %s",
3786 m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>(
3787 std::move(socket_pair->second)));
3801 std::weak_ptr<ProcessGDBRemote> process_wp,
lldb::pid_t debugserver_pid,
3810 "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
3811 ", signo=%i (0x%x), exit_status=%i)",
3812 __FUNCTION__, debugserver_pid, signo, signo, exit_status);
3814 std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
3815 LLDB_LOGF(log,
"ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
3816 static_cast<void *
>(process_sp.get()));
3817 if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
3823 std::this_thread::sleep_for(std::chrono::milliseconds(500));
3827 const StateType state = process_sp->GetState();
3836 llvm::StringRef signal_name =
3837 process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);
3839 if (!signal_name.empty())
3840 stream.
Format(format_str, signal_name);
3842 stream.
Format(format_str, signo);
3844 process_sp->SetExitStatus(-1, stream.
GetString());
3867 debugger, PluginProperties::GetSettingName())) {
3868 const bool is_global_setting =
true;
3871 "Properties for the gdb-remote process plug-in.", is_global_setting);
3878 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
3885 llvm::Expected<HostThread> async_thread =
3889 if (!async_thread) {
3891 "failed to launch host thread: {0}");
3897 "ProcessGDBRemote::%s () - Called when Async thread was "
3907 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
3922 "ProcessGDBRemote::%s () - Called when Async thread was not running.",
3928 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread starting...",
3929 __FUNCTION__,
GetID());
3947 "ProcessGDBRemote::%s(pid = %" PRIu64
3948 ") listener.WaitForEvent (NULL, event_sp)...",
3949 __FUNCTION__,
GetID());
3952 const uint32_t event_type = event_sp->GetType();
3955 "ProcessGDBRemote::%s(pid = %" PRIu64
3956 ") Got an event of type: %d...",
3957 __FUNCTION__,
GetID(), event_type);
3959 switch (event_type) {
3964 if (continue_packet) {
3965 const char *continue_cstr =
3966 (
const char *)continue_packet->
GetBytes();
3967 const size_t continue_cstr_len = continue_packet->
GetByteSize();
3969 "ProcessGDBRemote::%s(pid = %" PRIu64
3970 ") got eBroadcastBitAsyncContinue: %s",
3971 __FUNCTION__,
GetID(), continue_cstr);
3973 if (::strstr(continue_cstr,
"vAttach") ==
nullptr)
3980 llvm::StringRef(continue_cstr, continue_cstr_len),
3991 switch (stop_state) {
4004 int exit_status = response.
GetHexU8();
4005 std::string desc_string;
4007 llvm::StringRef desc_str;
4008 llvm::StringRef desc_token;
4010 if (desc_token !=
"description")
4025 if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4028 "System Integrity Protection");
4029 }
else if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4049 "ProcessGDBRemote::%s(pid = %" PRIu64
4050 ") got eBroadcastBitAsyncThreadShouldExit...",
4051 __FUNCTION__,
GetID());
4057 "ProcessGDBRemote::%s(pid = %" PRIu64
4058 ") got unknown event 0x%8.8x",
4059 __FUNCTION__,
GetID(), event_type);
4066 "ProcessGDBRemote::%s(pid = %" PRIu64
4067 ") listener.WaitForEvent (NULL, event_sp) => false",
4068 __FUNCTION__,
GetID());
4073 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread exiting...",
4074 __FUNCTION__,
GetID());
4106 LLDB_LOGF(log,
"Hit New Thread Notification breakpoint.");
4112 LLDB_LOG(log,
"Check if need to update ignored signals");
4126 LLDB_LOG(log,
"Signals' version hasn't changed. version={0}",
4131 auto signals_to_ignore =
4136 "Signals' version changed. old version={0}, new version={1}, "
4137 "signals ignored={2}, update result={3}",
4139 signals_to_ignore.size(),
error);
4141 if (
error.Success())
4156 platform_sp->SetThreadCreationBreakpoint(
GetTarget());
4159 log,
"Successfully created new thread notification breakpoint %i",
4164 LLDB_LOGF(log,
"Failed to create new thread notification breakpoint.");
4193 return_value =
m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
4194 if (return_value != 0) {
4197 "Sending events is not supported for this process.");
4207 if (
m_gdb_comm.GetQXferAuxvReadSupported()) {
4208 llvm::Expected<std::string> response =
m_gdb_comm.ReadExtFeature(
"auxv",
"");
4210 buf = std::make_shared<DataBufferHeap>(response->c_str(),
4211 response->length());
4222 if (
m_gdb_comm.GetThreadExtendedInfoSupported()) {
4228 args_dict->GetAsDictionary()->AddIntegerItem(
"thread", tid);
4231 packet <<
"jThreadExtendedInfo:";
4232 args_dict->Dump(packet,
false);
4239 packet << (char)(0x7d ^ 0x20);
4248 if (!response.
Empty()) {
4261 args_dict->GetAsDictionary()->AddIntegerItem(
"image_list_address",
4262 image_list_address);
4263 args_dict->GetAsDictionary()->AddIntegerItem(
"image_count", image_count);
4270 std::string info_level_str;
4272 info_level_str =
"address-only";
4274 info_level_str =
"address-name";
4276 info_level_str =
"address-name-uuid";
4278 info_level_str =
"full";
4280 return info_level_str;
4287 args_dict->GetAsDictionary()->AddBooleanItem(
"fetch_all_solibs",
true);
4289 args_dict->GetAsDictionary()->AddBooleanItem(
"report_load_commands",
false);
4291 if (!info_level_str.empty())
4292 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4293 info_level_str.c_str());
4300 const std::vector<lldb::addr_t> &load_addresses) {
4304 for (
auto addr : load_addresses)
4305 addresses->AddIntegerItem(addr);
4307 args_dict->GetAsDictionary()->AddItem(
"solib_addresses", addresses);
4310 if (!info_level_str.empty())
4311 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4312 info_level_str.c_str());
4322 if (
m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
4325 std::chrono::seconds(10));
4328 packet <<
"jGetLoadedDynamicLibrariesInfos:";
4329 args_dict->Dump(packet,
false);
4336 packet << (char)(0x7d ^ 0x20);
4345 if (!response.
Empty()) {
4358 if (
m_gdb_comm.GetDynamicLoaderProcessStateSupported()) {
4361 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"jGetDyldProcessState",
4367 if (!response.
Empty()) {
4384 packet <<
"jGetSharedCacheInfo:";
4385 args_dict->Dump(packet,
false);
4394 if (response.
Empty())
4403 if (!dict->
HasKey(
"shared_cache_uuid"))
4405 llvm::StringRef uuid_str;
4407 uuid_str ==
"00000000-0000-0000-0000-000000000000")
4409 if (dict->
HasKey(
"shared_cache_path")) {
4423 HostInfo::SharedCacheIndexFiles(sc_path, uuid, sc_mode);
4434 return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
4447 const uint64_t reasonable_largeish_default = 128 * 1024;
4448 const uint64_t conservative_default = 512;
4451 uint64_t stub_max_size =
m_gdb_comm.GetRemoteMaxPacketSize();
4452 if (stub_max_size !=
UINT64_MAX && stub_max_size != 0) {
4458 if (stub_max_size > reasonable_largeish_default) {
4459 stub_max_size = reasonable_largeish_default;
4465 if (stub_max_size > 70)
4466 stub_max_size -= 32 + 32 + 6;
4471 LLDB_LOG(log,
"warning: Packet size is too small. "
4472 "LLDB may face problems while writing memory");
4483 uint64_t user_specified_max) {
4484 if (user_specified_max != 0) {
4512 module_spec = cached->second;
4513 return bool(module_spec);
4516 if (!
m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
4517 LLDB_LOGF(log,
"ProcessGDBRemote::%s - failed to get module info for %s:%s",
4518 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4525 module_spec.
Dump(stream);
4526 LLDB_LOGF(log,
"ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
4527 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4536 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4537 auto module_specs =
m_gdb_comm.GetModulesInfo(module_file_specs, triple);
4539 for (
const FileSpec &spec : module_file_specs)
4544 triple.getTriple())] = spec;
4558typedef std::vector<std::string> stringVec;
4560typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
4561struct RegisterSetInfo {
4565typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
4567struct GdbServerTargetInfo {
4571 RegisterSetMap reg_set_map;
4588 std::map<uint64_t, FieldEnum::Enumerator> enumerators;
4591 "evalue", [&enumerators, &log](
const XMLNode &enumerator_node) {
4592 std::optional<llvm::StringRef> name;
4593 std::optional<uint64_t> value;
4596 [&name, &value, &log](
const llvm::StringRef &attr_name,
4597 const llvm::StringRef &attr_value) {
4598 if (attr_name ==
"name") {
4599 if (attr_value.size())
4602 LLDB_LOG(log,
"ProcessGDBRemote::ParseEnumEvalues "
4603 "Ignoring empty name in evalue");
4604 }
else if (attr_name ==
"value") {
4605 uint64_t parsed_value = 0;
4606 if (llvm::to_integer(attr_value, parsed_value))
4607 value = parsed_value;
4610 "ProcessGDBRemote::ParseEnumEvalues "
4611 "Invalid value \"{0}\" in "
4616 "ProcessGDBRemote::ParseEnumEvalues Ignoring "
4617 "unknown attribute "
4618 "\"{0}\" in evalue",
4626 enumerators.insert_or_assign(
4627 *value, FieldEnum::Enumerator(*value, name->str()));
4634 for (
auto [_, enumerator] : enumerators)
4635 final_enumerators.push_back(enumerator);
4637 return final_enumerators;
4641ParseEnums(XMLNode feature_node,
4642 llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4643 Log *log(
GetLog(GDBRLog::Process));
4647 "enum", [log, ®isters_enum_types](
const XMLNode &enum_node) {
4651 const llvm::StringRef &attr_value) {
4652 if (attr_name ==
"id")
4670 if (!enumerators.empty()) {
4672 "ProcessGDBRemote::ParseEnums Found enum type \"{0}\"",
4674 registers_enum_types.insert_or_assign(
4675 id, std::make_unique<FieldEnum>(
id, enumerators));
4684static std::vector<RegisterFlags::Field> ParseFlagsFields(
4685 XMLNode flags_node,
unsigned size,
4686 const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4687 Log *log(
GetLog(GDBRLog::Process));
4688 const unsigned max_start_bit = size * 8 - 1;
4691 std::vector<RegisterFlags::Field> fields;
4693 ®isters_enum_types](
4696 std::optional<llvm::StringRef> name;
4697 std::optional<unsigned> start;
4698 std::optional<unsigned> end;
4699 std::optional<llvm::StringRef> type;
4702 &log](
const llvm::StringRef &attr_name,
4703 const llvm::StringRef &attr_value) {
4706 if (attr_name ==
"name") {
4709 "ProcessGDBRemote::ParseFlagsFields Found field node name \"{0}\"",
4712 }
else if (attr_name ==
"start") {
4713 unsigned parsed_start = 0;
4714 if (llvm::to_integer(attr_value, parsed_start)) {
4715 if (parsed_start > max_start_bit) {
4717 "ProcessGDBRemote::ParseFlagsFields Invalid start {0} in "
4720 parsed_start, max_start_bit);
4722 start = parsed_start;
4726 "ProcessGDBRemote::ParseFlagsFields Invalid start \"{0}\" in "
4730 }
else if (attr_name ==
"end") {
4731 unsigned parsed_end = 0;
4732 if (llvm::to_integer(attr_value, parsed_end))
4733 if (parsed_end > max_start_bit) {
4735 "ProcessGDBRemote::ParseFlagsFields Invalid end {0} in "
4738 parsed_end, max_start_bit);
4743 "ProcessGDBRemote::ParseFlagsFields Invalid end \"{0}\" in "
4747 }
else if (attr_name ==
"type") {
4752 "ProcessGDBRemote::ParseFlagsFields Ignoring unknown attribute "
4753 "\"{0}\" in field node",
4760 if (name && start && end) {
4764 "ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
4765 "\"{2}\", ignoring",
4766 *start, *end, name->data());
4770 "ProcessGDBRemote::ParseFlagsFields Ignoring field \"{}\" "
4771 "that has size > 64 bits, this is not supported",
4775 const FieldEnum *enum_type =
nullptr;
4776 if (type && !type->empty()) {
4777 auto found = registers_enum_types.find(*type);
4778 if (found != registers_enum_types.end()) {
4779 enum_type = found->second.get();
4782 uint64_t max_value =
4785 if (enumerator.m_value > max_value) {
4786 enum_type =
nullptr;
4789 "ProcessGDBRemote::ParseFlagsFields In enum \"{0}\" "
4790 "evalue \"{1}\" with value {2} exceeds the maximum value "
4791 "of field \"{3}\" ({4}), ignoring enum",
4792 type->data(), enumerator.m_name, enumerator.m_value,
4793 name->data(), max_value);
4799 "ProcessGDBRemote::ParseFlagsFields Could not find type "
4801 "for field \"{1}\", ignoring",
4802 type->data(), name->data());
4807 RegisterFlags::Field(name->str(), *start, *end, enum_type));
4818 XMLNode feature_node,
4819 llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4820 const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4821 Log *log(
GetLog(GDBRLog::Process));
4825 [&log, ®isters_flags_types,
4826 ®isters_enum_types](
const XMLNode &flags_node) ->
bool {
4827 LLDB_LOG(log,
"ProcessGDBRemote::ParseFlags Found flags node \"{0}\"",
4830 std::optional<llvm::StringRef>
id;
4831 std::optional<unsigned> size;
4833 [&
id, &size, &log](
const llvm::StringRef &name,
4834 const llvm::StringRef &value) {
4837 }
else if (name ==
"size") {
4838 unsigned parsed_size = 0;
4839 if (llvm::to_integer(value, parsed_size))
4843 "ProcessGDBRemote::ParseFlags Invalid size \"{0}\" "
4849 "ProcessGDBRemote::ParseFlags Ignoring unknown "
4850 "attribute \"{0}\" in flags node",
4858 std::vector<RegisterFlags::Field> fields =
4859 ParseFlagsFields(flags_node, *size, registers_enum_types);
4860 if (fields.size()) {
4862 std::sort(fields.rbegin(), fields.rend());
4863 std::vector<RegisterFlags::Field>::const_iterator overlap =
4864 std::adjacent_find(fields.begin(), fields.end(),
4865 [](
const RegisterFlags::Field &lhs,
4866 const RegisterFlags::Field &rhs) {
4867 return lhs.Overlaps(rhs);
4871 if (overlap == fields.end()) {
4872 if (registers_flags_types.contains(*
id)) {
4886 "ProcessGDBRemote::ParseFlags Definition of flags "
4888 "previous definition, using original definition instead.",
4891 registers_flags_types.insert_or_assign(
4892 *
id, std::make_unique<RegisterFlags>(
id->str(), *size,
4893 std::move(fields)));
4897 std::vector<RegisterFlags::Field>::const_iterator next =
4901 "ProcessGDBRemote::ParseFlags Ignoring flags because fields "
4902 "{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) "
4904 overlap->GetName().c_str(), overlap->GetStart(),
4905 overlap->GetEnd(), next->GetName().c_str(), next->GetStart(),
4911 "ProcessGDBRemote::ParseFlags Ignoring definition of flags "
4912 "\"{0}\" because it contains no fields.",
4922 XMLNode feature_node, GdbServerTargetInfo &target_info,
4923 std::vector<DynamicRegisterInfo::Register> ®isters,
4924 llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4925 llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4929 Log *log(
GetLog(GDBRLog::Process));
4932 ParseEnums(feature_node, registers_enum_types);
4933 for (
const auto &enum_type : registers_enum_types)
4936 ParseFlags(feature_node, registers_flags_types, registers_enum_types);
4937 for (
const auto &flags : registers_flags_types)
4938 flags.second->DumpToLog(log);
4942 [&target_info, ®isters, ®isters_flags_types,
4943 log](
const XMLNode ®_node) ->
bool {
4944 std::string gdb_group;
4945 std::string gdb_type;
4946 DynamicRegisterInfo::Register reg_info;
4947 bool encoding_set =
false;
4948 bool format_set =
false;
4952 &encoding_set, &format_set, ®_info,
4953 log](
const llvm::StringRef &name,
4954 const llvm::StringRef &value) ->
bool {
4955 if (name ==
"name") {
4957 }
else if (name ==
"bitsize") {
4958 if (llvm::to_integer(value, reg_info.
byte_size))
4960 llvm::divideCeil(reg_info.
byte_size, CHAR_BIT);
4961 }
else if (name ==
"type") {
4962 gdb_type = value.str();
4963 }
else if (name ==
"group") {
4964 gdb_group = value.str();
4965 }
else if (name ==
"regnum") {
4967 }
else if (name ==
"offset") {
4969 }
else if (name ==
"altname") {
4971 }
else if (name ==
"encoding") {
4972 encoding_set =
true;
4974 }
else if (name ==
"format") {
4980 llvm::StringSwitch<lldb::Format>(value)
4991 }
else if (name ==
"group_id") {
4993 llvm::to_integer(value, set_id);
4994 RegisterSetMap::const_iterator pos =
4995 target_info.reg_set_map.find(set_id);
4996 if (pos != target_info.reg_set_map.end())
4997 reg_info.
set_name = pos->second.name;
4998 }
else if (name ==
"gcc_regnum" || name ==
"ehframe_regnum") {
5000 }
else if (name ==
"dwarf_regnum") {
5002 }
else if (name ==
"generic") {
5004 }
else if (name ==
"value_regnums") {
5007 }
else if (name ==
"invalidate_regnums") {
5012 "ProcessGDBRemote::ParseRegisters unhandled reg "
5013 "attribute %s = %s",
5014 name.data(), value.data());
5019 if (!gdb_type.empty()) {
5021 llvm::StringMap<std::unique_ptr<RegisterFlags>>::iterator it =
5022 registers_flags_types.find(gdb_type);
5023 if (it != registers_flags_types.end()) {
5024 auto flags_type = it->second.get();
5025 if (reg_info.
byte_size == flags_type->GetSize())
5030 "ProcessGDBRemote::ParseRegisters Size of register flags {0} "
5031 "({1} bytes) for register {2} does not match the register "
5032 "size ({3} bytes). Ignoring this set of flags.",
5033 flags_type->GetID().c_str(), flags_type->GetSize(),
5040 if (!gdb_type.empty() && !(encoding_set || format_set)) {
5041 if (llvm::StringRef(gdb_type).starts_with(
"int")) {
5044 }
else if (gdb_type ==
"data_ptr" || gdb_type ==
"code_ptr") {
5047 }
else if (gdb_type ==
"float" || gdb_type ==
"ieee_single" ||
5048 gdb_type ==
"ieee_double") {
5051 }
else if (gdb_type ==
"aarch64v" ||
5052 llvm::StringRef(gdb_type).starts_with(
"vec") ||
5053 gdb_type ==
"i387_ext" || gdb_type ==
"uint128" ||
5066 "ProcessGDBRemote::ParseRegisters Could not determine lldb"
5067 "format and encoding for gdb type %s",
5077 if (!gdb_group.empty()) {
5088 "ProcessGDBRemote::{0} Skipping zero bitsize register {1}",
5089 __FUNCTION__, reg_info.
name);
5091 registers.push_back(reg_info);
5106 ArchSpec &arch_to_use, std::string xml_filename,
5107 std::vector<DynamicRegisterInfo::Register> ®isters) {
5109 llvm::Expected<std::string> raw =
m_gdb_comm.ReadExtFeature(
"features", xml_filename);
5110 if (errorToBool(raw.takeError()))
5115 if (xml_document.
ParseMemory(raw->c_str(), raw->size(),
5116 xml_filename.c_str())) {
5117 GdbServerTargetInfo target_info;
5118 std::vector<XMLNode> feature_nodes;
5124 const XMLNode &node) ->
bool {
5125 llvm::StringRef name = node.
GetName();
5126 if (name ==
"architecture") {
5128 }
else if (name ==
"osabi") {
5130 }
else if (name ==
"xi:include" || name ==
"include") {
5133 target_info.includes.push_back(href);
5134 }
else if (name ==
"feature") {
5135 feature_nodes.push_back(node);
5136 }
else if (name ==
"groups") {
5138 "group", [&target_info](
const XMLNode &node) ->
bool {
5140 RegisterSetInfo set_info;
5143 [&set_id, &set_info](
const llvm::StringRef &name,
5144 const llvm::StringRef &value) ->
bool {
5147 llvm::to_integer(value, set_id);
5154 target_info.reg_set_map[set_id] = set_info;
5167 feature_nodes.push_back(feature_node);
5169 const XMLNode &node) ->
bool {
5170 llvm::StringRef name = node.
GetName();
5171 if (name ==
"xi:include" || name ==
"include") {
5174 target_info.includes.push_back(href);
5188 if (!arch_to_use.
IsValid() && !target_info.arch.empty()) {
5190 arch_to_use.
SetTriple(llvm::StringSwitch<std::string>(target_info.arch)
5191 .Case(
"i386:x86-64",
"x86_64")
5192 .Case(
"riscv:rv64",
"riscv64")
5193 .Case(
"riscv:rv32",
"riscv32")
5194 .Default(target_info.arch) +
5202 for (
auto &feature_node : feature_nodes) {
5203 ParseRegisters(feature_node, target_info, registers,
5207 for (
const auto &include : target_info.includes) {
5219 std::vector<DynamicRegisterInfo::Register> ®isters,
5221 std::map<uint32_t, uint32_t> remote_to_local_map;
5222 uint32_t remote_regnum = 0;
5223 for (
auto it : llvm::enumerate(registers)) {
5231 remote_to_local_map[remote_reg_info.
regnum_remote] = it.index();
5237 auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) {
5238 auto lldb_regit = remote_to_local_map.find(process_regnum);
5239 return lldb_regit != remote_to_local_map.end() ? lldb_regit->second
5243 llvm::transform(remote_reg_info.value_regs,
5244 remote_reg_info.value_regs.begin(), proc_to_lldb);
5245 llvm::transform(remote_reg_info.invalidate_regs,
5246 remote_reg_info.invalidate_regs.begin(), proc_to_lldb);
5253 abi_sp->AugmentRegisterInfo(registers);
5263 if (!
m_gdb_comm.GetQXferFeaturesReadSupported())
5264 return llvm::createStringError(
5265 llvm::inconvertibleErrorCode(),
5266 "the debug server does not support \"qXfer:features:read\"");
5269 return llvm::createStringError(
5270 llvm::inconvertibleErrorCode(),
5271 "the debug server supports \"qXfer:features:read\", but LLDB does not "
5272 "have XML parsing enabled (check LLLDB_ENABLE_LIBXML2)");
5282 std::vector<DynamicRegisterInfo::Register> registers;
5290 ? llvm::ErrorSuccess()
5291 : llvm::createStringError(
5292 llvm::inconvertibleErrorCode(),
5293 "the debug server did not describe any registers");
5299 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5300 "XML parsing not available");
5303 LLDB_LOGF(log,
"ProcessGDBRemote::%s", __FUNCTION__);
5312 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries-svr4",
"");
5314 return raw.takeError();
5317 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5320 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5321 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5322 "Error reading noname.xml");
5326 return llvm::createStringError(
5327 llvm::inconvertibleErrorCode(),
5328 "Error finding library-list-svr4 xml element");
5333 if (!main_lm.empty())
5337 "library", [log, &list](
const XMLNode &library) ->
bool {
5342 [&module](
const llvm::StringRef &name,
5343 const llvm::StringRef &value) ->
bool {
5346 module.set_name(value.str());
5347 else if (name ==
"lm") {
5349 llvm::to_integer(value, uint_value);
5350 module.set_link_map(uint_value);
5351 }
else if (name ==
"l_addr") {
5354 llvm::to_integer(value, uint_value);
5355 module.set_base(uint_value);
5358 module.set_base_is_offset(true);
5359 }
else if (name ==
"l_ld") {
5361 llvm::to_integer(value, uint_value);
5362 module.set_dynamic(uint_value);
5371 bool base_is_offset;
5373 module.get_name(name);
5374 module.get_link_map(lm);
5375 module.get_base(base);
5376 module.get_base_is_offset(base_is_offset);
5377 module.get_dynamic(ld);
5380 "found (link_map:0x%08" PRIx64
", base:0x%08" PRIx64
5381 "[%s], ld:0x%08" PRIx64
", name:'%s')",
5382 lm, base, (base_is_offset ?
"offset" :
"absolute"), ld,
5391 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5392 (
int)list.
m_list.size());
5396 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries",
"");
5399 return raw.takeError();
5401 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5404 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5405 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5406 "Error reading noname.xml");
5410 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5411 "Error finding library-list xml element");
5415 "library", [log, &list](
const XMLNode &library) ->
bool {
5419 module.set_name(name);
5428 llvm::to_integer(address, address_value);
5429 module.set_base(address_value);
5431 module.set_base_is_offset(false);
5436 bool base_is_offset;
5437 module.get_name(name);
5438 module.get_base(base);
5439 module.get_base_is_offset(base_is_offset);
5441 LLDB_LOGF(log,
"found (base:0x%08" PRIx64
"[%s], name:'%s')", base,
5442 (base_is_offset ?
"offset" :
"absolute"), name.c_str());
5450 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5451 (
int)list.
m_list.size());
5454 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5455 "Remote libraries not supported");
5462 bool value_is_offset) {
5477 return module_list.takeError();
5483 std::string mod_name;
5486 bool mod_base_is_offset;
5489 valid &= modInfo.
get_name(mod_name);
5490 valid &= modInfo.
get_base(mod_base);
5503 if (module_sp.get())
5504 new_modules.
Append(module_sp);
5507 if (new_modules.
GetSize() > 0) {
5512 for (
size_t i = 0; i < loaded_modules.
GetSize(); ++i) {
5516 for (
size_t j = 0; j < new_modules.
GetSize(); ++j) {
5525 removed_modules.
Append(loaded_module);
5529 loaded_modules.
Remove(removed_modules);
5530 m_process->GetTarget().ModulesDidUnload(removed_modules,
false);
5546 m_process->GetTarget().ModulesDidLoad(new_modules);
5549 return llvm::ErrorSuccess();
5558 std::string file_path = file.
GetPath(
false);
5559 if (file_path.empty())
5580 "Fetching file load address from remote server returned an error");
5590 "Unknown error happened during sending the load address packet");
5611 std::string input = data.str();
5618 size_t found, pos = 0, len = input.length();
5619 while ((found = input.find(
end_delimiter, pos)) != std::string::npos) {
5621 input.substr(pos, found).c_str());
5622 std::string profile_data =
5637 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
5639 llvm::raw_string_ostream output_stream(output);
5640 llvm::StringRef name, value;
5644 if (name.compare(
"thread_used_id") == 0) {
5646 uint64_t thread_id = threadIDHexExtractor.
GetHexMaxU64(
false, 0);
5648 bool has_used_usec =
false;
5649 uint32_t curr_used_usec = 0;
5650 llvm::StringRef usec_name, usec_value;
5651 uint32_t input_file_pos = profileDataExtractor.
GetFilePos();
5653 if (usec_name ==
"thread_used_usec") {
5654 has_used_usec =
true;
5655 usec_value.getAsInteger(0, curr_used_usec);
5659 profileDataExtractor.
SetFilePos(input_file_pos);
5663 if (has_used_usec) {
5664 uint32_t prev_used_usec = 0;
5665 std::map<uint64_t, uint32_t>::iterator iterator =
5668 prev_used_usec = iterator->second;
5670 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
5672 bool good_first_time =
5673 (prev_used_usec == 0) && (real_used_usec > 250000);
5674 bool good_subsequent_time =
5675 (prev_used_usec > 0) &&
5678 if (good_first_time || good_subsequent_time) {
5682 output_stream << name <<
":";
5684 output_stream << index_id <<
";";
5686 output_stream << usec_name <<
":" << usec_value <<
";";
5689 llvm::StringRef local_name, local_value;
5695 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
5698 output_stream << name <<
":" << value <<
";";
5701 output_stream << name <<
":" << value <<
";";
5736 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5737 "qSaveCore returned an error");
5742 for (
auto x : llvm::split(response.
GetStringRef(),
';')) {
5743 if (x.consume_front(
"core-path:"))
5749 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5750 "qSaveCore returned no core path");
5753 FileSpec remote_core{llvm::StringRef(path)};
5759 platform.
Unlink(remote_core);
5761 return error.ToError();
5767 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5768 "Unable to send qSaveCore");
5780 "GDBRemoteCommunicationClientBase::%s() received $J packet "
5781 "but was not a StructuredData packet: packet starts with "
5793 json_sp->Dump(json_str,
true);
5796 "ProcessGDBRemote::%s() "
5797 "received Async StructuredData packet: %s",
5798 __FUNCTION__, json_str.
GetData());
5801 "ProcessGDBRemote::%s"
5802 "() received StructuredData packet:"
5812 if (structured_data_sp)
5820 "Tests packet speeds of various sizes to determine "
5821 "the performance characteristics of the GDB remote "
5826 "The number of packets to send of each varying size "
5827 "(default is 1000).",
5830 "The maximum number of bytes to send in a packet. Sizes "
5831 "increase in powers of 2 while the size is less than or "
5832 "equal to this option value. (default 1024).",
5835 "The maximum number of bytes to receive in a packet. Sizes "
5836 "increase in powers of 2 while the size is less than or "
5837 "equal to this option value. (default 1024).",
5840 "Print the output as JSON data for easy parsing.", false, true) {
5860 if (!output_stream_sp)
5861 output_stream_sp =
m_interpreter.GetDebugger().GetAsyncOutputStream();
5864 const uint32_t num_packets =
5866 const uint64_t max_send =
m_max_send.GetOptionValue().GetCurrentValue();
5867 const uint64_t max_recv =
m_max_recv.GetOptionValue().GetCurrentValue();
5868 const bool json =
m_json.GetOptionValue().GetCurrentValue();
5869 const uint64_t k_recv_amount =
5872 num_packets, max_send, max_recv, k_recv_amount, json,
5897 "Dumps the packet history buffer. ", nullptr) {}
5918 interpreter,
"process plugin packet xfer-size",
5919 "Maximum size that lldb will try to read/write one one chunk.",
5930 "amount to be transferred when "
5941 uint64_t user_specified_max = strtoul(packet_size,
nullptr, 10);
5942 if (errno == 0 && user_specified_max != 0) {
5957 "Send a custom packet through the GDB remote "
5958 "protocol and print the answer. "
5959 "The packet header and footer will automatically "
5960 "be added to the packet prior to sending and "
5961 "stripped from the result.",
5972 "'%s' takes a one or more packet content arguments",
5980 for (
size_t i = 0; i < argc; ++i) {
5987 output_strm.
Printf(
" packet: %s\n", packet_cstr);
5988 std::string response_str = std::string(response.
GetStringRef());
5990 if (strstr(packet_cstr,
"qGetProfileData") !=
nullptr) {
5994 if (response_str.empty())
5995 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6008 "Send a qRcmd packet through the GDB remote protocol "
6009 "and print the response. "
6010 "The argument passed to this command will be hex "
6011 "encoded into a valid 'qRcmd' packet, sent and the "
6012 "response will be printed.") {}
6018 if (command.empty()) {
6035 [&output_strm](llvm::StringRef output) { output_strm << output; });
6038 const std::string &response_str = std::string(response.
GetStringRef());
6040 if (response_str.empty())
6041 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6053 "Commands that deal with GDB remote packets.",
6082 interpreter,
"process plugin",
6083 "Commands for operating on a ProcessGDBRemote process.",
6084 "process plugin <subcommand> [<subcommand-options>]") {
6095 m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(
6096 GetTarget().GetDebugger().GetCommandInterpreter());
6101 bool enable,
bool is_expression_fork) {
6107 if (!enable && is_expression_fork) {
6108 if (
auto entry =
GetTarget().GetEntryPointAddress())
6109 entry_addr = entry->GetOpcodeLoadAddress(&
GetTarget());
6123 "DidForkSwitchSoftwareBreakpoints: retaining expression-"
6124 "return trap at {0:x} in forked child",
6148 addr_t addr = wp_res_sp->GetLoadAddress();
6149 size_t size = wp_res_sp->GetByteSize();
6151 m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,
6157 bool is_expression_fork) {
6166 bool overrode_follow_mode =
false;
6169 if (is_expression_fork) {
6170 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6171 "to parent during expression evaluation");
6173 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6174 "to parent during expression evaluation. Child process "
6175 "{0} is available for manual attachment.",
6179 overrode_follow_mode =
true;
6190 switch (follow_fork_mode) {
6192 follow_pid = parent_pid;
6193 follow_tid = parent_tid;
6194 detach_pid = child_pid;
6195 detach_tid = child_tid;
6198 follow_pid = child_pid;
6199 follow_tid = child_tid;
6200 detach_pid = parent_pid;
6201 detach_tid = parent_tid;
6206 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6207 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to set pid/tid");
6221 if (!
m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) ||
6222 !
m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) {
6223 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to reset pid/tid");
6227 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6230 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6232 if (
error.Fail() && keep_stopped) {
6233 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach-and-stay-stopped not "
6234 "supported, falling back to normal detach");
6235 keep_stopped =
false;
6239 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach packet send failed: {0}",
6240 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6246 if (overrode_follow_mode && !is_expression_fork) {
6250 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
6251 "'parent' because an expression is being evaluated.\n"
6252 "Child process %" PRIu64
6253 " has been detached%s.\n"
6254 "You can attach to it with: process attach -p %" PRIu64
6257 keep_stopped ?
" and stopped" :
" (running)",
6273 bool is_expression_fork) {
6278 "ProcessGDBRemote::DidVFork() called for child_pid: {0}, child_tid {1}",
6279 child_pid, child_tid);
6285 bool overrode_follow_mode =
false;
6288 if (is_expression_fork) {
6289 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6290 "to parent during expression evaluation");
6292 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6293 "to parent during expression evaluation. Child process "
6294 "{0} is available for manual attachment.",
6298 overrode_follow_mode =
true;
6308 switch (follow_fork_mode) {
6310 detach_pid = child_pid;
6311 detach_tid = child_tid;
6314 detach_pid =
m_gdb_comm.GetCurrentProcessID();
6320 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6321 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to set pid/tid");
6329 if (!
m_gdb_comm.SetCurrentThread(child_tid, child_pid) ||
6330 !
m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) {
6331 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to reset pid/tid");
6337 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6338 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6340 if (
error.Fail() && keep_stopped) {
6341 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() detach-and-stay-stopped not "
6342 "supported, falling back to normal detach");
6343 keep_stopped =
false;
6348 "ProcessGDBRemote::DidVFork() detach packet send failed: {0}",
6349 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6353 if (overrode_follow_mode && !is_expression_fork) {
6357 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
6358 "'parent' because an expression is being evaluated.\n"
6359 "Child process %" PRIu64
6360 " has been detached%s.\n"
6361 "You can attach to it with: process attach -p %" PRIu64
6364 keep_stopped ?
" and stopped" :
" (running)",
6397 llvm::Error joined = llvm::Error::success();
6398 for (
auto &[site, action] : site_to_action) {
6402 joined = llvm::joinErrors(std::move(joined), std::move(
error));
6410static llvm::SmallVector<std::optional<uint8_t>>
6412 llvm::SmallVector<std::optional<uint8_t>> results;
6416 parsed ? parsed->GetAsDictionary() :
nullptr;
6424 llvm::StringRef token;
6425 if (
auto *
string = object->GetAsString())
6426 token =
string->GetValue();
6427 if (token ==
"OK") {
6428 results.push_back(std::nullopt);
6431 if (token.size() != 3 || !token.starts_with(
"E")) {
6432 results.push_back(uint8_t(0xff));
6435 uint8_t error_code = 0;
6436 if (token.drop_front(1).getAsInteger(16, error_code))
6437 results.push_back(0xff);
6439 results.push_back(error_code);
6448static std::optional<GDBStoppointType>
6457 return std::nullopt;
6466 return std::nullopt;
6468 llvm_unreachable(
"unhandled BreakpointSite type");
6472struct BreakpointPacketInfo {
6473 BreakpointSite &site;
6474 size_t trap_opcode_size;
6479std::string to_string(
const BreakpointPacketInfo &info) {
6480 char packet = info.is_enable ?
'Z' :
'z';
6481 return llvm::formatv(
"{0}{1},{2:x-},{3:x-}", packet,
6483 info.trap_opcode_size)
6490 if (site_to_action.empty())
6491 return llvm::Error::success();
6492 if (!
m_gdb_comm.GetMultiBreakpointSupported())
6497 std::vector<BreakpointPacketInfo> breakpoint_infos;
6498 for (
auto [site, action] : site_to_action) {
6500 std::optional<GDBStoppointType> type =
6504 LLDB_LOG(log,
"MultiBreakpoint: site {0} at {1:x} can't be batched",
6505 site->GetID(), site->GetLoadAddress());
6509 breakpoint_infos.push_back(
6514 stream <<
"jMultiBreakpoint:";
6516 auto args_array = std::make_shared<StructuredData::Array>();
6517 for (
auto &bp_info : breakpoint_infos)
6518 args_array->AddStringItem(to_string(bp_info));
6521 packet_dict.
AddItem(
"breakpoint_requests", args_array);
6522 packet_dict.
Dump(stream,
false);
6526 llvm::Expected<StringExtractorGDBRemote> response =
6531 LLDB_LOG_ERROR(log, response.takeError(),
"jMultiBreakpoint failed: {0}");
6535 llvm::SmallVector<std::optional<uint8_t>> results =
6539 if (results.size() != breakpoint_infos.size())
6540 return llvm::createStringErrorV(
6541 "MultiBreakpoint response count mismatch (expected {0}, got {1})",
6542 site_to_action.size(), results.size());
6544 llvm::Error joined = llvm::Error::success();
6545 for (
auto [error_code, bp_info] :
6546 llvm::zip_equal(results, breakpoint_infos)) {
6549 auto error = llvm::createStringErrorV(
6550 "MultiBreakpoint: site {0} at {1:x} failed with E{2}",
6551 bp_info.site.GetID(), bp_info.site.GetLoadAddress(), error_code);
6552 joined = llvm::joinErrors(std::move(joined), std::move(
error));
6556 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)
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.
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
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={})
static lldb::ModuleSP LoadBinaryWithUUIDAndAddress(Process *process, llvm::StringRef name, UUID uuid, lldb::addr_t value, bool value_is_offset, bool force_symbol_search, bool notify, bool set_address_in_target, bool allow_memory_image_last_resort)
Find/load a binary into lldb given a UUID and the address where it is loaded in memory,...
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
std::vector< Enumerator > Enumerators
const Enumerators & GetEnumerators() const
void DumpToLog(Log *log) const
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 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(const char *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.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
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)
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.
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)
virtual void ModulesDidLoad(ModuleList &module_list)
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)
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
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.
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).
MemoryCache m_memory_cache
uint32_t GetAddressByteSize() const
uint32_t GetStopID() const
void SetPrivateState(lldb::StateType state)
lldb::StateType GetPublicState() const
void SetSTDIOFileDescriptor(int file_descriptor)
Associates a file descriptor with the process' STDIO handling and configures an asynchronous reading ...
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
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.
virtual llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > ReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buffer)
Read from multiple memory ranges and write the results into buffer.
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.
uint64_t GetMaxValue() const
The maximum unsigned value that could be contained in this field.
unsigned GetSizeInBits() const
Get size of the field in bits. Will always be at least 1.
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 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...
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
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...
Module * GetExecutableModulePointer()
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()
const ArchSpec & GetArchitecture() const
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
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
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
friend class ThreadGDBRemote
DataExtractor GetAuxvData() override
GDBRemoteCommunicationClient & GetGDBRemote()
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...
Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info)
StructuredData::ObjectSP m_jstopinfo_sp
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...
StructuredData::ObjectSP m_shared_cache_info_sp
StructuredData::ObjectSP m_jthreadsinfo_sp
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
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.
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 m_waiting_for_attach
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
llvm::StringMap< std::unique_ptr< FieldEnum > > m_registers_enum_types
Status EstablishConnectionIfNeeded(const ProcessInfo &process_info)
llvm::Error UpdateBreakpointSites(const BreakpointSiteToActionMap &site_to_action) override
llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > ReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buf) override
Override of ReadMemoryRanges that uses MultiMemRead to optimize this operation.
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.
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)
void WillPublicStop() override
Called when the process is about to broadcast a public stop.
Status SendEventData(const char *data) override
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.
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.
GDBRemoteDynamicRegisterInfoSP m_register_info_sp
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
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
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a process.
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)
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)
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.
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.
std::mutex m_shared_cache_info_mutex
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
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.
llvm::StringMap< std::unique_ptr< RegisterFlags > > m_registers_flags_types
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
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)
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_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 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.
@ eSymbolSharedCacheUseInferiorSharedCacheOnly
@ eSymbolSharedCacheUseHostAndInferiorSharedCache
std::shared_ptr< lldb_private::Stream > StreamSP
std::shared_ptr< lldb_private::Process > ProcessSP
Encoding
Register encoding definitions.
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned 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.
const RegisterFlags * flags_type
std::vector< uint32_t > value_regs
std::vector< uint32_t > invalidate_regs
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