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);
181 uint64_t GetPacketTestDelay()
const {
182 const uint32_t idx = ePropertyPacketTestDelay;
183 return GetPropertyAtIndexAs<uint64_t>(
184 idx, g_processgdbremote_properties[idx].default_uint_value);
188std::chrono::seconds ResumeTimeout() {
return std::chrono::seconds(5); }
193 static PluginProperties g_settings;
201#if defined(__APPLE__)
202#define LOW_PORT (IPPORT_RESERVED)
203#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
205#define LOW_PORT (1024u)
206#define HIGH_PORT (49151u)
210 return "GDB Remote protocol based debugging plug-in.";
219 const FileSpec *crash_file_path,
bool can_connect) {
235 return std::chrono::milliseconds(
244 bool plugin_specified_by_name) {
245 if (plugin_specified_by_name)
249 Module *exe_module = target_sp->GetExecutableModulePointer();
253 switch (exe_objfile->
GetType()) {
277 :
Process(target_sp, listener_sp),
281 Listener::MakeListener(
"lldb.process.gdb-remote.async-listener")),
292 "async thread should exit");
294 "async thread continue");
296 "async thread did exit");
300 const uint32_t async_event_mask =
306 "ProcessGDBRemote::%s failed to listen for "
307 "m_async_broadcaster events",
311 const uint64_t timeout_seconds =
313 if (timeout_seconds > 0)
314 m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
338std::shared_ptr<ThreadGDBRemote>
340 return std::make_shared<ThreadGDBRemote>(*
this, tid);
344 const FileSpec &target_definition_fspec) {
350 if (module_object_sp) {
353 "gdb-server-target-definition",
error));
355 if (target_definition_sp) {
357 target_definition_sp->GetValueForKey(
"host-info"));
359 if (
auto host_info_dict = target_object->GetAsDictionary()) {
361 host_info_dict->GetValueForKey(
"triple");
362 if (
auto triple_string_value = triple_value->GetAsString()) {
363 std::string triple_string =
364 std::string(triple_string_value->GetValue());
365 ArchSpec host_arch(triple_string.c_str());
374 target_definition_sp->GetValueForKey(
"breakpoint-pc-offset");
375 if (breakpoint_pc_offset_value) {
376 if (
auto breakpoint_pc_int_value =
377 breakpoint_pc_offset_value->GetAsSignedInteger())
382 *target_definition_sp,
GetTarget().GetArchitecture()) > 0) {
391 const llvm::StringRef &comma_separated_register_numbers,
392 std::vector<uint32_t> ®nums,
int base) {
394 for (llvm::StringRef x : llvm::split(comma_separated_register_numbers,
',')) {
396 if (llvm::to_integer(x, reg, base))
397 regnums.push_back(reg);
399 return regnums.size();
411 const auto host_packet_timeout =
m_gdb_comm.GetHostDefaultPacketTimeout();
412 if (host_packet_timeout > std::chrono::seconds(0)) {
430 if (target_definition_fspec) {
436 target_definition_fspec.
GetPath() +
447 if (remote_process_arch.
IsValid())
448 arch_to_use = remote_process_arch;
450 arch_to_use = remote_host_arch;
453 arch_to_use = target_arch;
456 if (!register_info_err) {
463 "Failed to read register information from target XML: {0}");
464 LLDB_LOG(log,
"Now trying to use qRegisterInfo instead.");
467 std::vector<DynamicRegisterInfo::Register> registers;
468 uint32_t reg_num = 0;
472 const int packet_len =
473 ::snprintf(packet,
sizeof(packet),
"qRegisterInfo%x", reg_num);
474 assert(packet_len < (
int)
sizeof(packet));
477 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
481 llvm::StringRef name;
482 llvm::StringRef value;
486 if (name ==
"name") {
488 }
else if (name ==
"alt-name") {
490 }
else if (name ==
"bitsize") {
491 if (!value.getAsInteger(0, reg_info.
byte_size))
493 }
else if (name ==
"offset") {
495 }
else if (name ==
"encoding") {
499 }
else if (name ==
"format") {
503 llvm::StringSwitch<Format>(value)
545 }
else if (name ==
"set") {
547 }
else if (name ==
"gcc" || name ==
"ehframe") {
549 }
else if (name ==
"dwarf") {
551 }
else if (name ==
"generic") {
553 }
else if (name ==
"container-regs") {
555 }
else if (name ==
"invalidate-regs") {
561 registers.push_back(reg_info);
574 "the debug server supports Target Description XML but LLDB does "
575 "not have XML parsing enabled. Using \"qRegisterInfo\" was also "
576 "not possible. Register information may be incorrect or missing",
586 if (registers.empty()) {
588 if (!registers.empty())
591 "All other methods failed, using fallback register information.");
606 bool wait_for_launch) {
638 if (
m_gdb_comm.GetProcessArchitecture().IsValid()) {
641 if (
m_gdb_comm.GetHostArchitecture().IsValid()) {
652 "Process %" PRIu64
" was reported after connecting to "
653 "'%s', but state was not stopped: %s",
657 "Process %" PRIu64
" was reported after connecting to '%s', "
658 "but no stop reply packet was received",
659 pid, remote_url.str().c_str());
663 "ProcessGDBRemote::%s pid %" PRIu64
664 ": normalizing target architecture initial triple: %s "
665 "(GetTarget().GetArchitecture().IsValid() %s, "
666 "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
667 __FUNCTION__,
GetID(),
668 GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
670 m_gdb_comm.GetHostArchitecture().IsValid() ?
"true" :
"false");
676 if (
m_gdb_comm.GetProcessArchitecture().IsValid())
683 "ProcessGDBRemote::%s pid %" PRIu64
684 ": normalized target architecture triple: %s",
685 __FUNCTION__,
GetID(),
686 GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
703 LLDB_LOGF(log,
"ProcessGDBRemote::%s() entered", __FUNCTION__);
705 uint32_t launch_flags = launch_info.
GetFlags().
Get();
728 if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
730 "ProcessGDBRemote::%s provided with STDIO paths via "
731 "launch_info: stdin=%s, stdout=%s, stderr=%s",
733 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
734 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
735 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
737 LLDB_LOGF(log,
"ProcessGDBRemote::%s no STDIO paths given via launch_info",
740 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
741 if (stdin_file_spec || disable_stdio) {
756 if (
error.Success()) {
758 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
763 if (!stdin_file_spec)
765 FileSpec::Style::native);
766 if (!stdout_file_spec)
768 FileSpec::Style::native);
769 if (!stderr_file_spec)
771 FileSpec::Style::native);
772 }
else if (platform_sp && platform_sp->IsHost()) {
777 if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
781 if (!stdin_file_spec)
782 stdin_file_spec = secondary_name;
784 if (!stdout_file_spec)
785 stdout_file_spec = secondary_name;
787 if (!stderr_file_spec)
788 stderr_file_spec = secondary_name;
792 "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
793 "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
796 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
797 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
798 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
802 "ProcessGDBRemote::%s final STDIO paths after all "
803 "adjustments: stdin=%s, stdout=%s, stderr=%s",
805 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
806 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
807 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
811 if (stdout_file_spec)
813 if (stderr_file_spec)
816 m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
817 m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
820 GetTarget().GetArchitecture().GetArchitectureName());
823 if (launch_event_data !=
nullptr && *launch_event_data !=
'\0')
824 m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
836 std::chrono::seconds(10));
843 if (llvm::Error err =
m_gdb_comm.LaunchProcess(args)) {
846 llvm::fmt_consume(std::move(err)));
853 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
875 if (!disable_stdio) {
881 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
error.AsCString());
891 if (!connect_url.empty()) {
892 LLDB_LOGF(log,
"ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
893 connect_url.str().c_str());
894 std::unique_ptr<ConnectionFileDescriptor> conn_up(
897 const uint32_t max_retry_count = 50;
898 uint32_t retry_count = 0;
907 if (retry_count >= max_retry_count)
910 std::this_thread::sleep_for(std::chrono::milliseconds(100));
934 m_gdb_comm.GetListThreadsInStopReplySupported();
941 auto handle_cmds = [&] (
const Args &args) ->
void {
945 entry.c_str(), response);
951 handle_cmds(platform_sp->GetExtraStartupCommands());
968 if (remote_process_arch.
IsValid()) {
969 process_arch = remote_process_arch;
970 LLDB_LOG(log,
"gdb-remote had process architecture, using {0} {1}",
974 process_arch =
m_gdb_comm.GetHostArchitecture();
976 "gdb-remote did not have process architecture, using gdb-remote "
977 "host architecture {0} {1}",
988 LLDB_LOG(log,
"analyzing target arch, currently {0} {1}",
1000 if ((process_arch.
GetMachine() == llvm::Triple::arm ||
1001 process_arch.
GetMachine() == llvm::Triple::thumb) &&
1002 process_arch.
GetTriple().getVendor() == llvm::Triple::Apple) {
1005 "remote process is ARM/Apple, "
1006 "setting target arch to {0} {1}",
1011 const llvm::Triple &remote_triple = process_arch.
GetTriple();
1012 llvm::Triple new_target_triple = target_arch.
GetTriple();
1013 if (new_target_triple.getVendorName().size() == 0) {
1014 new_target_triple.setVendor(remote_triple.getVendor());
1016 if (new_target_triple.getOSName().size() == 0) {
1017 new_target_triple.setOS(remote_triple.getOS());
1019 if (new_target_triple.getEnvironmentName().size() == 0)
1020 new_target_triple.setEnvironment(remote_triple.getEnvironment());
1023 ArchSpec new_target_arch = target_arch;
1024 new_target_arch.
SetTriple(new_target_triple);
1030 "final target arch after adjustments for remote architecture: "
1049 m_gdb_comm.GetSupportedStructuredDataPlugins())
1058 if (platform_sp && platform_sp->IsConnected())
1070 UUID standalone_uuid;
1072 bool standalone_value_is_offset;
1073 if (
m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value,
1074 standalone_value_is_offset)) {
1077 if (standalone_uuid.
IsValid()) {
1078 const bool force_symbol_search =
true;
1079 const bool notify =
true;
1080 const bool set_address_in_target =
true;
1081 const bool allow_memory_image_last_resort =
false;
1083 this,
"", standalone_uuid, standalone_value,
1084 standalone_value_is_offset, force_symbol_search, notify,
1085 set_address_in_target, allow_memory_image_last_resort);
1097 std::vector<addr_t> bin_addrs =
m_gdb_comm.GetProcessStandaloneBinaries();
1098 if (bin_addrs.size()) {
1100 const bool value_is_slide =
false;
1101 for (
addr_t addr : bin_addrs) {
1102 const bool notify =
true;
1109 .LoadPlatformBinaryAndSetup(
this, addr, notify))
1112 const bool force_symbol_search =
true;
1113 const bool set_address_in_target =
true;
1114 const bool allow_memory_image_last_resort =
false;
1117 this, llvm::StringRef(), uuid, addr, value_is_slide,
1118 force_symbol_search, notify, set_address_in_target,
1119 allow_memory_image_last_resort);
1129 std::optional<QOffsets> offsets =
m_gdb_comm.GetQOffsets();
1134 size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==
1135 offsets->offsets.size();
1139 bool changed =
false;
1140 module_sp->SetLoadAddress(
GetTarget(), offsets->offsets[0],
1145 m_process->GetTarget().ModulesDidLoad(list);
1159 LLDB_LOGF(log,
"ProcessGDBRemote::%s()", __FUNCTION__);
1165 if (
error.Success()) {
1169 const int packet_len =
1170 ::snprintf(packet,
sizeof(packet),
"vAttach;%" PRIx64, attach_pid);
1173 std::make_shared<EventDataBytes>(llvm::StringRef(packet, packet_len));
1188 if (process_name && process_name[0]) {
1190 if (
error.Success()) {
1196 if (!
m_gdb_comm.GetVAttachOrWaitSupported()) {
1211 auto data_sp = std::make_shared<EventDataBytes>(packet.
GetString());
1232llvm::Expected<std::string>
1237llvm::Expected<std::vector<uint8_t>>
1249 process_arch.
Clear();
1265 return m_gdb_comm.GetReverseStepSupported() ||
1272 LLDB_LOGF(log,
"ProcessGDBRemote::Resume(%s)",
1277 if (listener_sp->StartListeningForEvents(
1279 listener_sp->StartListeningForEvents(
1286 bool continue_packet_error =
false;
1300 std::string pid_prefix;
1302 pid_prefix = llvm::formatv(
"p{0:x-}.",
GetID());
1304 if (num_continue_c_tids == num_threads ||
1309 continue_packet.
Format(
"vCont;c:{0}-1", pid_prefix);
1317 for (tid_collection::const_iterator
1320 t_pos != t_end; ++t_pos)
1321 continue_packet.
Format(
";c:{0}{1:x-}", pid_prefix, *t_pos);
1323 continue_packet_error =
true;
1328 for (tid_sig_collection::const_iterator
1331 s_pos != s_end; ++s_pos)
1332 continue_packet.
Format(
";C{0:x-2}:{1}{2:x-}", s_pos->second,
1333 pid_prefix, s_pos->first);
1335 continue_packet_error =
true;
1340 for (tid_collection::const_iterator
1343 t_pos != t_end; ++t_pos)
1344 continue_packet.
Format(
";s:{0}{1:x-}", pid_prefix, *t_pos);
1346 continue_packet_error =
true;
1351 for (tid_sig_collection::const_iterator
1354 s_pos != s_end; ++s_pos)
1355 continue_packet.
Format(
";S{0:x-2}:{1}{2:x-}", s_pos->second,
1356 pid_prefix, s_pos->first);
1358 continue_packet_error =
true;
1361 if (continue_packet_error)
1362 continue_packet.
Clear();
1365 continue_packet_error =
true;
1371 if (num_continue_c_tids > 0) {
1372 if (num_continue_c_tids == num_threads) {
1376 continue_packet_error =
false;
1377 }
else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
1378 num_continue_s_tids == 0 && num_continue_S_tids == 0) {
1382 continue_packet_error =
false;
1386 if (continue_packet_error && num_continue_C_tids > 0) {
1387 if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
1388 num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
1389 num_continue_S_tids == 0) {
1392 if (num_continue_C_tids > 1) {
1397 if (num_continue_C_tids > 1) {
1398 continue_packet_error =
false;
1401 continue_packet_error =
true;
1404 if (!continue_packet_error)
1408 continue_packet_error =
false;
1411 if (!continue_packet_error) {
1413 continue_packet.
Printf(
"C%2.2x", continue_signo);
1418 if (continue_packet_error && num_continue_s_tids > 0) {
1419 if (num_continue_s_tids == num_threads) {
1425 continue_packet_error =
false;
1426 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1427 num_continue_s_tids == 1 && num_continue_S_tids == 0) {
1431 continue_packet_error =
false;
1435 if (!continue_packet_error && num_continue_S_tids > 0) {
1436 if (num_continue_S_tids == num_threads) {
1439 continue_packet_error =
false;
1440 if (num_continue_S_tids > 1) {
1441 for (
size_t i = 1; i < num_threads; ++i) {
1443 continue_packet_error =
true;
1446 if (!continue_packet_error) {
1449 continue_packet.
Printf(
"S%2.2x", step_signo);
1451 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1452 num_continue_s_tids == 0 && num_continue_S_tids == 1) {
1456 continue_packet_error =
false;
1462 if (num_continue_s_tids > 0 || num_continue_S_tids > 0) {
1464 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1465 "support reverse-stepping");
1467 "target does not support reverse-stepping");
1470 if (num_continue_S_tids > 0) {
1473 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1475 "can't deliver signals while running in reverse");
1478 if (num_continue_s_tids > 1) {
1479 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: can't step multiple "
1480 "threads in reverse");
1482 "can't step multiple threads while reverse-stepping");
1488 if (!
m_gdb_comm.GetReverseContinueSupported()) {
1489 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1490 "support reverse-continue");
1492 "target does not support reverse execution of processes");
1495 if (num_continue_C_tids > 0) {
1498 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1500 "can't deliver signals while running in reverse");
1508 continue_packet_error =
false;
1511 if (continue_packet_error) {
1513 "can't make continue packet for this resume");
1518 "Trying to resume but the async thread is dead.");
1519 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Trying to resume but the "
1520 "async thread is dead.");
1525 std::make_shared<EventDataBytes>(continue_packet.
GetString());
1528 if (!listener_sp->GetEvent(event_sp, ResumeTimeout())) {
1530 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Resume timed out.");
1533 "Broadcast continue, but the async thread was "
1534 "killed before we got an ack back.");
1536 "ProcessGDBRemote::DoResume: Broadcast continue, but the "
1537 "async thread was killed before we got an ack back.");
1553 llvm::StringRef value) {
1559 auto pid_tid = thread_ids.
GetPidTid(pid);
1560 if (pid_tid && pid_tid->first == pid) {
1566 }
while (thread_ids.
GetChar() ==
',');
1572 llvm::StringRef value) {
1574 for (llvm::StringRef x : llvm::split(value,
',')) {
1576 if (llvm::to_integer(x,
pc, 16))
1588 if (thread_infos && thread_infos->
GetSize() > 0) {
1612 const llvm::StringRef stop_info_str = stop_info.
GetStringRef();
1615 const size_t thread_pcs_pos = stop_info_str.find(
";thread-pcs:");
1616 if (thread_pcs_pos != llvm::StringRef::npos) {
1617 const size_t start = thread_pcs_pos + strlen(
";thread-pcs:");
1618 const size_t end = stop_info_str.find(
';', start);
1619 if (end != llvm::StringRef::npos) {
1620 llvm::StringRef value = stop_info_str.substr(start, end - start);
1625 const size_t threads_pos = stop_info_str.find(
";threads:");
1626 if (threads_pos != llvm::StringRef::npos) {
1627 const size_t start = threads_pos + strlen(
";threads:");
1628 const size_t end = stop_info_str.find(
';', start);
1629 if (end != llvm::StringRef::npos) {
1630 llvm::StringRef value = stop_info_str.substr(start, end - start);
1638 bool sequence_mutex_unavailable =
false;
1640 if (sequence_mutex_unavailable) {
1655 if (num_thread_ids == 0) {
1661 ThreadList old_thread_list_copy(old_thread_list);
1662 if (num_thread_ids > 0) {
1663 for (
size_t i = 0; i < num_thread_ids; ++i) {
1670 thread_sp.get(), thread_sp->GetID());
1673 thread_sp.get(), thread_sp->GetID());
1683 size_t old_num_thread_ids = old_thread_list_copy.
GetSize(
false);
1684 for (
size_t i = 0; i < old_num_thread_ids; i++) {
1686 if (old_thread_sp) {
1687 lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
1702 uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1715 if (thread_infos_sp) {
1719 const size_t n = thread_infos->
GetSize();
1720 for (
size_t i = 0; i < n; ++i) {
1726 if (tid == thread->GetID())
1755 if (
GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
1765 for (
const auto &pair : expedited_register_map) {
1766 uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1776 reg_value_extractor.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
1784 uint8_t signo,
const std::string &thread_name,
const std::string &reason,
1785 const std::string &description, uint32_t exc_type,
1786 const std::vector<addr_t> &exc_data,
addr_t thread_dispatch_qaddr,
1787 bool queue_vars_valid,
1789 LazyBool associated_with_dispatch_queue,
addr_t dispatch_queue_t,
1790 std::string &queue_name,
QueueKind queue_kind, uint64_t queue_serial,
1791 std::vector<lldb::addr_t> &added_binaries,
1816 reg_ctx_sp->InvalidateIfNeeded(
true);
1824 if (reg_ctx_sp->ReconfigureRegisterInfo()) {
1827 reg_ctx_sp->InvalidateAllRegisters();
1834 thread_sp->SetName(thread_name.empty() ?
nullptr : thread_name.c_str());
1839 if (queue_vars_valid)
1840 gdb_thread->
SetQueueInfo(std::move(queue_name), queue_kind, queue_serial,
1841 dispatch_queue_t, associated_with_dispatch_queue);
1855 StopInfoSP current_stop_info_sp = thread_sp->GetPrivateStopInfo(
false);
1857 current_stop_info_sp) {
1858 thread_sp->SetStopInfo(current_stop_info_sp);
1862 if (!thread_sp->StopInfoIsUpToDate()) {
1865 addr_t pc = thread_sp->GetRegisterContext()->GetPC();
1867 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1869 thread_sp->SetThreadStoppedAtUnexecutedBP(
pc);
1871 if (exc_type != 0) {
1879 if (interrupt_thread)
1880 thread_sp = interrupt_thread;
1882 const size_t exc_data_size = exc_data.size();
1883 thread_sp->SetStopInfo(
1885 *thread_sp, exc_type, exc_data_size,
1886 exc_data_size >= 1 ? exc_data[0] : 0,
1887 exc_data_size >= 2 ? exc_data[1] : 0,
1888 exc_data_size >= 3 ? exc_data[2] : 0));
1891 bool handled =
false;
1892 bool did_exec =
false;
1895 if (!reason.empty() && reason !=
"none") {
1896 if (reason ==
"trace") {
1899 }
else if (reason ==
"breakpoint") {
1900 thread_sp->SetThreadHitBreakpointSite();
1908 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
1909 thread_sp->SetStopInfo(
1911 *thread_sp, bp_site_sp->GetID()));
1914 thread_sp->SetStopInfo(invalid_stop_info_sp);
1917 }
else if (reason ==
"trap") {
1919 }
else if (reason ==
"watchpoint") {
1955 bool silently_continue =
false;
1965 silently_continue =
true;
1969 if (!wp_resource_sp) {
1971 LLDB_LOGF(log,
"failed to find watchpoint");
1978 watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
1981 *thread_sp, watch_id, silently_continue));
1983 }
else if (reason ==
"exception") {
1985 *thread_sp, description.c_str()));
1987 }
else if (reason ==
"history boundary") {
1989 *thread_sp, description.c_str()));
1991 }
else if (reason ==
"exec") {
1993 thread_sp->SetStopInfo(
1996 }
else if (reason ==
"processor trace") {
1998 *thread_sp, description.c_str()));
1999 }
else if (reason ==
"fork") {
2004 thread_sp->SetStopInfo(
2007 }
else if (reason ==
"vfork") {
2013 *thread_sp, child_pid, child_tid));
2015 }
else if (reason ==
"vforkdone") {
2016 thread_sp->SetStopInfo(
2022 if (!handled && signo && !did_exec) {
2043 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
2053 thread_sp->SetThreadHitBreakpointSite();
2055 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2057 thread_sp->GetRegisterContext()->SetPC(
pc);
2058 thread_sp->SetStopInfo(
2060 *thread_sp, bp_site_sp->GetID()));
2063 thread_sp->SetStopInfo(invalid_stop_info_sp);
2069 thread_sp->SetStopInfo(
2073 *thread_sp, signo, description.c_str()));
2084 if (interrupt_thread)
2085 thread_sp = interrupt_thread;
2088 *thread_sp, signo, description.c_str()));
2092 if (!description.empty()) {
2095 const char *stop_info_desc = stop_info_sp->GetDescription();
2096 if (!stop_info_desc || !stop_info_desc[0])
2097 stop_info_sp->SetDescription(description.c_str());
2100 *thread_sp, description.c_str()));
2110 const std::string &description) {
2119 *thread_sp, signo, description.c_str()));
2128 static constexpr llvm::StringLiteral g_key_tid(
"tid");
2129 static constexpr llvm::StringLiteral g_key_name(
"name");
2130 static constexpr llvm::StringLiteral g_key_reason(
"reason");
2131 static constexpr llvm::StringLiteral g_key_metype(
"metype");
2132 static constexpr llvm::StringLiteral g_key_medata(
"medata");
2133 static constexpr llvm::StringLiteral g_key_qaddr(
"qaddr");
2134 static constexpr llvm::StringLiteral g_key_dispatch_queue_t(
2135 "dispatch_queue_t");
2136 static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(
2137 "associated_with_dispatch_queue");
2138 static constexpr llvm::StringLiteral g_key_queue_name(
"qname");
2139 static constexpr llvm::StringLiteral g_key_queue_kind(
"qkind");
2140 static constexpr llvm::StringLiteral g_key_queue_serial_number(
"qserialnum");
2141 static constexpr llvm::StringLiteral g_key_registers(
"registers");
2142 static constexpr llvm::StringLiteral g_key_memory(
"memory");
2143 static constexpr llvm::StringLiteral g_key_description(
"description");
2144 static constexpr llvm::StringLiteral g_key_signal(
"signal");
2145 static constexpr llvm::StringLiteral g_key_added_binaries(
"added-binaries");
2146 static constexpr llvm::StringLiteral g_key_detailed_binaries_info(
2147 "detailed-binaries-info");
2152 std::string thread_name;
2154 std::string description;
2155 uint32_t exc_type = 0;
2156 std::vector<addr_t> exc_data;
2159 bool queue_vars_valid =
false;
2162 std::string queue_name;
2164 uint64_t queue_serial_number = 0;
2165 std::vector<addr_t> added_binaries;
2171 thread_dict->
ForEach([
this, &tid, &expedited_register_map, &thread_name,
2172 &signo, &reason, &description, &exc_type, &exc_data,
2173 &thread_dispatch_qaddr, &queue_vars_valid,
2174 &associated_with_dispatch_queue, &dispatch_queue_t,
2175 &queue_name, &queue_kind, &queue_serial_number,
2176 &added_binaries, &detailed_binaries_info](
2177 llvm::StringRef key,
2179 if (key == g_key_tid) {
2182 }
else if (key == g_key_metype) {
2184 exc_type =
object->GetUnsignedIntegerValue(0);
2185 }
else if (key == g_key_medata) {
2190 exc_data.push_back(object->GetUnsignedIntegerValue());
2194 }
else if (key == g_key_name) {
2195 thread_name = std::string(object->GetStringValue());
2196 }
else if (key == g_key_qaddr) {
2197 thread_dispatch_qaddr =
2199 }
else if (key == g_key_queue_name) {
2200 queue_vars_valid =
true;
2201 queue_name = std::string(object->GetStringValue());
2202 }
else if (key == g_key_queue_kind) {
2203 std::string queue_kind_str = std::string(object->GetStringValue());
2204 if (queue_kind_str ==
"serial") {
2205 queue_vars_valid =
true;
2207 }
else if (queue_kind_str ==
"concurrent") {
2208 queue_vars_valid =
true;
2211 }
else if (key == g_key_queue_serial_number) {
2212 queue_serial_number =
object->GetUnsignedIntegerValue(0);
2213 if (queue_serial_number != 0)
2214 queue_vars_valid =
true;
2215 }
else if (key == g_key_dispatch_queue_t) {
2216 dispatch_queue_t =
object->GetUnsignedIntegerValue(0);
2218 queue_vars_valid =
true;
2219 }
else if (key == g_key_associated_with_dispatch_queue) {
2220 queue_vars_valid =
true;
2221 bool associated =
object->GetBooleanValue();
2226 }
else if (key == g_key_reason) {
2227 reason = std::string(object->GetStringValue());
2228 }
else if (key == g_key_description) {
2229 description = std::string(object->GetStringValue());
2230 }
else if (key == g_key_registers) {
2233 if (registers_dict) {
2235 [&expedited_register_map](llvm::StringRef key,
2238 if (llvm::to_integer(key, reg))
2239 expedited_register_map[reg] =
2240 std::string(object->GetStringValue());
2244 }
else if (key == g_key_memory) {
2250 if (mem_cache_dict) {
2253 "address", mem_cache_addr)) {
2255 llvm::StringRef str;
2260 const size_t byte_size = bytes.
GetStringRef().size() / 2;
2263 const size_t bytes_copied =
2265 if (bytes_copied == byte_size)
2275 }
else if (key == g_key_signal)
2277 else if (key == g_key_added_binaries) {
2280 array->
ForEach([&added_binaries](
2283 object->GetAsUnsignedInteger();
2287 added_binaries.push_back(value);
2292 }
else if (key == g_key_detailed_binaries_info) {
2297 if (object->GetAsDictionary()) {
2299 object->Dump(json_str);
2300 detailed_binaries_info =
2308 tid, expedited_register_map, signo, thread_name, reason, description,
2309 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2310 associated_with_dispatch_queue, dispatch_queue_t, queue_name, queue_kind,
2311 queue_serial_number, added_binaries, detailed_binaries_info);
2317 const char stop_type = stop_packet.
GetChar();
2318 switch (stop_type) {
2337 const uint8_t signo = stop_packet.
GetHexU8();
2338 llvm::StringRef key;
2339 llvm::StringRef value;
2340 std::string thread_name;
2342 std::string description;
2343 std::vector<addr_t> added_binaries;
2345 uint32_t exc_type = 0;
2346 std::vector<addr_t> exc_data;
2348 bool queue_vars_valid =
2352 std::string queue_name;
2354 uint64_t queue_serial_number = 0;
2358 if (key.compare(
"metype") == 0) {
2360 value.getAsInteger(16, exc_type);
2361 }
else if (key.compare(
"medata") == 0) {
2364 value.getAsInteger(16, x);
2365 exc_data.push_back(x);
2366 }
else if (key.compare(
"thread") == 0) {
2369 auto pid_tid = thread_id.
GetPidTid(pid);
2371 stop_pid = pid_tid->first;
2372 tid = pid_tid->second;
2375 }
else if (key.compare(
"threads") == 0) {
2376 std::lock_guard<std::recursive_mutex> guard(
2379 }
else if (key.compare(
"thread-pcs") == 0) {
2384 while (!value.empty()) {
2385 llvm::StringRef pc_str;
2386 std::tie(pc_str, value) = value.split(
',');
2387 if (pc_str.getAsInteger(16,
pc))
2391 }
else if (key.compare(
"jstopinfo") == 0) {
2400 }
else if (key.compare(
"hexname") == 0) {
2404 }
else if (key.compare(
"name") == 0) {
2405 thread_name = std::string(value);
2406 }
else if (key.compare(
"qaddr") == 0) {
2407 value.getAsInteger(16, thread_dispatch_qaddr);
2408 }
else if (key.compare(
"dispatch_queue_t") == 0) {
2409 queue_vars_valid =
true;
2410 value.getAsInteger(16, dispatch_queue_t);
2411 }
else if (key.compare(
"qname") == 0) {
2412 queue_vars_valid =
true;
2416 }
else if (key.compare(
"qkind") == 0) {
2417 queue_kind = llvm::StringSwitch<QueueKind>(value)
2422 }
else if (key.compare(
"qserialnum") == 0) {
2423 if (!value.getAsInteger(0, queue_serial_number))
2424 queue_vars_valid =
true;
2425 }
else if (key.compare(
"reason") == 0) {
2426 reason = std::string(value);
2427 }
else if (key.compare(
"description") == 0) {
2431 }
else if (key.compare(
"memory") == 0) {
2445 llvm::StringRef addr_str, bytes_str;
2446 std::tie(addr_str, bytes_str) = value.split(
'=');
2447 if (!addr_str.empty() && !bytes_str.empty()) {
2449 if (!addr_str.getAsInteger(0, mem_cache_addr)) {
2454 const size_t bytes_copied =
2456 if (bytes_copied == byte_size)
2460 }
else if (key.compare(
"watch") == 0 || key.compare(
"rwatch") == 0 ||
2461 key.compare(
"awatch") == 0) {
2464 value.getAsInteger(16, wp_addr);
2472 reason =
"watchpoint";
2474 ostr.
Printf(
"%" PRIu64, wp_addr);
2475 description = std::string(ostr.
GetString());
2476 }
else if (key.compare(
"swbreak") == 0 || key.compare(
"hwbreak") == 0) {
2477 reason =
"breakpoint";
2478 }
else if (key.compare(
"replaylog") == 0) {
2479 reason =
"history boundary";
2480 }
else if (key.compare(
"library") == 0) {
2486 }
else if (key.compare(
"fork") == 0 || key.compare(
"vfork") == 0) {
2492 LLDB_LOG(log,
"Invalid PID/TID to fork: {0}", value);
2498 ostr.
Printf(
"%" PRIu64
" %" PRIu64, pid_tid->first, pid_tid->second);
2499 description = std::string(ostr.
GetString());
2500 }
else if (key.compare(
"addressing_bits") == 0) {
2501 uint64_t addressing_bits;
2502 if (!value.getAsInteger(0, addressing_bits)) {
2505 }
else if (key.compare(
"low_mem_addressing_bits") == 0) {
2506 uint64_t addressing_bits;
2507 if (!value.getAsInteger(0, addressing_bits)) {
2510 }
else if (key.compare(
"high_mem_addressing_bits") == 0) {
2511 uint64_t addressing_bits;
2512 if (!value.getAsInteger(0, addressing_bits)) {
2515 }
else if (key ==
"added-binaries") {
2519 while (!value.empty()) {
2520 llvm::StringRef pc_str;
2521 std::tie(pc_str, value) = value.split(
',');
2522 if (pc_str.getAsInteger(16,
pc))
2524 added_binaries.push_back(
pc);
2526 }
else if (key ==
"detailed-binaries-info") {
2534 }
else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
2536 if (!key.getAsInteger(16, reg))
2537 expedited_register_map[reg] = std::string(std::move(value));
2547 "Received stop for incorrect PID = {0} (inferior PID = {1})",
2567 tid, expedited_register_map, signo, thread_name, reason, description,
2568 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2569 associated_with_dispatch_queue, dispatch_queue_t, queue_name,
2570 queue_kind, queue_serial_number, added_binaries,
2571 detailed_binaries_info);
2638 LLDB_LOGF(log,
"ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
2642 if (
error.Success())
2644 "ProcessGDBRemote::DoDetach() detach packet sent successfully");
2647 "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
2648 error.AsCString() ?
error.AsCString() :
"<unknown error>");
2651 if (!
error.Success())
2666 LLDB_LOGF(log,
"ProcessGDBRemote::DoDestroy()");
2669 int exit_status = SIGABRT;
2670 std::string exit_string;
2677 exit_status = kill_res.get();
2678#if defined(__APPLE__)
2690 if (platform_sp && platform_sp->IsHost()) {
2693 reap_pid = waitpid(
GetID(), &status, WNOHANG);
2694 LLDB_LOGF(log,
"Reaped pid: %d, status: %d.\n", reap_pid, status);
2698 exit_string.assign(
"killed");
2700 exit_string.assign(llvm::toString(kill_res.takeError()));
2703 exit_string.assign(
"killed or interrupted while attaching.");
2709 exit_string.assign(
"destroying when not connected to debugserver");
2730 const bool did_exec =
2731 response.
GetStringRef().find(
";reason:exec;") != std::string::npos;
2734 LLDB_LOGF(log,
"ProcessGDBRemote::SetLastStopPacket () - detected exec");
2739 m_gdb_comm.ResetDiscoverableSettings(did_exec);
2764 LLDB_LOG_ERROR(log, list.takeError(),
"Failed to read module list: {0}.");
2766 addr = list->m_link_map;
2786 const size_t n = thread_infos->
GetSize();
2787 for (
size_t i = 0; i < n; ++i) {
2803 xPacketState x_state =
m_gdb_comm.GetxPacketState();
2806 size_t max_memory_size = x_state != xPacketState::Unimplemented
2809 if (size > max_memory_size) {
2813 size = max_memory_size;
2818 packet_len = ::snprintf(packet,
sizeof(packet),
"%c%" PRIx64
",%" PRIx64,
2819 x_state != xPacketState::Unimplemented ?
'x' :
'm',
2820 (uint64_t)addr, (uint64_t)size);
2821 assert(packet_len + 1 < (
int)
sizeof(packet));
2824 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
2829 if (x_state != xPacketState::Unimplemented) {
2834 llvm::StringRef data_received = response.
GetStringRef();
2835 if (x_state == xPacketState::Prefixed &&
2836 !data_received.consume_front(
"b")) {
2838 "unexpected response to GDB server memory read packet '{0}': "
2840 packet, data_received);
2845 size_t memcpy_size = std::min(size, data_received.size());
2846 memcpy(buf, data_received.data(), memcpy_size);
2850 llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size),
'\xdd');
2854 "memory read failed for 0x%" PRIx64, addr);
2857 "GDB server does not support reading memory");
2860 "unexpected response to GDB server memory read packet '%s': '%s'",
2872 uint64_t max_packet_size,
2876 constexpr uint64_t range_overhead = 33;
2877 uint64_t current_size = 0;
2878 for (
auto [idx, range] : llvm::enumerate(ranges)) {
2879 uint64_t potential_size = current_size + range.size + range_overhead;
2880 if (potential_size > max_packet_size) {
2883 "MultiMemRead input has a range (base = {0:x}, size = {1}) "
2884 "bigger than the maximum allowed by remote",
2885 range.base, range.size);
2889 return ranges.size();
2892llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>
2895 llvm::MutableArrayRef<uint8_t> buffer) {
2899 const llvm::ArrayRef<Range<lldb::addr_t, size_t>> original_ranges = ranges;
2900 llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> memory_regions;
2902 while (!ranges.empty()) {
2903 uint64_t num_ranges =
2905 if (num_ranges == 0)
2908 auto ranges_for_request = ranges.take_front(num_ranges);
2909 ranges = ranges.drop_front(num_ranges);
2911 llvm::Expected<StringExtractorGDBRemote> response =
2915 "MultiMemRead error response: {0}");
2919 llvm::StringRef response_str = response->GetStringRef();
2920 const unsigned expected_num_ranges = ranges_for_request.size();
2922 response_str, buffer, expected_num_ranges, memory_regions)) {
2924 "MultiMemRead error parsing response: {0}");
2928 return memory_regions;
2931llvm::Expected<StringExtractorGDBRemote>
2934 std::string packet_str;
2935 llvm::raw_string_ostream stream(packet_str);
2936 stream <<
"MultiMemRead:ranges:";
2938 auto range_to_stream = [&](
auto range) {
2940 stream << llvm::formatv(
"{0:x-},{1:x-}", range.base, range.size);
2942 llvm::interleave(ranges, stream, range_to_stream,
",");
2947 m_gdb_comm.SendPacketAndWaitForResponse(packet_str.data(), response,
2950 return llvm::createStringErrorV(
"MultiMemRead failed to send packet: '{0}'",
2954 return llvm::createStringErrorV(
"MultiMemRead failed: '{0}'",
2958 return llvm::createStringErrorV(
"MultiMemRead unexpected response: '{0}'",
2965 llvm::StringRef response_str, llvm::MutableArrayRef<uint8_t> buffer,
2966 unsigned expected_num_ranges,
2969 auto [sizes_str, memory_data] = response_str.split(
';');
2970 if (sizes_str.size() == response_str.size())
2971 return llvm::createStringErrorV(
2972 "MultiMemRead response missing field separator ';' in: '{0}'",
2976 for (llvm::StringRef size_str : llvm::split(sizes_str,
',')) {
2978 if (size_str.getAsInteger(16, read_size))
2979 return llvm::createStringErrorV(
2980 "MultiMemRead response has invalid size string: {0}", size_str);
2982 if (memory_data.size() < read_size)
2983 return llvm::createStringErrorV(
"MultiMemRead response did not have "
2984 "enough data, requested sizes: {0}",
2987 llvm::StringRef region_to_read = memory_data.take_front(read_size);
2988 memory_data = memory_data.drop_front(read_size);
2990 assert(buffer.size() >= read_size);
2991 llvm::MutableArrayRef<uint8_t> region_to_write =
2992 buffer.take_front(read_size);
2993 buffer = buffer.drop_front(read_size);
2995 memcpy(region_to_write.data(), region_to_read.data(), read_size);
2996 memory_regions.push_back(region_to_write);
2999 return llvm::Error::success();
3003 return m_gdb_comm.GetMemoryTaggingSupported();
3006llvm::Expected<std::vector<uint8_t>>
3013 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3014 "Error reading memory tags from remote");
3018 llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
3019 std::vector<uint8_t> got;
3020 got.reserve(tag_data.size());
3021 std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
3027 const std::vector<uint8_t> &tags) {
3030 return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
3034 std::vector<ObjectFile::LoadableData> entries) {
3044 if (
error.Success())
3058 for (
size_t i = 0; i < size; ++i)
3083 if (blocksize == 0) {
3091 lldb::addr_t block_start_addr = addr - (addr % blocksize);
3092 size += (addr - block_start_addr);
3093 if ((size % blocksize) != 0)
3094 size += (blocksize - size % blocksize);
3110 auto overlap = last_range.GetRangeEnd() - range.
GetRangeBase();
3131 "flash erase failed for 0x%" PRIx64, addr);
3134 "GDB server does not support flashing");
3137 "unexpected response to GDB server flash erase packet '%s': '%s'",
3154 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"vFlashDone", response,
3164 "GDB server does not support flashing");
3167 "unexpected response to GDB server flash done packet: '%s'",
3182 if (size > max_memory_size) {
3186 size = max_memory_size;
3206 if (!
error.Success())
3208 packet.
Printf(
"vFlashWrite:%" PRIx64
":", addr);
3211 packet.
Printf(
"M%" PRIx64
",%" PRIx64
":", addr, (uint64_t)size);
3224 "memory write failed for 0x%" PRIx64, addr);
3227 "GDB server does not support writing memory");
3230 "unexpected response to GDB server memory write packet '%s': '%s'",
3240 uint32_t permissions,
3246 allocated_addr =
m_gdb_comm.AllocateMemory(size, permissions);
3249 return allocated_addr;
3255 if (permissions & lldb::ePermissionsReadable)
3257 if (permissions & lldb::ePermissionsWritable)
3259 if (permissions & lldb::ePermissionsExecutable)
3268 "ProcessGDBRemote::%s no direct stub support for memory "
3269 "allocation, and InferiorCallMmap also failed - is stub "
3270 "missing register context save/restore capability?",
3277 "unable to allocate %" PRIu64
" bytes of memory with permissions %s",
3281 return allocated_addr;
3296 return m_gdb_comm.GetWatchpointReportedAfter();
3303 switch (supported) {
3308 "tried to deallocate memory without ever allocating memory");
3314 "unable to deallocate memory at 0x%" PRIx64, addr);
3326 "unable to deallocate memory at 0x%" PRIx64, addr);
3341 m_gdb_comm.SendStdinNotification(src, src_len);
3359 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3361 if (error_no == 0) {
3364 return llvm::Error::success();
3367 if (error_no != UINT8_MAX)
3368 return llvm::createStringErrorV(
3369 "error sending the breakpoint request: {0}", error_no);
3370 return llvm::createStringError(
"error sending the breakpoint request");
3372 LLDB_LOG(log,
"Software breakpoints are unsupported");
3377 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3379 if (error_no == 0) {
3382 return llvm::Error::success();
3385 if (error_no != UINT8_MAX)
3386 return llvm::createStringErrorV(
3387 "error sending the hardware breakpoint request: {0} "
3388 "(hardware breakpoint resources might be exhausted or unavailable)",
3390 return llvm::createStringError(
3391 "error sending the hardware breakpoint request "
3392 "(hardware breakpoint resources might be exhausted or unavailable)");
3394 LLDB_LOG(log,
"Hardware breakpoints are unsupported");
3398 return llvm::createStringError(
"hardware breakpoints are not supported");
3414 return error.takeError();
3420 return llvm::createStringError(
"unknown error");
3425 return llvm::createStringError(
"unknown error");
3429 return llvm::Error::success();
3433 assert(bp_site !=
nullptr);
3444 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3445 ") address = 0x%" PRIx64,
3446 site_id, (uint64_t)addr);
3451 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3452 ") address = 0x%" PRIx64
" -- SUCCESS (already enabled)",
3453 site_id, (uint64_t)addr);
3461 assert(bp_site !=
nullptr);
3466 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3467 ") addr = 0x%8.8" PRIx64,
3468 site_id, (uint64_t)addr);
3472 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3473 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3474 site_id, (uint64_t)addr);
3485 bool read = wp_res_sp->WatchpointResourceRead();
3486 bool write = wp_res_sp->WatchpointResourceWrite();
3488 assert((read || write) &&
3489 "WatchpointResource type is neither read nor write");
3505 addr_t addr = wp_sp->GetLoadAddress();
3507 LLDB_LOGF(log,
"ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
")",
3509 if (wp_sp->IsEnabled()) {
3511 "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
3512 ") addr = 0x%8.8" PRIx64
": watchpoint already enabled.",
3513 watchID, (uint64_t)addr);
3517 bool read = wp_sp->WatchpointRead();
3518 bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
3519 size_t size = wp_sp->GetByteSize();
3522 WatchpointHardwareFeature supported_features =
3525 std::vector<WatchpointResourceSP> resources =
3527 addr, size, read, write, supported_features, target_arch);
3552 bool set_all_resources =
true;
3553 std::vector<WatchpointResourceSP> succesfully_set_resources;
3554 for (
const auto &wp_res_sp : resources) {
3555 addr_t addr = wp_res_sp->GetLoadAddress();
3556 size_t size = wp_res_sp->GetByteSize();
3558 if (!
m_gdb_comm.SupportsGDBStoppointPacket(type) ||
3559 m_gdb_comm.SendGDBStoppointTypePacket(type,
true, addr, size,
3561 set_all_resources =
false;
3564 succesfully_set_resources.push_back(wp_res_sp);
3567 if (set_all_resources) {
3568 wp_sp->SetEnabled(
true, notify);
3569 for (
const auto &wp_res_sp : resources) {
3572 wp_res_sp->AddConstituent(wp_sp);
3580 for (
const auto &wp_res_sp : succesfully_set_resources) {
3581 addr_t addr = wp_res_sp->GetLoadAddress();
3582 size_t size = wp_res_sp->GetByteSize();
3584 m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3588 "Setting one of the watchpoint resources failed");
3604 addr_t addr = wp_sp->GetLoadAddress();
3607 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3608 ") addr = 0x%8.8" PRIx64,
3609 watchID, (uint64_t)addr);
3611 if (!wp_sp->IsEnabled()) {
3613 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3614 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3615 watchID, (uint64_t)addr);
3619 wp_sp->SetEnabled(
false, notify);
3623 if (wp_sp->IsHardware()) {
3624 bool disabled_all =
true;
3626 std::vector<WatchpointResourceSP> unused_resources;
3628 if (wp_res_sp->ConstituentsContains(wp_sp)) {
3630 addr_t addr = wp_res_sp->GetLoadAddress();
3631 size_t size = wp_res_sp->GetByteSize();
3632 if (
m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3634 disabled_all =
false;
3636 wp_res_sp->RemoveConstituent(wp_sp);
3637 if (wp_res_sp->GetNumberOfConstituents() == 0)
3638 unused_resources.push_back(wp_res_sp);
3642 for (
auto &wp_res_sp : unused_resources)
3645 wp_sp->SetEnabled(
false, notify);
3648 "Failure disabling one of the watchpoint locations");
3661 LLDB_LOGF(log,
"ProcessGDBRemote::DoSignal (signal = %d)", signo);
3676 if (platform_sp && !platform_sp->IsHost())
3681 const char *error_string =
error.AsCString();
3682 if (error_string ==
nullptr)
3691 static FileSpec g_debugserver_file_spec;
3698 std::string env_debugserver_path = host_env.lookup(
"LLDB_DEBUGSERVER_PATH");
3699 if (!env_debugserver_path.empty()) {
3700 debugserver_file_spec.
SetFile(env_debugserver_path,
3701 FileSpec::Style::native);
3702 LLDB_LOG(log,
"gdb-remote stub exe path set from environment variable: {0}",
3703 env_debugserver_path);
3705 debugserver_file_spec = g_debugserver_file_spec;
3707 return debugserver_file_spec;
3710 debugserver_file_spec = HostInfo::GetSupportExeDir();
3711 if (debugserver_file_spec) {
3714 LLDB_LOG(log,
"found gdb-remote stub exe '{0}'", debugserver_file_spec);
3716 g_debugserver_file_spec = debugserver_file_spec;
3719 if (!debugserver_file_spec) {
3722 LLDB_LOG(log,
"could not find gdb-remote stub exe '{0}'",
3723 debugserver_file_spec);
3727 g_debugserver_file_spec.
Clear();
3730 return debugserver_file_spec;
3735 using namespace std::placeholders;
3745 const std::weak_ptr<ProcessGDBRemote> this_wp =
3746 std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3753#if defined(__APPLE__)
3757 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
3759 struct kinfo_proc processInfo;
3760 size_t bufsize =
sizeof(processInfo);
3761 if (sysctl(mib, (
unsigned)(
sizeof(mib) /
sizeof(
int)), &processInfo, &bufsize,
3764 if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
3765 debugserver_path =
FileSpec(
"/Library/Apple/usr/libexec/oah/debugserver");
3772 "'. Please ensure it is properly installed "
3773 "and available in your PATH");
3788 debugserver_launch_info,
nullptr);
3793 LLDB_LOGF(log,
"failed to start debugserver process: %s",
3803 m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>(
3804 std::move(socket_pair->second)));
3818 std::weak_ptr<ProcessGDBRemote> process_wp,
lldb::pid_t debugserver_pid,
3827 "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
3828 ", signo=%i (0x%x), exit_status=%i)",
3829 __FUNCTION__, debugserver_pid, signo, signo, exit_status);
3831 std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
3832 LLDB_LOGF(log,
"ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
3833 static_cast<void *
>(process_sp.get()));
3834 if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
3840 std::this_thread::sleep_for(std::chrono::milliseconds(500));
3844 const StateType state = process_sp->GetState();
3853 llvm::StringRef signal_name =
3854 process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);
3856 if (!signal_name.empty())
3857 stream.
Format(format_str, signal_name);
3859 stream.
Format(format_str, signo);
3861 process_sp->SetExitStatus(-1, stream.
GetString());
3884 debugger, PluginProperties::GetSettingName())) {
3885 const bool is_global_setting =
true;
3888 "Properties for the gdb-remote process plug-in.", is_global_setting);
3895 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
3902 llvm::Expected<HostThread> async_thread =
3906 if (!async_thread) {
3908 "failed to launch host thread: {0}");
3914 "ProcessGDBRemote::%s () - Called when Async thread was "
3924 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
3939 "ProcessGDBRemote::%s () - Called when Async thread was not running.",
3945 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread starting...",
3946 __FUNCTION__,
GetID());
3964 "ProcessGDBRemote::%s(pid = %" PRIu64
3965 ") listener.WaitForEvent (NULL, event_sp)...",
3966 __FUNCTION__,
GetID());
3969 const uint32_t event_type = event_sp->GetType();
3972 "ProcessGDBRemote::%s(pid = %" PRIu64
3973 ") Got an event of type: %d...",
3974 __FUNCTION__,
GetID(), event_type);
3976 switch (event_type) {
3981 if (continue_packet) {
3982 const char *continue_cstr =
3983 (
const char *)continue_packet->
GetBytes();
3984 const size_t continue_cstr_len = continue_packet->
GetByteSize();
3986 "ProcessGDBRemote::%s(pid = %" PRIu64
3987 ") got eBroadcastBitAsyncContinue: %s",
3988 __FUNCTION__,
GetID(), continue_cstr);
3990 if (::strstr(continue_cstr,
"vAttach") ==
nullptr)
3997 llvm::StringRef(continue_cstr, continue_cstr_len),
4008 switch (stop_state) {
4021 int exit_status = response.
GetHexU8();
4022 std::string desc_string;
4024 llvm::StringRef desc_str;
4025 llvm::StringRef desc_token;
4027 if (desc_token !=
"description")
4042 if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4045 "System Integrity Protection");
4046 }
else if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4066 "ProcessGDBRemote::%s(pid = %" PRIu64
4067 ") got eBroadcastBitAsyncThreadShouldExit...",
4068 __FUNCTION__,
GetID());
4074 "ProcessGDBRemote::%s(pid = %" PRIu64
4075 ") got unknown event 0x%8.8x",
4076 __FUNCTION__,
GetID(), event_type);
4083 "ProcessGDBRemote::%s(pid = %" PRIu64
4084 ") listener.WaitForEvent (NULL, event_sp) => false",
4085 __FUNCTION__,
GetID());
4090 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread exiting...",
4091 __FUNCTION__,
GetID());
4123 LLDB_LOGF(log,
"Hit New Thread Notification breakpoint.");
4129 LLDB_LOG(log,
"Check if need to update ignored signals");
4143 LLDB_LOG(log,
"Signals' version hasn't changed. version={0}",
4148 auto signals_to_ignore =
4153 "Signals' version changed. old version={0}, new version={1}, "
4154 "signals ignored={2}, update result={3}",
4156 signals_to_ignore.size(),
error);
4158 if (
error.Success())
4173 platform_sp->SetThreadCreationBreakpoint(
GetTarget());
4176 log,
"Successfully created new thread notification breakpoint %i",
4181 LLDB_LOGF(log,
"Failed to create new thread notification breakpoint.");
4210 return_value =
m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
4211 if (return_value != 0) {
4214 "Sending events is not supported for this process.");
4224 if (
m_gdb_comm.GetQXferAuxvReadSupported()) {
4225 llvm::Expected<std::string> response =
m_gdb_comm.ReadExtFeature(
"auxv",
"");
4227 buf = std::make_shared<DataBufferHeap>(response->c_str(),
4228 response->length());
4239 if (
m_gdb_comm.GetThreadExtendedInfoSupported()) {
4245 args_dict->GetAsDictionary()->AddIntegerItem(
"thread", tid);
4248 packet <<
"jThreadExtendedInfo:";
4249 args_dict->Dump(packet,
false);
4256 packet << (char)(0x7d ^ 0x20);
4265 if (!response.
Empty()) {
4278 args_dict->GetAsDictionary()->AddIntegerItem(
"image_list_address",
4279 image_list_address);
4280 args_dict->GetAsDictionary()->AddIntegerItem(
"image_count", image_count);
4287 std::string info_level_str;
4289 info_level_str =
"address-only";
4291 info_level_str =
"address-name";
4293 info_level_str =
"address-name-uuid";
4295 info_level_str =
"full";
4297 return info_level_str;
4304 args_dict->GetAsDictionary()->AddBooleanItem(
"fetch_all_solibs",
true);
4306 args_dict->GetAsDictionary()->AddBooleanItem(
"report_load_commands",
false);
4308 if (!info_level_str.empty())
4309 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4310 info_level_str.c_str());
4317 const std::vector<lldb::addr_t> &load_addresses) {
4321 for (
auto addr : load_addresses)
4322 addresses->AddIntegerItem(addr);
4324 args_dict->GetAsDictionary()->AddItem(
"solib_addresses", addresses);
4327 if (!info_level_str.empty())
4328 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4329 info_level_str.c_str());
4339 if (
m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
4342 std::chrono::seconds(10));
4345 packet <<
"jGetLoadedDynamicLibrariesInfos:";
4346 args_dict->Dump(packet,
false);
4353 packet << (char)(0x7d ^ 0x20);
4362 if (!response.
Empty()) {
4375 if (
m_gdb_comm.GetDynamicLoaderProcessStateSupported()) {
4378 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"jGetDyldProcessState",
4384 if (!response.
Empty()) {
4401 packet <<
"jGetSharedCacheInfo:";
4402 args_dict->Dump(packet,
false);
4411 if (response.
Empty())
4420 if (!dict->
HasKey(
"shared_cache_uuid"))
4422 llvm::StringRef uuid_str;
4424 uuid_str ==
"00000000-0000-0000-0000-000000000000")
4426 if (dict->
HasKey(
"shared_cache_path")) {
4440 HostInfo::SharedCacheIndexFiles(sc_path, uuid, sc_mode);
4451 return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
4464 const uint64_t reasonable_largeish_default = 128 * 1024;
4465 const uint64_t conservative_default = 512;
4468 uint64_t stub_max_size =
m_gdb_comm.GetRemoteMaxPacketSize();
4469 if (stub_max_size !=
UINT64_MAX && stub_max_size != 0) {
4475 if (stub_max_size > reasonable_largeish_default) {
4476 stub_max_size = reasonable_largeish_default;
4482 if (stub_max_size > 70)
4483 stub_max_size -= 32 + 32 + 6;
4488 LLDB_LOG(log,
"warning: Packet size is too small. "
4489 "LLDB may face problems while writing memory");
4500 uint64_t user_specified_max) {
4501 if (user_specified_max != 0) {
4529 module_spec = cached->second;
4530 return bool(module_spec);
4533 if (!
m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
4534 LLDB_LOGF(log,
"ProcessGDBRemote::%s - failed to get module info for %s:%s",
4535 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4542 module_spec.
Dump(stream);
4543 LLDB_LOGF(log,
"ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
4544 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4553 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4554 auto module_specs =
m_gdb_comm.GetModulesInfo(module_file_specs, triple);
4556 for (
const FileSpec &spec : module_file_specs)
4561 triple.getTriple())] = spec;
4575typedef std::vector<std::string> stringVec;
4577typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
4578struct RegisterSetInfo {
4582typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
4584struct GdbServerTargetInfo {
4588 RegisterSetMap reg_set_map;
4605 std::map<uint64_t, FieldEnum::Enumerator> enumerators;
4608 "evalue", [&enumerators, &log](
const XMLNode &enumerator_node) {
4609 std::optional<llvm::StringRef> name;
4610 std::optional<uint64_t> value;
4613 [&name, &value, &log](
const llvm::StringRef &attr_name,
4614 const llvm::StringRef &attr_value) {
4615 if (attr_name ==
"name") {
4616 if (attr_value.size())
4619 LLDB_LOG(log,
"ProcessGDBRemote::ParseEnumEvalues "
4620 "Ignoring empty name in evalue");
4621 }
else if (attr_name ==
"value") {
4622 uint64_t parsed_value = 0;
4623 if (llvm::to_integer(attr_value, parsed_value))
4624 value = parsed_value;
4627 "ProcessGDBRemote::ParseEnumEvalues "
4628 "Invalid value \"{0}\" in "
4633 "ProcessGDBRemote::ParseEnumEvalues Ignoring "
4634 "unknown attribute "
4635 "\"{0}\" in evalue",
4643 enumerators.insert_or_assign(
4644 *value, FieldEnum::Enumerator(*value, name->str()));
4651 for (
auto [_, enumerator] : enumerators)
4652 final_enumerators.push_back(enumerator);
4654 return final_enumerators;
4658ParseEnums(XMLNode feature_node,
4659 llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4660 Log *log(
GetLog(GDBRLog::Process));
4664 "enum", [log, ®isters_enum_types](
const XMLNode &enum_node) {
4668 const llvm::StringRef &attr_value) {
4669 if (attr_name ==
"id")
4687 if (!enumerators.empty()) {
4689 "ProcessGDBRemote::ParseEnums Found enum type \"{0}\"",
4691 registers_enum_types.insert_or_assign(
4692 id, std::make_unique<FieldEnum>(
id, enumerators));
4701static std::vector<RegisterFlags::Field> ParseFlagsFields(
4702 XMLNode flags_node,
unsigned size,
4703 const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4704 Log *log(
GetLog(GDBRLog::Process));
4705 const unsigned max_start_bit = size * 8 - 1;
4708 std::vector<RegisterFlags::Field> fields;
4710 ®isters_enum_types](
4713 std::optional<llvm::StringRef> name;
4714 std::optional<unsigned> start;
4715 std::optional<unsigned> end;
4716 std::optional<llvm::StringRef> type;
4719 &log](
const llvm::StringRef &attr_name,
4720 const llvm::StringRef &attr_value) {
4723 if (attr_name ==
"name") {
4726 "ProcessGDBRemote::ParseFlagsFields Found field node name \"{0}\"",
4729 }
else if (attr_name ==
"start") {
4730 unsigned parsed_start = 0;
4731 if (llvm::to_integer(attr_value, parsed_start)) {
4732 if (parsed_start > max_start_bit) {
4734 "ProcessGDBRemote::ParseFlagsFields Invalid start {0} in "
4737 parsed_start, max_start_bit);
4739 start = parsed_start;
4743 "ProcessGDBRemote::ParseFlagsFields Invalid start \"{0}\" in "
4747 }
else if (attr_name ==
"end") {
4748 unsigned parsed_end = 0;
4749 if (llvm::to_integer(attr_value, parsed_end))
4750 if (parsed_end > max_start_bit) {
4752 "ProcessGDBRemote::ParseFlagsFields Invalid end {0} in "
4755 parsed_end, max_start_bit);
4760 "ProcessGDBRemote::ParseFlagsFields Invalid end \"{0}\" in "
4764 }
else if (attr_name ==
"type") {
4769 "ProcessGDBRemote::ParseFlagsFields Ignoring unknown attribute "
4770 "\"{0}\" in field node",
4777 if (name && start && end) {
4781 "ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
4782 "\"{2}\", ignoring",
4783 *start, *end, name->data());
4787 "ProcessGDBRemote::ParseFlagsFields Ignoring field \"{}\" "
4788 "that has size > 64 bits, this is not supported",
4792 const FieldEnum *enum_type =
nullptr;
4793 if (type && !type->empty()) {
4794 auto found = registers_enum_types.find(*type);
4795 if (found != registers_enum_types.end()) {
4796 enum_type = found->second.get();
4799 uint64_t max_value =
4802 if (enumerator.m_value > max_value) {
4803 enum_type =
nullptr;
4806 "ProcessGDBRemote::ParseFlagsFields In enum \"{0}\" "
4807 "evalue \"{1}\" with value {2} exceeds the maximum value "
4808 "of field \"{3}\" ({4}), ignoring enum",
4809 type->data(), enumerator.m_name, enumerator.m_value,
4810 name->data(), max_value);
4816 "ProcessGDBRemote::ParseFlagsFields Could not find type "
4818 "for field \"{1}\", ignoring",
4819 type->data(), name->data());
4824 RegisterFlags::Field(name->str(), *start, *end, enum_type));
4835 XMLNode feature_node,
4836 llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4837 const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4838 Log *log(
GetLog(GDBRLog::Process));
4842 [&log, ®isters_flags_types,
4843 ®isters_enum_types](
const XMLNode &flags_node) ->
bool {
4844 LLDB_LOG(log,
"ProcessGDBRemote::ParseFlags Found flags node \"{0}\"",
4847 std::optional<llvm::StringRef>
id;
4848 std::optional<unsigned> size;
4850 [&
id, &size, &log](
const llvm::StringRef &name,
4851 const llvm::StringRef &value) {
4854 }
else if (name ==
"size") {
4855 unsigned parsed_size = 0;
4856 if (llvm::to_integer(value, parsed_size))
4860 "ProcessGDBRemote::ParseFlags Invalid size \"{0}\" "
4866 "ProcessGDBRemote::ParseFlags Ignoring unknown "
4867 "attribute \"{0}\" in flags node",
4875 std::vector<RegisterFlags::Field> fields =
4876 ParseFlagsFields(flags_node, *size, registers_enum_types);
4877 if (fields.size()) {
4879 std::sort(fields.rbegin(), fields.rend());
4880 std::vector<RegisterFlags::Field>::const_iterator overlap =
4881 std::adjacent_find(fields.begin(), fields.end(),
4882 [](
const RegisterFlags::Field &lhs,
4883 const RegisterFlags::Field &rhs) {
4884 return lhs.Overlaps(rhs);
4888 if (overlap == fields.end()) {
4889 if (registers_flags_types.contains(*
id)) {
4903 "ProcessGDBRemote::ParseFlags Definition of flags "
4905 "previous definition, using original definition instead.",
4908 registers_flags_types.insert_or_assign(
4909 *
id, std::make_unique<RegisterFlags>(
id->str(), *size,
4910 std::move(fields)));
4914 std::vector<RegisterFlags::Field>::const_iterator next =
4918 "ProcessGDBRemote::ParseFlags Ignoring flags because fields "
4919 "{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) "
4921 overlap->GetName().c_str(), overlap->GetStart(),
4922 overlap->GetEnd(), next->GetName().c_str(), next->GetStart(),
4928 "ProcessGDBRemote::ParseFlags Ignoring definition of flags "
4929 "\"{0}\" because it contains no fields.",
4939 XMLNode feature_node, GdbServerTargetInfo &target_info,
4940 std::vector<DynamicRegisterInfo::Register> ®isters,
4941 llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4942 llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4946 Log *log(
GetLog(GDBRLog::Process));
4949 ParseEnums(feature_node, registers_enum_types);
4950 for (
const auto &enum_type : registers_enum_types)
4953 ParseFlags(feature_node, registers_flags_types, registers_enum_types);
4954 for (
const auto &flags : registers_flags_types)
4955 flags.second->DumpToLog(log);
4959 [&target_info, ®isters, ®isters_flags_types,
4960 log](
const XMLNode ®_node) ->
bool {
4961 std::string gdb_group;
4962 std::string gdb_type;
4963 DynamicRegisterInfo::Register reg_info;
4964 bool encoding_set =
false;
4965 bool format_set =
false;
4969 &encoding_set, &format_set, ®_info,
4970 log](
const llvm::StringRef &name,
4971 const llvm::StringRef &value) ->
bool {
4972 if (name ==
"name") {
4974 }
else if (name ==
"bitsize") {
4975 if (llvm::to_integer(value, reg_info.
byte_size))
4977 llvm::divideCeil(reg_info.
byte_size, CHAR_BIT);
4978 }
else if (name ==
"type") {
4979 gdb_type = value.str();
4980 }
else if (name ==
"group") {
4981 gdb_group = value.str();
4982 }
else if (name ==
"regnum") {
4984 }
else if (name ==
"offset") {
4986 }
else if (name ==
"altname") {
4988 }
else if (name ==
"encoding") {
4989 encoding_set =
true;
4991 }
else if (name ==
"format") {
4997 llvm::StringSwitch<lldb::Format>(value)
5008 }
else if (name ==
"group_id") {
5010 llvm::to_integer(value, set_id);
5011 RegisterSetMap::const_iterator pos =
5012 target_info.reg_set_map.find(set_id);
5013 if (pos != target_info.reg_set_map.end())
5014 reg_info.
set_name = pos->second.name;
5015 }
else if (name ==
"gcc_regnum" || name ==
"ehframe_regnum") {
5017 }
else if (name ==
"dwarf_regnum") {
5019 }
else if (name ==
"generic") {
5021 }
else if (name ==
"value_regnums") {
5024 }
else if (name ==
"invalidate_regnums") {
5029 "ProcessGDBRemote::ParseRegisters unhandled reg "
5030 "attribute %s = %s",
5031 name.data(), value.data());
5036 if (!gdb_type.empty()) {
5038 llvm::StringMap<std::unique_ptr<RegisterFlags>>::iterator it =
5039 registers_flags_types.find(gdb_type);
5040 if (it != registers_flags_types.end()) {
5041 auto flags_type = it->second.get();
5042 if (reg_info.
byte_size == flags_type->GetSize())
5047 "ProcessGDBRemote::ParseRegisters Size of register flags {0} "
5048 "({1} bytes) for register {2} does not match the register "
5049 "size ({3} bytes). Ignoring this set of flags.",
5050 flags_type->GetID().c_str(), flags_type->GetSize(),
5057 if (!gdb_type.empty() && !(encoding_set || format_set)) {
5058 if (llvm::StringRef(gdb_type).starts_with(
"int")) {
5061 }
else if (gdb_type ==
"data_ptr" || gdb_type ==
"code_ptr") {
5064 }
else if (gdb_type ==
"float" || gdb_type ==
"ieee_single" ||
5065 gdb_type ==
"ieee_double") {
5068 }
else if (gdb_type ==
"aarch64v" ||
5069 llvm::StringRef(gdb_type).starts_with(
"vec") ||
5070 gdb_type ==
"i387_ext" || gdb_type ==
"uint128" ||
5083 "ProcessGDBRemote::ParseRegisters Could not determine lldb"
5084 "format and encoding for gdb type %s",
5094 if (!gdb_group.empty()) {
5105 "ProcessGDBRemote::{0} Skipping zero bitsize register {1}",
5106 __FUNCTION__, reg_info.
name);
5108 registers.push_back(reg_info);
5123 ArchSpec &arch_to_use, std::string xml_filename,
5124 std::vector<DynamicRegisterInfo::Register> ®isters) {
5126 llvm::Expected<std::string> raw =
m_gdb_comm.ReadExtFeature(
"features", xml_filename);
5127 if (errorToBool(raw.takeError()))
5132 if (xml_document.
ParseMemory(raw->c_str(), raw->size(),
5133 xml_filename.c_str())) {
5134 GdbServerTargetInfo target_info;
5135 std::vector<XMLNode> feature_nodes;
5141 const XMLNode &node) ->
bool {
5142 llvm::StringRef name = node.
GetName();
5143 if (name ==
"architecture") {
5145 }
else if (name ==
"osabi") {
5147 }
else if (name ==
"xi:include" || name ==
"include") {
5150 target_info.includes.push_back(href);
5151 }
else if (name ==
"feature") {
5152 feature_nodes.push_back(node);
5153 }
else if (name ==
"groups") {
5155 "group", [&target_info](
const XMLNode &node) ->
bool {
5157 RegisterSetInfo set_info;
5160 [&set_id, &set_info](
const llvm::StringRef &name,
5161 const llvm::StringRef &value) ->
bool {
5164 llvm::to_integer(value, set_id);
5171 target_info.reg_set_map[set_id] = set_info;
5184 feature_nodes.push_back(feature_node);
5186 const XMLNode &node) ->
bool {
5187 llvm::StringRef name = node.
GetName();
5188 if (name ==
"xi:include" || name ==
"include") {
5191 target_info.includes.push_back(href);
5205 if (!arch_to_use.
IsValid() && !target_info.arch.empty()) {
5207 arch_to_use.
SetTriple(llvm::StringSwitch<std::string>(target_info.arch)
5208 .Case(
"i386:x86-64",
"x86_64")
5209 .Case(
"riscv:rv64",
"riscv64")
5210 .Case(
"riscv:rv32",
"riscv32")
5211 .Default(target_info.arch) +
5219 for (
auto &feature_node : feature_nodes) {
5220 ParseRegisters(feature_node, target_info, registers,
5224 for (
const auto &include : target_info.includes) {
5236 std::vector<DynamicRegisterInfo::Register> ®isters,
5238 std::map<uint32_t, uint32_t> remote_to_local_map;
5239 uint32_t remote_regnum = 0;
5240 for (
auto it : llvm::enumerate(registers)) {
5248 remote_to_local_map[remote_reg_info.
regnum_remote] = it.index();
5254 auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) {
5255 auto lldb_regit = remote_to_local_map.find(process_regnum);
5256 return lldb_regit != remote_to_local_map.end() ? lldb_regit->second
5260 llvm::transform(remote_reg_info.value_regs,
5261 remote_reg_info.value_regs.begin(), proc_to_lldb);
5262 llvm::transform(remote_reg_info.invalidate_regs,
5263 remote_reg_info.invalidate_regs.begin(), proc_to_lldb);
5270 abi_sp->AugmentRegisterInfo(registers);
5280 if (!
m_gdb_comm.GetQXferFeaturesReadSupported())
5281 return llvm::createStringError(
5282 llvm::inconvertibleErrorCode(),
5283 "the debug server does not support \"qXfer:features:read\"");
5286 return llvm::createStringError(
5287 llvm::inconvertibleErrorCode(),
5288 "the debug server supports \"qXfer:features:read\", but LLDB does not "
5289 "have XML parsing enabled (check LLLDB_ENABLE_LIBXML2)");
5299 std::vector<DynamicRegisterInfo::Register> registers;
5307 ? llvm::ErrorSuccess()
5308 : llvm::createStringError(
5309 llvm::inconvertibleErrorCode(),
5310 "the debug server did not describe any registers");
5316 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5317 "XML parsing not available");
5320 LLDB_LOGF(log,
"ProcessGDBRemote::%s", __FUNCTION__);
5329 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries-svr4",
"");
5331 return raw.takeError();
5334 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5337 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5338 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5339 "Error reading noname.xml");
5343 return llvm::createStringError(
5344 llvm::inconvertibleErrorCode(),
5345 "Error finding library-list-svr4 xml element");
5350 if (!main_lm.empty())
5354 "library", [log, &list](
const XMLNode &library) ->
bool {
5359 [&module](
const llvm::StringRef &name,
5360 const llvm::StringRef &value) ->
bool {
5363 module.set_name(value.str());
5364 else if (name ==
"lm") {
5366 llvm::to_integer(value, uint_value);
5367 module.set_link_map(uint_value);
5368 }
else if (name ==
"l_addr") {
5371 llvm::to_integer(value, uint_value);
5372 module.set_base(uint_value);
5375 module.set_base_is_offset(true);
5376 }
else if (name ==
"l_ld") {
5378 llvm::to_integer(value, uint_value);
5379 module.set_dynamic(uint_value);
5388 bool base_is_offset;
5390 module.get_name(name);
5391 module.get_link_map(lm);
5392 module.get_base(base);
5393 module.get_base_is_offset(base_is_offset);
5394 module.get_dynamic(ld);
5397 "found (link_map:0x%08" PRIx64
", base:0x%08" PRIx64
5398 "[%s], ld:0x%08" PRIx64
", name:'%s')",
5399 lm, base, (base_is_offset ?
"offset" :
"absolute"), ld,
5408 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5409 (
int)list.
m_list.size());
5413 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries",
"");
5416 return raw.takeError();
5418 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5421 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5422 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5423 "Error reading noname.xml");
5427 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5428 "Error finding library-list xml element");
5432 "library", [log, &list](
const XMLNode &library) ->
bool {
5436 module.set_name(name);
5445 llvm::to_integer(address, address_value);
5446 module.set_base(address_value);
5448 module.set_base_is_offset(false);
5453 bool base_is_offset;
5454 module.get_name(name);
5455 module.get_base(base);
5456 module.get_base_is_offset(base_is_offset);
5458 LLDB_LOGF(log,
"found (base:0x%08" PRIx64
"[%s], name:'%s')", base,
5459 (base_is_offset ?
"offset" :
"absolute"), name.c_str());
5467 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5468 (
int)list.
m_list.size());
5471 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5472 "Remote libraries not supported");
5479 bool value_is_offset) {
5494 return module_list.takeError();
5500 std::string mod_name;
5503 bool mod_base_is_offset;
5506 valid &= modInfo.
get_name(mod_name);
5507 valid &= modInfo.
get_base(mod_base);
5520 if (module_sp.get())
5521 new_modules.
Append(module_sp);
5524 if (new_modules.
GetSize() > 0) {
5529 for (
size_t i = 0; i < loaded_modules.
GetSize(); ++i) {
5533 for (
size_t j = 0; j < new_modules.
GetSize(); ++j) {
5542 removed_modules.
Append(loaded_module);
5546 loaded_modules.
Remove(removed_modules);
5547 m_process->GetTarget().ModulesDidUnload(removed_modules,
false);
5566 m_process->GetTarget().ModulesDidLoad(new_modules);
5569 return llvm::ErrorSuccess();
5578 std::string file_path = file.
GetPath(
false);
5579 if (file_path.empty())
5600 "Fetching file load address from remote server returned an error");
5610 "Unknown error happened during sending the load address packet");
5631 std::string input = data.str();
5638 size_t found, pos = 0, len = input.length();
5639 while ((found = input.find(
end_delimiter, pos)) != std::string::npos) {
5641 input.substr(pos, found).c_str());
5642 std::string profile_data =
5657 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
5659 llvm::raw_string_ostream output_stream(output);
5660 llvm::StringRef name, value;
5664 if (name.compare(
"thread_used_id") == 0) {
5666 uint64_t thread_id = threadIDHexExtractor.
GetHexMaxU64(
false, 0);
5668 bool has_used_usec =
false;
5669 uint32_t curr_used_usec = 0;
5670 llvm::StringRef usec_name, usec_value;
5671 uint32_t input_file_pos = profileDataExtractor.
GetFilePos();
5673 if (usec_name ==
"thread_used_usec") {
5674 has_used_usec =
true;
5675 usec_value.getAsInteger(0, curr_used_usec);
5679 profileDataExtractor.
SetFilePos(input_file_pos);
5683 if (has_used_usec) {
5684 uint32_t prev_used_usec = 0;
5685 std::map<uint64_t, uint32_t>::iterator iterator =
5688 prev_used_usec = iterator->second;
5690 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
5692 bool good_first_time =
5693 (prev_used_usec == 0) && (real_used_usec > 250000);
5694 bool good_subsequent_time =
5695 (prev_used_usec > 0) &&
5698 if (good_first_time || good_subsequent_time) {
5702 output_stream << name <<
":";
5704 output_stream << index_id <<
";";
5706 output_stream << usec_name <<
":" << usec_value <<
";";
5709 llvm::StringRef local_name, local_value;
5715 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
5718 output_stream << name <<
":" << value <<
";";
5721 output_stream << name <<
":" << value <<
";";
5756 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5757 "qSaveCore returned an error");
5762 for (
auto x : llvm::split(response.
GetStringRef(),
';')) {
5763 if (x.consume_front(
"core-path:"))
5769 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5770 "qSaveCore returned no core path");
5773 FileSpec remote_core{llvm::StringRef(path)};
5779 platform.
Unlink(remote_core);
5781 return error.ToError();
5787 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5788 "Unable to send qSaveCore");
5800 "GDBRemoteCommunicationClientBase::%s() received $J packet "
5801 "but was not a StructuredData packet: packet starts with "
5813 json_sp->Dump(json_str,
true);
5816 "ProcessGDBRemote::%s() "
5817 "received Async StructuredData packet: %s",
5818 __FUNCTION__, json_str.
GetData());
5821 "ProcessGDBRemote::%s"
5822 "() received StructuredData packet:"
5832 if (structured_data_sp)
5840 "Tests packet speeds of various sizes to determine "
5841 "the performance characteristics of the GDB remote "
5846 "The number of packets to send of each varying size "
5847 "(default is 1000).",
5850 "The maximum number of bytes to send in a packet. Sizes "
5851 "increase in powers of 2 while the size is less than or "
5852 "equal to this option value. (default 1024).",
5855 "The maximum number of bytes to receive in a packet. Sizes "
5856 "increase in powers of 2 while the size is less than or "
5857 "equal to this option value. (default 1024).",
5860 "Print the output as JSON data for easy parsing.", false, true) {
5880 if (!output_stream_sp)
5881 output_stream_sp =
m_interpreter.GetDebugger().GetAsyncOutputStream();
5884 const uint32_t num_packets =
5886 const uint64_t max_send =
m_max_send.GetOptionValue().GetCurrentValue();
5887 const uint64_t max_recv =
m_max_recv.GetOptionValue().GetCurrentValue();
5888 const bool json =
m_json.GetOptionValue().GetCurrentValue();
5889 const uint64_t k_recv_amount =
5892 num_packets, max_send, max_recv, k_recv_amount, json,
5917 "Dumps the packet history buffer. ", nullptr) {}
5938 interpreter,
"process plugin packet xfer-size",
5939 "Maximum size that lldb will try to read/write one one chunk.",
5950 "amount to be transferred when "
5961 uint64_t user_specified_max = strtoul(packet_size,
nullptr, 10);
5962 if (errno == 0 && user_specified_max != 0) {
5977 "Send a custom packet through the GDB remote "
5978 "protocol and print the answer. "
5979 "The packet header and footer will automatically "
5980 "be added to the packet prior to sending and "
5981 "stripped from the result.",
5992 "'%s' takes a one or more packet content arguments",
6000 for (
size_t i = 0; i < argc; ++i) {
6007 output_strm.
Printf(
" packet: %s\n", packet_cstr);
6008 std::string response_str = std::string(response.
GetStringRef());
6010 if (strstr(packet_cstr,
"qGetProfileData") !=
nullptr) {
6014 if (response_str.empty())
6015 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6028 "Send a qRcmd packet through the GDB remote protocol "
6029 "and print the response. "
6030 "The argument passed to this command will be hex "
6031 "encoded into a valid 'qRcmd' packet, sent and the "
6032 "response will be printed.") {}
6038 if (command.empty()) {
6055 [&output_strm](llvm::StringRef output) { output_strm << output; });
6058 const std::string &response_str = std::string(response.
GetStringRef());
6060 if (response_str.empty())
6061 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6073 "Commands that deal with GDB remote packets.",
6102 interpreter,
"process plugin",
6103 "Commands for operating on a ProcessGDBRemote process.",
6104 "process plugin <subcommand> [<subcommand-options>]") {
6115 m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(
6116 GetTarget().GetDebugger().GetCommandInterpreter());
6121 bool enable,
bool is_expression_fork) {
6127 if (!enable && is_expression_fork) {
6128 if (
auto entry =
GetTarget().GetEntryPointAddress())
6129 entry_addr = entry->GetOpcodeLoadAddress(&
GetTarget());
6143 "DidForkSwitchSoftwareBreakpoints: retaining expression-"
6144 "return trap at {0:x} in forked child",
6168 addr_t addr = wp_res_sp->GetLoadAddress();
6169 size_t size = wp_res_sp->GetByteSize();
6171 m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,
6177 bool is_expression_fork) {
6186 bool overrode_follow_mode =
false;
6189 if (is_expression_fork) {
6190 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6191 "to parent during expression evaluation");
6193 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6194 "to parent during expression evaluation. Child process "
6195 "{0} is available for manual attachment.",
6199 overrode_follow_mode =
true;
6210 switch (follow_fork_mode) {
6212 follow_pid = parent_pid;
6213 follow_tid = parent_tid;
6214 detach_pid = child_pid;
6215 detach_tid = child_tid;
6218 follow_pid = child_pid;
6219 follow_tid = child_tid;
6220 detach_pid = parent_pid;
6221 detach_tid = parent_tid;
6226 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6227 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to set pid/tid");
6241 if (!
m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) ||
6242 !
m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) {
6243 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to reset pid/tid");
6247 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6250 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6252 if (
error.Fail() && keep_stopped) {
6253 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach-and-stay-stopped not "
6254 "supported, falling back to normal detach");
6255 keep_stopped =
false;
6259 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach packet send failed: {0}",
6260 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6266 if (overrode_follow_mode && !is_expression_fork) {
6270 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
6271 "'parent' because an expression is being evaluated.\n"
6272 "Child process %" PRIu64
6273 " has been detached%s.\n"
6274 "You can attach to it with: process attach -p %" PRIu64
6277 keep_stopped ?
" and stopped" :
" (running)",
6293 bool is_expression_fork) {
6298 "ProcessGDBRemote::DidVFork() called for child_pid: {0}, child_tid {1}",
6299 child_pid, child_tid);
6305 bool overrode_follow_mode =
false;
6308 if (is_expression_fork) {
6309 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6310 "to parent during expression evaluation");
6312 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6313 "to parent during expression evaluation. Child process "
6314 "{0} is available for manual attachment.",
6318 overrode_follow_mode =
true;
6328 switch (follow_fork_mode) {
6330 detach_pid = child_pid;
6331 detach_tid = child_tid;
6334 detach_pid =
m_gdb_comm.GetCurrentProcessID();
6340 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6341 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to set pid/tid");
6349 if (!
m_gdb_comm.SetCurrentThread(child_tid, child_pid) ||
6350 !
m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) {
6351 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to reset pid/tid");
6357 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6358 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6360 if (
error.Fail() && keep_stopped) {
6361 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() detach-and-stay-stopped not "
6362 "supported, falling back to normal detach");
6363 keep_stopped =
false;
6368 "ProcessGDBRemote::DidVFork() detach packet send failed: {0}",
6369 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6373 if (overrode_follow_mode && !is_expression_fork) {
6377 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
6378 "'parent' because an expression is being evaluated.\n"
6379 "Child process %" PRIu64
6380 " has been detached%s.\n"
6381 "You can attach to it with: process attach -p %" PRIu64
6384 keep_stopped ?
" and stopped" :
" (running)",
6417 llvm::Error joined = llvm::Error::success();
6418 for (
auto &[site, action] : site_to_action) {
6422 joined = llvm::joinErrors(std::move(joined), std::move(
error));
6430static llvm::SmallVector<std::optional<uint8_t>>
6432 llvm::SmallVector<std::optional<uint8_t>> results;
6436 parsed ? parsed->GetAsDictionary() :
nullptr;
6444 llvm::StringRef token;
6445 if (
auto *
string = object->GetAsString())
6446 token =
string->GetValue();
6447 if (token ==
"OK") {
6448 results.push_back(std::nullopt);
6451 if (token.size() != 3 || !token.starts_with(
"E")) {
6452 results.push_back(uint8_t(0xff));
6455 uint8_t error_code = 0;
6456 if (token.drop_front(1).getAsInteger(16, error_code))
6457 results.push_back(0xff);
6459 results.push_back(error_code);
6468static std::optional<GDBStoppointType>
6477 return std::nullopt;
6486 return std::nullopt;
6488 llvm_unreachable(
"unhandled BreakpointSite type");
6492struct BreakpointPacketInfo {
6493 BreakpointSite &site;
6494 size_t trap_opcode_size;
6499std::string to_string(
const BreakpointPacketInfo &info) {
6500 char packet = info.is_enable ?
'Z' :
'z';
6501 return llvm::formatv(
"{0}{1},{2:x-},{3:x-}", packet,
6503 info.trap_opcode_size)
6510 if (site_to_action.empty())
6511 return llvm::Error::success();
6512 if (!
m_gdb_comm.GetMultiBreakpointSupported())
6517 std::vector<BreakpointPacketInfo> breakpoint_infos;
6518 for (
auto [site, action] : site_to_action) {
6520 std::optional<GDBStoppointType> type =
6524 LLDB_LOG(log,
"MultiBreakpoint: site {0} at {1:x} can't be batched",
6525 site->GetID(), site->GetLoadAddress());
6529 breakpoint_infos.push_back(
6534 stream <<
"jMultiBreakpoint:";
6536 auto args_array = std::make_shared<StructuredData::Array>();
6537 for (
auto &bp_info : breakpoint_infos)
6538 args_array->AddStringItem(to_string(bp_info));
6541 packet_dict.
AddItem(
"breakpoint_requests", args_array);
6542 packet_dict.
Dump(stream,
false);
6546 llvm::Expected<StringExtractorGDBRemote> response =
6551 LLDB_LOG_ERROR(log, response.takeError(),
"jMultiBreakpoint failed: {0}");
6555 llvm::SmallVector<std::optional<uint8_t>> results =
6559 if (results.size() != breakpoint_infos.size())
6560 return llvm::createStringErrorV(
6561 "MultiBreakpoint response count mismatch (expected {0}, got {1})",
6562 site_to_action.size(), results.size());
6564 llvm::Error joined = llvm::Error::success();
6565 for (
auto [error_code, bp_info] :
6566 llvm::zip_equal(results, breakpoint_infos)) {
6569 auto error = llvm::createStringErrorV(
6570 "MultiBreakpoint: site {0} at {1:x} failed with E{2}",
6571 bp_info.site.GetID(), bp_info.site.GetLoadAddress(), error_code);
6572 joined = llvm::joinErrors(std::move(joined), std::move(
error));
6576 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)
virtual llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buffer)
Reads each range individually via ReadMemoryFromInferior, bypassing the memory cache.
void ResumePrivateStateThread()
void MapSupportedStructuredDataPlugins(const StructuredData::Array &supported_type_names)
Loads any plugins associated with asynchronous structured data and maps the relevant supported type n...
std::map< lldb::BreakpointSiteSP, BreakpointAction, SiteIDCmp > BreakpointSiteToActionMap
virtual SystemRuntime * GetSystemRuntime()
Get the system runtime plug-in for this process.
std::map< uint64_t, uint32_t > m_thread_id_to_index_id_map
lldb::StateType GetPrivateState() const
void SetBreakpointSiteEnabled(BreakpointSite &site, bool is_enabled=true)
lldb::DynamicLoaderUP m_dyld_up
virtual Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries)
StopPointSiteList< lldb_private::WatchpointResource > m_watchpoint_resource_list
Watchpoint resources currently in use.
bool IsBreakpointSitePhysicallyEnabled(const BreakpointSite &site)
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.
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
llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buf) override
Override of DoReadMemoryRanges that uses MultiMemRead to perform this operation in a single packet.
friend class ThreadGDBRemote
DataExtractor GetAuxvData() override
GDBRemoteCommunicationClient & GetGDBRemote()
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
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
static std::chrono::milliseconds GetPacketTestDelay()
llvm::Error LoadModules() override
Sometimes processes know how to retrieve and load shared libraries.
uint64_t m_max_memory_size
void HandleAsyncMisc(llvm::StringRef data) override
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path, bool can_connect)
void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple) override
llvm::VersionTuple GetHostMacCatalystVersion() override
void DidForkSwitchHardwareTraps(bool enable)
HostThread m_async_thread
StructuredData::ObjectSP GetDynamicLoaderProcessState() override
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override
Try to fetch the module specification for a module with the given file name and architecture.
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)
void PrivateSetRegisterUnavailable(uint32_t reg)
lldb::RegisterContextSP GetRegisterContext() override
void SetDetailedBinariesInfo(StructuredData::ObjectSP &detailed_info)
void SetAssociatedWithLibdispatchQueue(lldb_private::LazyBool associated_with_libdispatch_queue) override
bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef< uint8_t > data)
#define LLDB_INVALID_SITE_ID
#define LLDB_INVALID_WATCH_ID
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_THREAD_ID
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_INVALID_PROCESS_ID
#define LLDB_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