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);
152 ~PluginProperties()
override =
default;
154 uint64_t GetPacketTimeout() {
155 const uint32_t idx = ePropertyPacketTimeout;
156 return GetPropertyAtIndexAs<uint64_t>(
157 idx, g_processgdbremote_properties[idx].default_uint_value);
160 bool SetPacketTimeout(uint64_t timeout) {
161 const uint32_t idx = ePropertyPacketTimeout;
162 return SetPropertyAtIndex(idx, timeout);
165 FileSpec GetTargetDefinitionFile()
const {
166 const uint32_t idx = ePropertyTargetDefinitionFile;
167 return GetPropertyAtIndexAs<FileSpec>(idx, {});
170 bool GetUseSVR4()
const {
171 const uint32_t idx = ePropertyUseSVR4;
172 return GetPropertyAtIndexAs<bool>(
173 idx, g_processgdbremote_properties[idx].default_uint_value != 0);
176 bool GetUseGPacketForReading()
const {
177 const uint32_t idx = ePropertyUseGPacketForReading;
178 return GetPropertyAtIndexAs<bool>(idx,
true);
182std::chrono::seconds ResumeTimeout() {
return std::chrono::seconds(5); }
187 static PluginProperties g_settings;
195#if defined(__APPLE__)
196#define LOW_PORT (IPPORT_RESERVED)
197#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
199#define LOW_PORT (1024u)
200#define HIGH_PORT (49151u)
204 return "GDB Remote protocol based debugging plug-in.";
213 const FileSpec *crash_file_path,
bool can_connect) {
233 bool plugin_specified_by_name) {
234 if (plugin_specified_by_name)
238 Module *exe_module = target_sp->GetExecutableModulePointer();
242 switch (exe_objfile->
GetType()) {
266 :
Process(target_sp, listener_sp),
270 Listener::MakeListener(
"lldb.process.gdb-remote.async-listener")),
280 "async thread should exit");
282 "async thread continue");
284 "async thread did exit");
288 const uint32_t async_event_mask =
294 "ProcessGDBRemote::%s failed to listen for "
295 "m_async_broadcaster events",
299 const uint64_t timeout_seconds =
301 if (timeout_seconds > 0)
302 m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
326std::shared_ptr<ThreadGDBRemote>
328 return std::make_shared<ThreadGDBRemote>(*
this, tid);
332 const FileSpec &target_definition_fspec) {
338 if (module_object_sp) {
341 "gdb-server-target-definition",
error));
343 if (target_definition_sp) {
345 target_definition_sp->GetValueForKey(
"host-info"));
347 if (
auto host_info_dict = target_object->GetAsDictionary()) {
349 host_info_dict->GetValueForKey(
"triple");
350 if (
auto triple_string_value = triple_value->GetAsString()) {
351 std::string triple_string =
352 std::string(triple_string_value->GetValue());
353 ArchSpec host_arch(triple_string.c_str());
362 target_definition_sp->GetValueForKey(
"breakpoint-pc-offset");
363 if (breakpoint_pc_offset_value) {
364 if (
auto breakpoint_pc_int_value =
365 breakpoint_pc_offset_value->GetAsSignedInteger())
370 *target_definition_sp,
GetTarget().GetArchitecture()) > 0) {
379 const llvm::StringRef &comma_separated_register_numbers,
380 std::vector<uint32_t> ®nums,
int base) {
382 for (llvm::StringRef x : llvm::split(comma_separated_register_numbers,
',')) {
384 if (llvm::to_integer(x, reg, base))
385 regnums.push_back(reg);
387 return regnums.size();
399 const auto host_packet_timeout =
m_gdb_comm.GetHostDefaultPacketTimeout();
400 if (host_packet_timeout > std::chrono::seconds(0)) {
418 if (target_definition_fspec) {
424 target_definition_fspec.
GetPath() +
435 if (remote_process_arch.
IsValid())
436 arch_to_use = remote_process_arch;
438 arch_to_use = remote_host_arch;
441 arch_to_use = target_arch;
444 if (!register_info_err) {
451 "Failed to read register information from target XML: {0}");
452 LLDB_LOG(log,
"Now trying to use qRegisterInfo instead.");
455 std::vector<DynamicRegisterInfo::Register> registers;
456 uint32_t reg_num = 0;
460 const int packet_len =
461 ::snprintf(packet,
sizeof(packet),
"qRegisterInfo%x", reg_num);
462 assert(packet_len < (
int)
sizeof(packet));
465 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
469 llvm::StringRef name;
470 llvm::StringRef value;
474 if (name ==
"name") {
476 }
else if (name ==
"alt-name") {
478 }
else if (name ==
"bitsize") {
479 if (!value.getAsInteger(0, reg_info.
byte_size))
481 }
else if (name ==
"offset") {
483 }
else if (name ==
"encoding") {
487 }
else if (name ==
"format") {
491 llvm::StringSwitch<Format>(value)
533 }
else if (name ==
"set") {
535 }
else if (name ==
"gcc" || name ==
"ehframe") {
537 }
else if (name ==
"dwarf") {
539 }
else if (name ==
"generic") {
541 }
else if (name ==
"container-regs") {
543 }
else if (name ==
"invalidate-regs") {
549 registers.push_back(reg_info);
562 "the debug server supports Target Description XML but LLDB does "
563 "not have XML parsing enabled. Using \"qRegisterInfo\" was also "
564 "not possible. Register information may be incorrect or missing.",
574 if (registers.empty()) {
576 if (!registers.empty())
579 "All other methods failed, using fallback register information.");
594 bool wait_for_launch) {
626 if (
m_gdb_comm.GetProcessArchitecture().IsValid()) {
629 if (
m_gdb_comm.GetHostArchitecture().IsValid()) {
640 "Process %" PRIu64
" was reported after connecting to "
641 "'%s', but state was not stopped: %s",
645 "Process %" PRIu64
" was reported after connecting to '%s', "
646 "but no stop reply packet was received",
647 pid, remote_url.str().c_str());
651 "ProcessGDBRemote::%s pid %" PRIu64
652 ": normalizing target architecture initial triple: %s "
653 "(GetTarget().GetArchitecture().IsValid() %s, "
654 "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
655 __FUNCTION__,
GetID(),
656 GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
658 m_gdb_comm.GetHostArchitecture().IsValid() ?
"true" :
"false");
664 if (
m_gdb_comm.GetProcessArchitecture().IsValid())
671 "ProcessGDBRemote::%s pid %" PRIu64
672 ": normalized target architecture triple: %s",
673 __FUNCTION__,
GetID(),
674 GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
691 LLDB_LOGF(log,
"ProcessGDBRemote::%s() entered", __FUNCTION__);
693 uint32_t launch_flags = launch_info.
GetFlags().
Get();
717 if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
719 "ProcessGDBRemote::%s provided with STDIO paths via "
720 "launch_info: stdin=%s, stdout=%s, stderr=%s",
722 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
723 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
724 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
727 "ProcessGDBRemote::%s no STDIO paths given via launch_info",
731 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
732 if (stdin_file_spec || disable_stdio) {
747 if (
error.Success()) {
749 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
754 if (!stdin_file_spec)
756 FileSpec::Style::native);
757 if (!stdout_file_spec)
759 FileSpec::Style::native);
760 if (!stderr_file_spec)
762 FileSpec::Style::native);
763 }
else if (platform_sp && platform_sp->IsHost()) {
768 if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
772 if (!stdin_file_spec)
773 stdin_file_spec = secondary_name;
775 if (!stdout_file_spec)
776 stdout_file_spec = secondary_name;
778 if (!stderr_file_spec)
779 stderr_file_spec = secondary_name;
783 "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
784 "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
787 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
788 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
789 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
793 "ProcessGDBRemote::%s final STDIO paths after all "
794 "adjustments: stdin=%s, stdout=%s, stderr=%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 if (stdout_file_spec)
804 if (stderr_file_spec)
807 m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
808 m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
811 GetTarget().GetArchitecture().GetArchitectureName());
814 if (launch_event_data !=
nullptr && *launch_event_data !=
'\0')
815 m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
827 std::chrono::seconds(10));
834 if (llvm::Error err =
m_gdb_comm.LaunchProcess(args)) {
837 llvm::fmt_consume(std::move(err)));
844 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
866 if (!disable_stdio) {
872 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
error.AsCString());
882 if (!connect_url.empty()) {
883 LLDB_LOGF(log,
"ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
884 connect_url.str().c_str());
885 std::unique_ptr<ConnectionFileDescriptor> conn_up(
888 const uint32_t max_retry_count = 50;
889 uint32_t retry_count = 0;
898 if (retry_count >= max_retry_count)
901 std::this_thread::sleep_for(std::chrono::milliseconds(100));
925 m_gdb_comm.GetListThreadsInStopReplySupported();
932 auto handle_cmds = [&] (
const Args &args) ->
void {
936 entry.c_str(), response);
942 handle_cmds(platform_sp->GetExtraStartupCommands());
959 if (remote_process_arch.
IsValid()) {
960 process_arch = remote_process_arch;
961 LLDB_LOG(log,
"gdb-remote had process architecture, using {0} {1}",
965 process_arch =
m_gdb_comm.GetHostArchitecture();
967 "gdb-remote did not have process architecture, using gdb-remote "
968 "host architecture {0} {1}",
979 LLDB_LOG(log,
"analyzing target arch, currently {0} {1}",
991 if ((process_arch.
GetMachine() == llvm::Triple::arm ||
992 process_arch.
GetMachine() == llvm::Triple::thumb) &&
993 process_arch.
GetTriple().getVendor() == llvm::Triple::Apple) {
996 "remote process is ARM/Apple, "
997 "setting target arch to {0} {1}",
1002 const llvm::Triple &remote_triple = process_arch.
GetTriple();
1003 llvm::Triple new_target_triple = target_arch.
GetTriple();
1004 if (new_target_triple.getVendorName().size() == 0) {
1005 new_target_triple.setVendor(remote_triple.getVendor());
1007 if (new_target_triple.getOSName().size() == 0) {
1008 new_target_triple.setOS(remote_triple.getOS());
1010 if (new_target_triple.getEnvironmentName().size() == 0)
1011 new_target_triple.setEnvironment(remote_triple.getEnvironment());
1014 ArchSpec new_target_arch = target_arch;
1015 new_target_arch.
SetTriple(new_target_triple);
1021 "final target arch after adjustments for remote architecture: "
1040 m_gdb_comm.GetSupportedStructuredDataPlugins())
1049 if (platform_sp && platform_sp->IsConnected())
1061 UUID standalone_uuid;
1063 bool standalone_value_is_offset;
1064 if (
m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value,
1065 standalone_value_is_offset)) {
1068 if (standalone_uuid.
IsValid()) {
1069 const bool force_symbol_search =
true;
1070 const bool notify =
true;
1071 const bool set_address_in_target =
true;
1072 const bool allow_memory_image_last_resort =
false;
1074 this,
"", standalone_uuid, standalone_value,
1075 standalone_value_is_offset, force_symbol_search, notify,
1076 set_address_in_target, allow_memory_image_last_resort);
1088 std::vector<addr_t> bin_addrs =
m_gdb_comm.GetProcessStandaloneBinaries();
1089 if (bin_addrs.size()) {
1091 const bool value_is_slide =
false;
1092 for (
addr_t addr : bin_addrs) {
1093 const bool notify =
true;
1100 .LoadPlatformBinaryAndSetup(
this, addr, notify))
1103 const bool force_symbol_search =
true;
1104 const bool set_address_in_target =
true;
1105 const bool allow_memory_image_last_resort =
false;
1108 this, llvm::StringRef(), uuid, addr, value_is_slide,
1109 force_symbol_search, notify, set_address_in_target,
1110 allow_memory_image_last_resort);
1120 std::optional<QOffsets> offsets =
m_gdb_comm.GetQOffsets();
1125 size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==
1126 offsets->offsets.size();
1130 bool changed =
false;
1131 module_sp->SetLoadAddress(
GetTarget(), offsets->offsets[0],
1136 m_process->GetTarget().ModulesDidLoad(list);
1150 LLDB_LOGF(log,
"ProcessGDBRemote::%s()", __FUNCTION__);
1156 if (
error.Success()) {
1160 const int packet_len =
1161 ::snprintf(packet,
sizeof(packet),
"vAttach;%" PRIx64, attach_pid);
1164 std::make_shared<EventDataBytes>(llvm::StringRef(packet, packet_len));
1179 if (process_name && process_name[0]) {
1181 if (
error.Success()) {
1187 if (!
m_gdb_comm.GetVAttachOrWaitSupported()) {
1202 auto data_sp = std::make_shared<EventDataBytes>(packet.
GetString());
1223llvm::Expected<std::string>
1228llvm::Expected<std::vector<uint8_t>>
1240 process_arch.
Clear();
1255 return m_gdb_comm.GetReverseStepSupported() ||
1262 LLDB_LOGF(log,
"ProcessGDBRemote::Resume(%s)",
1267 if (listener_sp->StartListeningForEvents(
1269 listener_sp->StartListeningForEvents(
1276 bool continue_packet_error =
false;
1290 std::string pid_prefix;
1292 pid_prefix = llvm::formatv(
"p{0:x-}.",
GetID());
1294 if (num_continue_c_tids == num_threads ||
1299 continue_packet.
Format(
"vCont;c:{0}-1", pid_prefix);
1307 for (tid_collection::const_iterator
1310 t_pos != t_end; ++t_pos)
1311 continue_packet.
Format(
";c:{0}{1:x-}", pid_prefix, *t_pos);
1313 continue_packet_error =
true;
1318 for (tid_sig_collection::const_iterator
1321 s_pos != s_end; ++s_pos)
1322 continue_packet.
Format(
";C{0:x-2}:{1}{2:x-}", s_pos->second,
1323 pid_prefix, s_pos->first);
1325 continue_packet_error =
true;
1330 for (tid_collection::const_iterator
1333 t_pos != t_end; ++t_pos)
1334 continue_packet.
Format(
";s:{0}{1:x-}", pid_prefix, *t_pos);
1336 continue_packet_error =
true;
1341 for (tid_sig_collection::const_iterator
1344 s_pos != s_end; ++s_pos)
1345 continue_packet.
Format(
";S{0:x-2}:{1}{2:x-}", s_pos->second,
1346 pid_prefix, s_pos->first);
1348 continue_packet_error =
true;
1351 if (continue_packet_error)
1352 continue_packet.
Clear();
1355 continue_packet_error =
true;
1361 if (num_continue_c_tids > 0) {
1362 if (num_continue_c_tids == num_threads) {
1366 continue_packet_error =
false;
1367 }
else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
1368 num_continue_s_tids == 0 && num_continue_S_tids == 0) {
1372 continue_packet_error =
false;
1376 if (continue_packet_error && num_continue_C_tids > 0) {
1377 if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
1378 num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
1379 num_continue_S_tids == 0) {
1382 if (num_continue_C_tids > 1) {
1387 if (num_continue_C_tids > 1) {
1388 continue_packet_error =
false;
1391 continue_packet_error =
true;
1394 if (!continue_packet_error)
1398 continue_packet_error =
false;
1401 if (!continue_packet_error) {
1403 continue_packet.
Printf(
"C%2.2x", continue_signo);
1408 if (continue_packet_error && num_continue_s_tids > 0) {
1409 if (num_continue_s_tids == num_threads) {
1415 continue_packet_error =
false;
1416 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1417 num_continue_s_tids == 1 && num_continue_S_tids == 0) {
1421 continue_packet_error =
false;
1425 if (!continue_packet_error && num_continue_S_tids > 0) {
1426 if (num_continue_S_tids == num_threads) {
1429 continue_packet_error =
false;
1430 if (num_continue_S_tids > 1) {
1431 for (
size_t i = 1; i < num_threads; ++i) {
1433 continue_packet_error =
true;
1436 if (!continue_packet_error) {
1439 continue_packet.
Printf(
"S%2.2x", step_signo);
1441 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1442 num_continue_s_tids == 0 && num_continue_S_tids == 1) {
1446 continue_packet_error =
false;
1452 if (num_continue_s_tids > 0 || num_continue_S_tids > 0) {
1454 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1455 "support reverse-stepping");
1457 "target does not support reverse-stepping");
1460 if (num_continue_S_tids > 0) {
1463 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1465 "can't deliver signals while running in reverse");
1468 if (num_continue_s_tids > 1) {
1469 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: can't step multiple "
1470 "threads in reverse");
1472 "can't step multiple threads while reverse-stepping");
1478 if (!
m_gdb_comm.GetReverseContinueSupported()) {
1479 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1480 "support reverse-continue");
1482 "target does not support reverse execution of processes");
1485 if (num_continue_C_tids > 0) {
1488 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1490 "can't deliver signals while running in reverse");
1498 continue_packet_error =
false;
1501 if (continue_packet_error) {
1503 "can't make continue packet for this resume");
1508 "Trying to resume but the async thread is dead.");
1509 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Trying to resume but the "
1510 "async thread is dead.");
1515 std::make_shared<EventDataBytes>(continue_packet.
GetString());
1518 if (!listener_sp->GetEvent(event_sp, ResumeTimeout())) {
1520 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Resume timed out.");
1523 "Broadcast continue, but the async thread was "
1524 "killed before we got an ack back.");
1526 "ProcessGDBRemote::DoResume: Broadcast continue, but the "
1527 "async thread was killed before we got an ack back.");
1543 llvm::StringRef value) {
1549 auto pid_tid = thread_ids.
GetPidTid(pid);
1550 if (pid_tid && pid_tid->first == pid) {
1556 }
while (thread_ids.
GetChar() ==
',');
1562 llvm::StringRef value) {
1564 for (llvm::StringRef x : llvm::split(value,
',')) {
1566 if (llvm::to_integer(x,
pc, 16))
1578 if (thread_infos && thread_infos->
GetSize() > 0) {
1602 const llvm::StringRef stop_info_str = stop_info.
GetStringRef();
1605 const size_t thread_pcs_pos = stop_info_str.find(
";thread-pcs:");
1606 if (thread_pcs_pos != llvm::StringRef::npos) {
1607 const size_t start = thread_pcs_pos + strlen(
";thread-pcs:");
1608 const size_t end = stop_info_str.find(
';', start);
1609 if (end != llvm::StringRef::npos) {
1610 llvm::StringRef value = stop_info_str.substr(start, end - start);
1615 const size_t threads_pos = stop_info_str.find(
";threads:");
1616 if (threads_pos != llvm::StringRef::npos) {
1617 const size_t start = threads_pos + strlen(
";threads:");
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);
1628 bool sequence_mutex_unavailable =
false;
1630 if (sequence_mutex_unavailable) {
1645 if (num_thread_ids == 0) {
1651 ThreadList old_thread_list_copy(old_thread_list);
1652 if (num_thread_ids > 0) {
1653 for (
size_t i = 0; i < num_thread_ids; ++i) {
1659 LLDB_LOGV(log,
"Making new thread: {0} for thread ID: {1:x}.",
1660 thread_sp.get(), thread_sp->GetID());
1662 LLDB_LOGV(log,
"Found old thread: {0} for thread ID: {1:x}.",
1663 thread_sp.get(), thread_sp->GetID());
1673 size_t old_num_thread_ids = old_thread_list_copy.
GetSize(
false);
1674 for (
size_t i = 0; i < old_num_thread_ids; i++) {
1676 if (old_thread_sp) {
1677 lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
1692 uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1705 if (thread_infos_sp) {
1709 const size_t n = thread_infos->
GetSize();
1710 for (
size_t i = 0; i < n; ++i) {
1716 if (tid == thread->GetID())
1745 if (
GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
1755 for (
const auto &pair : expedited_register_map) {
1759 reg_value_extractor.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
1760 uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1768 uint8_t signo,
const std::string &thread_name,
const std::string &reason,
1769 const std::string &description, uint32_t exc_type,
1770 const std::vector<addr_t> &exc_data,
addr_t thread_dispatch_qaddr,
1771 bool queue_vars_valid,
1773 LazyBool associated_with_dispatch_queue,
addr_t dispatch_queue_t,
1774 std::string &queue_name,
QueueKind queue_kind, uint64_t queue_serial) {
1798 reg_ctx_sp->InvalidateIfNeeded(
true);
1806 if (reg_ctx_sp->ReconfigureRegisterInfo()) {
1809 reg_ctx_sp->InvalidateAllRegisters();
1816 thread_sp->SetName(thread_name.empty() ?
nullptr : thread_name.c_str());
1821 if (queue_vars_valid)
1822 gdb_thread->
SetQueueInfo(std::move(queue_name), queue_kind, queue_serial,
1823 dispatch_queue_t, associated_with_dispatch_queue);
1834 StopInfoSP current_stop_info_sp = thread_sp->GetPrivateStopInfo(
false);
1836 current_stop_info_sp) {
1837 thread_sp->SetStopInfo(current_stop_info_sp);
1841 if (!thread_sp->StopInfoIsUpToDate()) {
1844 addr_t pc = thread_sp->GetRegisterContext()->GetPC();
1846 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1847 if (bp_site_sp && bp_site_sp->IsEnabled())
1848 thread_sp->SetThreadStoppedAtUnexecutedBP(
pc);
1850 if (exc_type != 0) {
1858 if (interrupt_thread)
1859 thread_sp = interrupt_thread;
1861 const size_t exc_data_size = exc_data.size();
1862 thread_sp->SetStopInfo(
1864 *thread_sp, exc_type, exc_data_size,
1865 exc_data_size >= 1 ? exc_data[0] : 0,
1866 exc_data_size >= 2 ? exc_data[1] : 0,
1867 exc_data_size >= 3 ? exc_data[2] : 0));
1870 bool handled =
false;
1871 bool did_exec =
false;
1874 if (!reason.empty() && reason !=
"none") {
1875 if (reason ==
"trace") {
1878 }
else if (reason ==
"breakpoint") {
1879 thread_sp->SetThreadHitBreakpointSite();
1887 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
1888 thread_sp->SetStopInfo(
1890 *thread_sp, bp_site_sp->GetID()));
1893 thread_sp->SetStopInfo(invalid_stop_info_sp);
1896 }
else if (reason ==
"trap") {
1898 }
else if (reason ==
"watchpoint") {
1934 bool silently_continue =
false;
1944 silently_continue =
true;
1948 if (!wp_resource_sp) {
1950 LLDB_LOGF(log,
"failed to find watchpoint");
1957 watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
1960 *thread_sp, watch_id, silently_continue));
1962 }
else if (reason ==
"exception") {
1964 *thread_sp, description.c_str()));
1966 }
else if (reason ==
"history boundary") {
1968 *thread_sp, description.c_str()));
1970 }
else if (reason ==
"exec") {
1972 thread_sp->SetStopInfo(
1975 }
else if (reason ==
"processor trace") {
1977 *thread_sp, description.c_str()));
1978 }
else if (reason ==
"fork") {
1983 thread_sp->SetStopInfo(
1986 }
else if (reason ==
"vfork") {
1992 *thread_sp, child_pid, child_tid));
1994 }
else if (reason ==
"vforkdone") {
1995 thread_sp->SetStopInfo(
2001 if (!handled && signo && !did_exec) {
2022 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
2031 if (bp_site_sp->IsEnabled())
2032 thread_sp->SetThreadHitBreakpointSite();
2034 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2036 thread_sp->GetRegisterContext()->SetPC(
pc);
2037 thread_sp->SetStopInfo(
2039 *thread_sp, bp_site_sp->GetID()));
2042 thread_sp->SetStopInfo(invalid_stop_info_sp);
2048 thread_sp->SetStopInfo(
2052 *thread_sp, signo, description.c_str()));
2063 if (interrupt_thread)
2064 thread_sp = interrupt_thread;
2067 *thread_sp, signo, description.c_str()));
2071 if (!description.empty()) {
2074 const char *stop_info_desc = stop_info_sp->GetDescription();
2075 if (!stop_info_desc || !stop_info_desc[0])
2076 stop_info_sp->SetDescription(description.c_str());
2079 *thread_sp, description.c_str()));
2089 const std::string &description) {
2098 *thread_sp, signo, description.c_str()));
2107 static constexpr llvm::StringLiteral g_key_tid(
"tid");
2108 static constexpr llvm::StringLiteral g_key_name(
"name");
2109 static constexpr llvm::StringLiteral g_key_reason(
"reason");
2110 static constexpr llvm::StringLiteral g_key_metype(
"metype");
2111 static constexpr llvm::StringLiteral g_key_medata(
"medata");
2112 static constexpr llvm::StringLiteral g_key_qaddr(
"qaddr");
2113 static constexpr llvm::StringLiteral g_key_dispatch_queue_t(
2114 "dispatch_queue_t");
2115 static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(
2116 "associated_with_dispatch_queue");
2117 static constexpr llvm::StringLiteral g_key_queue_name(
"qname");
2118 static constexpr llvm::StringLiteral g_key_queue_kind(
"qkind");
2119 static constexpr llvm::StringLiteral g_key_queue_serial_number(
"qserialnum");
2120 static constexpr llvm::StringLiteral g_key_registers(
"registers");
2121 static constexpr llvm::StringLiteral g_key_memory(
"memory");
2122 static constexpr llvm::StringLiteral g_key_description(
"description");
2123 static constexpr llvm::StringLiteral g_key_signal(
"signal");
2128 std::string thread_name;
2130 std::string description;
2131 uint32_t exc_type = 0;
2132 std::vector<addr_t> exc_data;
2135 bool queue_vars_valid =
false;
2138 std::string queue_name;
2140 uint64_t queue_serial_number = 0;
2145 thread_dict->
ForEach([
this, &tid, &expedited_register_map, &thread_name,
2146 &signo, &reason, &description, &exc_type, &exc_data,
2147 &thread_dispatch_qaddr, &queue_vars_valid,
2148 &associated_with_dispatch_queue, &dispatch_queue_t,
2149 &queue_name, &queue_kind, &queue_serial_number](
2150 llvm::StringRef key,
2152 if (key == g_key_tid) {
2155 }
else if (key == g_key_metype) {
2157 exc_type =
object->GetUnsignedIntegerValue(0);
2158 }
else if (key == g_key_medata) {
2163 exc_data.push_back(object->GetUnsignedIntegerValue());
2167 }
else if (key == g_key_name) {
2168 thread_name = std::string(object->GetStringValue());
2169 }
else if (key == g_key_qaddr) {
2170 thread_dispatch_qaddr =
2172 }
else if (key == g_key_queue_name) {
2173 queue_vars_valid =
true;
2174 queue_name = std::string(object->GetStringValue());
2175 }
else if (key == g_key_queue_kind) {
2176 std::string queue_kind_str = std::string(object->GetStringValue());
2177 if (queue_kind_str ==
"serial") {
2178 queue_vars_valid =
true;
2180 }
else if (queue_kind_str ==
"concurrent") {
2181 queue_vars_valid =
true;
2184 }
else if (key == g_key_queue_serial_number) {
2185 queue_serial_number =
object->GetUnsignedIntegerValue(0);
2186 if (queue_serial_number != 0)
2187 queue_vars_valid =
true;
2188 }
else if (key == g_key_dispatch_queue_t) {
2189 dispatch_queue_t =
object->GetUnsignedIntegerValue(0);
2191 queue_vars_valid =
true;
2192 }
else if (key == g_key_associated_with_dispatch_queue) {
2193 queue_vars_valid =
true;
2194 bool associated =
object->GetBooleanValue();
2199 }
else if (key == g_key_reason) {
2200 reason = std::string(object->GetStringValue());
2201 }
else if (key == g_key_description) {
2202 description = std::string(object->GetStringValue());
2203 }
else if (key == g_key_registers) {
2206 if (registers_dict) {
2208 [&expedited_register_map](llvm::StringRef key,
2211 if (llvm::to_integer(key, reg))
2212 expedited_register_map[reg] =
2213 std::string(object->GetStringValue());
2217 }
else if (key == g_key_memory) {
2223 if (mem_cache_dict) {
2226 "address", mem_cache_addr)) {
2228 llvm::StringRef str;
2233 const size_t byte_size = bytes.
GetStringRef().size() / 2;
2236 const size_t bytes_copied =
2238 if (bytes_copied == byte_size)
2249 }
else if (key == g_key_signal)
2255 reason, description, exc_type, exc_data,
2256 thread_dispatch_qaddr, queue_vars_valid,
2257 associated_with_dispatch_queue, dispatch_queue_t,
2258 queue_name, queue_kind, queue_serial_number);
2264 const char stop_type = stop_packet.
GetChar();
2265 switch (stop_type) {
2284 const uint8_t signo = stop_packet.
GetHexU8();
2285 llvm::StringRef key;
2286 llvm::StringRef value;
2287 std::string thread_name;
2289 std::string description;
2290 uint32_t exc_type = 0;
2291 std::vector<addr_t> exc_data;
2293 bool queue_vars_valid =
2297 std::string queue_name;
2299 uint64_t queue_serial_number = 0;
2303 if (key.compare(
"metype") == 0) {
2305 value.getAsInteger(16, exc_type);
2306 }
else if (key.compare(
"medata") == 0) {
2309 value.getAsInteger(16, x);
2310 exc_data.push_back(x);
2311 }
else if (key.compare(
"thread") == 0) {
2314 auto pid_tid = thread_id.
GetPidTid(pid);
2316 stop_pid = pid_tid->first;
2317 tid = pid_tid->second;
2320 }
else if (key.compare(
"threads") == 0) {
2321 std::lock_guard<std::recursive_mutex> guard(
2324 }
else if (key.compare(
"thread-pcs") == 0) {
2329 while (!value.empty()) {
2330 llvm::StringRef pc_str;
2331 std::tie(pc_str, value) = value.split(
',');
2332 if (pc_str.getAsInteger(16,
pc))
2336 }
else if (key.compare(
"jstopinfo") == 0) {
2345 }
else if (key.compare(
"hexname") == 0) {
2349 }
else if (key.compare(
"name") == 0) {
2350 thread_name = std::string(value);
2351 }
else if (key.compare(
"qaddr") == 0) {
2352 value.getAsInteger(16, thread_dispatch_qaddr);
2353 }
else if (key.compare(
"dispatch_queue_t") == 0) {
2354 queue_vars_valid =
true;
2355 value.getAsInteger(16, dispatch_queue_t);
2356 }
else if (key.compare(
"qname") == 0) {
2357 queue_vars_valid =
true;
2361 }
else if (key.compare(
"qkind") == 0) {
2362 queue_kind = llvm::StringSwitch<QueueKind>(value)
2367 }
else if (key.compare(
"qserialnum") == 0) {
2368 if (!value.getAsInteger(0, queue_serial_number))
2369 queue_vars_valid =
true;
2370 }
else if (key.compare(
"reason") == 0) {
2371 reason = std::string(value);
2372 }
else if (key.compare(
"description") == 0) {
2376 }
else if (key.compare(
"memory") == 0) {
2390 llvm::StringRef addr_str, bytes_str;
2391 std::tie(addr_str, bytes_str) = value.split(
'=');
2392 if (!addr_str.empty() && !bytes_str.empty()) {
2394 if (!addr_str.getAsInteger(0, mem_cache_addr)) {
2399 const size_t bytes_copied =
2401 if (bytes_copied == byte_size)
2405 }
else if (key.compare(
"watch") == 0 || key.compare(
"rwatch") == 0 ||
2406 key.compare(
"awatch") == 0) {
2409 value.getAsInteger(16, wp_addr);
2417 reason =
"watchpoint";
2419 ostr.
Printf(
"%" PRIu64, wp_addr);
2420 description = std::string(ostr.
GetString());
2421 }
else if (key.compare(
"swbreak") == 0 || key.compare(
"hwbreak") == 0) {
2422 reason =
"breakpoint";
2423 }
else if (key.compare(
"replaylog") == 0) {
2424 reason =
"history boundary";
2425 }
else if (key.compare(
"library") == 0) {
2431 }
else if (key.compare(
"fork") == 0 || key.compare(
"vfork") == 0) {
2437 LLDB_LOG(log,
"Invalid PID/TID to fork: {0}", value);
2443 ostr.
Printf(
"%" PRIu64
" %" PRIu64, pid_tid->first, pid_tid->second);
2444 description = std::string(ostr.
GetString());
2445 }
else if (key.compare(
"addressing_bits") == 0) {
2446 uint64_t addressing_bits;
2447 if (!value.getAsInteger(0, addressing_bits)) {
2450 }
else if (key.compare(
"low_mem_addressing_bits") == 0) {
2451 uint64_t addressing_bits;
2452 if (!value.getAsInteger(0, addressing_bits)) {
2455 }
else if (key.compare(
"high_mem_addressing_bits") == 0) {
2456 uint64_t addressing_bits;
2457 if (!value.getAsInteger(0, addressing_bits)) {
2460 }
else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
2462 if (!key.getAsInteger(16, reg))
2463 expedited_register_map[reg] = std::string(std::move(value));
2473 "Received stop for incorrect PID = {0} (inferior PID = {1})",
2493 tid, expedited_register_map, signo, thread_name, reason, description,
2494 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2495 associated_with_dispatch_queue, dispatch_queue_t, queue_name,
2496 queue_kind, queue_serial_number);
2563 LLDB_LOGF(log,
"ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
2567 if (
error.Success())
2569 "ProcessGDBRemote::DoDetach() detach packet sent successfully");
2572 "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
2573 error.AsCString() ?
error.AsCString() :
"<unknown error>");
2576 if (!
error.Success())
2591 LLDB_LOGF(log,
"ProcessGDBRemote::DoDestroy()");
2594 int exit_status = SIGABRT;
2595 std::string exit_string;
2602 exit_status = kill_res.get();
2603#if defined(__APPLE__)
2615 if (platform_sp && platform_sp->IsHost()) {
2618 reap_pid = waitpid(
GetID(), &status, WNOHANG);
2619 LLDB_LOGF(log,
"Reaped pid: %d, status: %d.\n", reap_pid, status);
2623 exit_string.assign(
"killed");
2625 exit_string.assign(llvm::toString(kill_res.takeError()));
2628 exit_string.assign(
"killed or interrupted while attaching.");
2634 exit_string.assign(
"destroying when not connected to debugserver");
2655 const bool did_exec =
2656 response.
GetStringRef().find(
";reason:exec;") != std::string::npos;
2659 LLDB_LOGF(log,
"ProcessGDBRemote::SetLastStopPacket () - detected exec");
2664 m_gdb_comm.ResetDiscoverableSettings(did_exec);
2689 LLDB_LOG_ERROR(log, list.takeError(),
"Failed to read module list: {0}.");
2691 addr = list->m_link_map;
2711 const size_t n = thread_infos->
GetSize();
2712 for (
size_t i = 0; i < n; ++i) {
2728 xPacketState x_state =
m_gdb_comm.GetxPacketState();
2731 size_t max_memory_size = x_state != xPacketState::Unimplemented
2734 if (size > max_memory_size) {
2738 size = max_memory_size;
2743 packet_len = ::snprintf(packet,
sizeof(packet),
"%c%" PRIx64
",%" PRIx64,
2744 x_state != xPacketState::Unimplemented ?
'x' :
'm',
2745 (uint64_t)addr, (uint64_t)size);
2746 assert(packet_len + 1 < (
int)
sizeof(packet));
2749 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
2754 if (x_state != xPacketState::Unimplemented) {
2759 llvm::StringRef data_received = response.
GetStringRef();
2760 if (x_state == xPacketState::Prefixed &&
2761 !data_received.consume_front(
"b")) {
2763 "unexpected response to GDB server memory read packet '{0}': "
2765 packet, data_received);
2770 size_t memcpy_size = std::min(size, data_received.size());
2771 memcpy(buf, data_received.data(), memcpy_size);
2775 llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size),
'\xdd');
2779 "memory read failed for 0x%" PRIx64, addr);
2782 "GDB server does not support reading memory");
2785 "unexpected response to GDB server memory read packet '%s': '%s'",
2797 uint64_t max_packet_size,
2801 constexpr uint64_t range_overhead = 33;
2802 uint64_t current_size = 0;
2803 for (
auto [idx, range] : llvm::enumerate(ranges)) {
2804 uint64_t potential_size = current_size + range.size + range_overhead;
2805 if (potential_size > max_packet_size) {
2808 "MultiMemRead input has a range (base = {0:x}, size = {1}) "
2809 "bigger than the maximum allowed by remote",
2810 range.base, range.size);
2814 return ranges.size();
2817llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>
2820 llvm::MutableArrayRef<uint8_t> buffer) {
2824 const llvm::ArrayRef<Range<lldb::addr_t, size_t>> original_ranges = ranges;
2825 llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> memory_regions;
2827 while (!ranges.empty()) {
2828 uint64_t num_ranges =
2830 if (num_ranges == 0)
2833 auto ranges_for_request = ranges.take_front(num_ranges);
2834 ranges = ranges.drop_front(num_ranges);
2836 llvm::Expected<StringExtractorGDBRemote> response =
2840 "MultiMemRead error response: {0}");
2844 llvm::StringRef response_str = response->GetStringRef();
2845 const unsigned expected_num_ranges = ranges_for_request.size();
2847 response_str, buffer, expected_num_ranges, memory_regions)) {
2849 "MultiMemRead error parsing response: {0}");
2853 return memory_regions;
2856llvm::Expected<StringExtractorGDBRemote>
2859 std::string packet_str;
2860 llvm::raw_string_ostream stream(packet_str);
2861 stream <<
"MultiMemRead:ranges:";
2863 auto range_to_stream = [&](
auto range) {
2865 stream << llvm::formatv(
"{0:x-},{1:x-}", range.base, range.size);
2867 llvm::interleave(ranges, stream, range_to_stream,
",");
2872 m_gdb_comm.SendPacketAndWaitForResponse(packet_str.data(), response,
2875 return llvm::createStringErrorV(
"MultiMemRead failed to send packet: '{0}'",
2879 return llvm::createStringErrorV(
"MultiMemRead failed: '{0}'",
2883 return llvm::createStringErrorV(
"MultiMemRead unexpected response: '{0}'",
2890 llvm::StringRef response_str, llvm::MutableArrayRef<uint8_t> buffer,
2891 unsigned expected_num_ranges,
2894 auto [sizes_str, memory_data] = response_str.split(
';');
2895 if (sizes_str.size() == response_str.size())
2896 return llvm::createStringErrorV(
2897 "MultiMemRead response missing field separator ';' in: '{0}'",
2901 for (llvm::StringRef size_str : llvm::split(sizes_str,
',')) {
2903 if (size_str.getAsInteger(16, read_size))
2904 return llvm::createStringErrorV(
2905 "MultiMemRead response has invalid size string: {0}", size_str);
2907 if (memory_data.size() < read_size)
2908 return llvm::createStringErrorV(
"MultiMemRead response did not have "
2909 "enough data, requested sizes: {0}",
2912 llvm::StringRef region_to_read = memory_data.take_front(read_size);
2913 memory_data = memory_data.drop_front(read_size);
2915 assert(buffer.size() >= read_size);
2916 llvm::MutableArrayRef<uint8_t> region_to_write =
2917 buffer.take_front(read_size);
2918 buffer = buffer.drop_front(read_size);
2920 memcpy(region_to_write.data(), region_to_read.data(), read_size);
2921 memory_regions.push_back(region_to_write);
2924 return llvm::Error::success();
2928 return m_gdb_comm.GetMemoryTaggingSupported();
2931llvm::Expected<std::vector<uint8_t>>
2938 return llvm::createStringError(llvm::inconvertibleErrorCode(),
2939 "Error reading memory tags from remote");
2943 llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
2944 std::vector<uint8_t> got;
2945 got.reserve(tag_data.size());
2946 std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
2952 const std::vector<uint8_t> &tags) {
2955 return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
2959 std::vector<ObjectFile::LoadableData> entries) {
2969 if (
error.Success())
2983 for (
size_t i = 0; i < size; ++i)
3008 if (blocksize == 0) {
3016 lldb::addr_t block_start_addr = addr - (addr % blocksize);
3017 size += (addr - block_start_addr);
3018 if ((size % blocksize) != 0)
3019 size += (blocksize - size % blocksize);
3035 auto overlap = last_range.GetRangeEnd() - range.
GetRangeBase();
3056 "flash erase failed for 0x%" PRIx64, addr);
3059 "GDB server does not support flashing");
3062 "unexpected response to GDB server flash erase packet '%s': '%s'",
3079 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"vFlashDone", response,
3089 "GDB server does not support flashing");
3092 "unexpected response to GDB server flash done packet: '%s'",
3107 if (size > max_memory_size) {
3111 size = max_memory_size;
3132 if (!
error.Success())
3134 packet.
Printf(
"vFlashWrite:%" PRIx64
":", addr);
3137 packet.
Printf(
"M%" PRIx64
",%" PRIx64
":", addr, (uint64_t)size);
3150 "memory write failed for 0x%" PRIx64, addr);
3153 "GDB server does not support writing memory");
3156 "unexpected response to GDB server memory write packet '%s': '%s'",
3166 uint32_t permissions,
3172 allocated_addr =
m_gdb_comm.AllocateMemory(size, permissions);
3175 return allocated_addr;
3181 if (permissions & lldb::ePermissionsReadable)
3183 if (permissions & lldb::ePermissionsWritable)
3185 if (permissions & lldb::ePermissionsExecutable)
3194 "ProcessGDBRemote::%s no direct stub support for memory "
3195 "allocation, and InferiorCallMmap also failed - is stub "
3196 "missing register context save/restore capability?",
3203 "unable to allocate %" PRIu64
" bytes of memory with permissions %s",
3207 return allocated_addr;
3222 return m_gdb_comm.GetWatchpointReportedAfter();
3229 switch (supported) {
3234 "tried to deallocate memory without ever allocating memory");
3240 "unable to deallocate memory at 0x%" PRIx64, addr);
3252 "unable to deallocate memory at 0x%" PRIx64, addr);
3267 m_gdb_comm.SendStdinNotification(src, src_len);
3274 assert(bp_site !=
nullptr);
3285 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3286 ") address = 0x%" PRIx64,
3287 site_id, (uint64_t)addr);
3292 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3293 ") address = 0x%" PRIx64
" -- SUCCESS (already enabled)",
3294 site_id, (uint64_t)addr);
3313 uint8_t error_no =
m_gdb_comm.SendGDBStoppointTypePacket(
3315 if (error_no == 0) {
3331 if (error_no != UINT8_MAX)
3333 "error: %d sending the breakpoint request", error_no);
3342 LLDB_LOGF(log,
"Software breakpoints are unsupported");
3353 uint8_t error_no =
m_gdb_comm.SendGDBStoppointTypePacket(
3355 if (error_no == 0) {
3366 if (error_no != UINT8_MAX)
3368 "error: %d sending the hardware breakpoint request "
3369 "(hardware breakpoint resources might be exhausted or unavailable)",
3373 "error sending the hardware breakpoint request "
3374 "(hardware breakpoint resources "
3375 "might be exhausted or unavailable)");
3381 LLDB_LOGF(log,
"Hardware breakpoints are unsupported");
3399 assert(bp_site !=
nullptr);
3404 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3405 ") addr = 0x%8.8" PRIx64,
3406 site_id, (uint64_t)addr);
3431 if (
error.Success())
3435 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3436 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3437 site_id, (uint64_t)addr);
3441 if (
error.Success())
3450 bool read = wp_res_sp->WatchpointResourceRead();
3451 bool write = wp_res_sp->WatchpointResourceWrite();
3453 assert((read || write) &&
3454 "WatchpointResource type is neither read nor write");
3470 addr_t addr = wp_sp->GetLoadAddress();
3472 LLDB_LOGF(log,
"ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
")",
3474 if (wp_sp->IsEnabled()) {
3476 "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
3477 ") addr = 0x%8.8" PRIx64
": watchpoint already enabled.",
3478 watchID, (uint64_t)addr);
3482 bool read = wp_sp->WatchpointRead();
3483 bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
3484 size_t size = wp_sp->GetByteSize();
3487 WatchpointHardwareFeature supported_features =
3490 std::vector<WatchpointResourceSP> resources =
3492 addr, size, read, write, supported_features, target_arch);
3517 bool set_all_resources =
true;
3518 std::vector<WatchpointResourceSP> succesfully_set_resources;
3519 for (
const auto &wp_res_sp : resources) {
3520 addr_t addr = wp_res_sp->GetLoadAddress();
3521 size_t size = wp_res_sp->GetByteSize();
3523 if (!
m_gdb_comm.SupportsGDBStoppointPacket(type) ||
3524 m_gdb_comm.SendGDBStoppointTypePacket(type,
true, addr, size,
3526 set_all_resources =
false;
3529 succesfully_set_resources.push_back(wp_res_sp);
3532 if (set_all_resources) {
3533 wp_sp->SetEnabled(
true, notify);
3534 for (
const auto &wp_res_sp : resources) {
3537 wp_res_sp->AddConstituent(wp_sp);
3545 for (
const auto &wp_res_sp : succesfully_set_resources) {
3546 addr_t addr = wp_res_sp->GetLoadAddress();
3547 size_t size = wp_res_sp->GetByteSize();
3549 m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3553 "Setting one of the watchpoint resources failed");
3569 addr_t addr = wp_sp->GetLoadAddress();
3572 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3573 ") addr = 0x%8.8" PRIx64,
3574 watchID, (uint64_t)addr);
3576 if (!wp_sp->IsEnabled()) {
3578 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3579 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3580 watchID, (uint64_t)addr);
3584 wp_sp->SetEnabled(
false, notify);
3588 if (wp_sp->IsHardware()) {
3589 bool disabled_all =
true;
3591 std::vector<WatchpointResourceSP> unused_resources;
3593 if (wp_res_sp->ConstituentsContains(wp_sp)) {
3595 addr_t addr = wp_res_sp->GetLoadAddress();
3596 size_t size = wp_res_sp->GetByteSize();
3597 if (
m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3599 disabled_all =
false;
3601 wp_res_sp->RemoveConstituent(wp_sp);
3602 if (wp_res_sp->GetNumberOfConstituents() == 0)
3603 unused_resources.push_back(wp_res_sp);
3607 for (
auto &wp_res_sp : unused_resources)
3610 wp_sp->SetEnabled(
false, notify);
3613 "Failure disabling one of the watchpoint locations");
3626 LLDB_LOGF(log,
"ProcessGDBRemote::DoSignal (signal = %d)", signo);
3641 if (platform_sp && !platform_sp->IsHost())
3646 const char *error_string =
error.AsCString();
3647 if (error_string ==
nullptr)
3656 static FileSpec g_debugserver_file_spec;
3663 std::string env_debugserver_path = host_env.lookup(
"LLDB_DEBUGSERVER_PATH");
3664 if (!env_debugserver_path.empty()) {
3665 debugserver_file_spec.
SetFile(env_debugserver_path,
3666 FileSpec::Style::native);
3667 LLDB_LOG(log,
"gdb-remote stub exe path set from environment variable: {0}",
3668 env_debugserver_path);
3670 debugserver_file_spec = g_debugserver_file_spec;
3672 return debugserver_file_spec;
3675 debugserver_file_spec = HostInfo::GetSupportExeDir();
3676 if (debugserver_file_spec) {
3679 LLDB_LOG(log,
"found gdb-remote stub exe '{0}'", debugserver_file_spec);
3681 g_debugserver_file_spec = debugserver_file_spec;
3684 if (!debugserver_file_spec) {
3687 LLDB_LOG(log,
"could not find gdb-remote stub exe '{0}'",
3688 debugserver_file_spec);
3692 g_debugserver_file_spec.
Clear();
3695 return debugserver_file_spec;
3700 using namespace std::placeholders;
3710 const std::weak_ptr<ProcessGDBRemote> this_wp =
3711 std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3718#if defined(__APPLE__)
3722 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
3724 struct kinfo_proc processInfo;
3725 size_t bufsize =
sizeof(processInfo);
3726 if (sysctl(mib, (
unsigned)(
sizeof(mib) /
sizeof(
int)), &processInfo, &bufsize,
3729 if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
3730 debugserver_path =
FileSpec(
"/Library/Apple/usr/libexec/oah/debugserver");
3737 "'. Please ensure it is properly installed "
3738 "and available in your PATH");
3753 debugserver_launch_info,
nullptr);
3758 LLDB_LOGF(log,
"failed to start debugserver process: %s",
3768 m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>(
3769 std::move(socket_pair->second)));
3783 std::weak_ptr<ProcessGDBRemote> process_wp,
lldb::pid_t debugserver_pid,
3792 "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
3793 ", signo=%i (0x%x), exit_status=%i)",
3794 __FUNCTION__, debugserver_pid, signo, signo, exit_status);
3796 std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
3797 LLDB_LOGF(log,
"ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
3798 static_cast<void *
>(process_sp.get()));
3799 if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
3805 std::this_thread::sleep_for(std::chrono::milliseconds(500));
3809 const StateType state = process_sp->GetState();
3818 llvm::StringRef signal_name =
3819 process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);
3821 if (!signal_name.empty())
3822 stream.
Format(format_str, signal_name);
3824 stream.
Format(format_str, signo);
3826 process_sp->SetExitStatus(-1, stream.
GetString());
3842 static llvm::once_flag g_once_flag;
3844 llvm::call_once(g_once_flag, []() {
3853 debugger, PluginProperties::GetSettingName())) {
3854 const bool is_global_setting =
true;
3857 "Properties for the gdb-remote process plug-in.", is_global_setting);
3864 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
3871 llvm::Expected<HostThread> async_thread =
3875 if (!async_thread) {
3877 "failed to launch host thread: {0}");
3883 "ProcessGDBRemote::%s () - Called when Async thread was "
3893 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
3908 "ProcessGDBRemote::%s () - Called when Async thread was not running.",
3914 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread starting...",
3915 __FUNCTION__,
GetID());
3933 "ProcessGDBRemote::%s(pid = %" PRIu64
3934 ") listener.WaitForEvent (NULL, event_sp)...",
3935 __FUNCTION__,
GetID());
3938 const uint32_t event_type = event_sp->GetType();
3941 "ProcessGDBRemote::%s(pid = %" PRIu64
3942 ") Got an event of type: %d...",
3943 __FUNCTION__,
GetID(), event_type);
3945 switch (event_type) {
3950 if (continue_packet) {
3951 const char *continue_cstr =
3952 (
const char *)continue_packet->
GetBytes();
3953 const size_t continue_cstr_len = continue_packet->
GetByteSize();
3955 "ProcessGDBRemote::%s(pid = %" PRIu64
3956 ") got eBroadcastBitAsyncContinue: %s",
3957 __FUNCTION__,
GetID(), continue_cstr);
3959 if (::strstr(continue_cstr,
"vAttach") ==
nullptr)
3966 llvm::StringRef(continue_cstr, continue_cstr_len),
3977 switch (stop_state) {
3990 int exit_status = response.
GetHexU8();
3991 std::string desc_string;
3993 llvm::StringRef desc_str;
3994 llvm::StringRef desc_token;
3996 if (desc_token !=
"description")
4011 if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4014 "System Integrity Protection");
4015 }
else if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4035 "ProcessGDBRemote::%s(pid = %" PRIu64
4036 ") got eBroadcastBitAsyncThreadShouldExit...",
4037 __FUNCTION__,
GetID());
4043 "ProcessGDBRemote::%s(pid = %" PRIu64
4044 ") got unknown event 0x%8.8x",
4045 __FUNCTION__,
GetID(), event_type);
4052 "ProcessGDBRemote::%s(pid = %" PRIu64
4053 ") listener.WaitForEvent (NULL, event_sp) => false",
4054 __FUNCTION__,
GetID());
4059 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread exiting...",
4060 __FUNCTION__,
GetID());
4092 LLDB_LOGF(log,
"Hit New Thread Notification breakpoint.");
4098 LLDB_LOG(log,
"Check if need to update ignored signals");
4112 LLDB_LOG(log,
"Signals' version hasn't changed. version={0}",
4117 auto signals_to_ignore =
4122 "Signals' version changed. old version={0}, new version={1}, "
4123 "signals ignored={2}, update result={3}",
4125 signals_to_ignore.size(),
error);
4127 if (
error.Success())
4137 LLDB_LOGF(log,
"Enabled noticing new thread breakpoint.");
4143 platform_sp->SetThreadCreationBreakpoint(
GetTarget());
4147 log,
"Successfully created new thread notification breakpoint %i",
4152 LLDB_LOGF(log,
"Failed to create new thread notification breakpoint.");
4162 LLDB_LOGF(log,
"Disabling new thread notification breakpoint.");
4182 return_value =
m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
4183 if (return_value != 0) {
4186 "Sending events is not supported for this process.");
4196 if (
m_gdb_comm.GetQXferAuxvReadSupported()) {
4197 llvm::Expected<std::string> response =
m_gdb_comm.ReadExtFeature(
"auxv",
"");
4199 buf = std::make_shared<DataBufferHeap>(response->c_str(),
4200 response->length());
4211 if (
m_gdb_comm.GetThreadExtendedInfoSupported()) {
4217 args_dict->GetAsDictionary()->AddIntegerItem(
"thread", tid);
4220 packet <<
"jThreadExtendedInfo:";
4221 args_dict->Dump(packet,
false);
4228 packet << (char)(0x7d ^ 0x20);
4237 if (!response.
Empty()) {
4250 args_dict->GetAsDictionary()->AddIntegerItem(
"image_list_address",
4251 image_list_address);
4252 args_dict->GetAsDictionary()->AddIntegerItem(
"image_count", image_count);
4260 args_dict->GetAsDictionary()->AddBooleanItem(
"fetch_all_solibs",
true);
4266 const std::vector<lldb::addr_t> &load_addresses) {
4270 for (
auto addr : load_addresses)
4271 addresses->AddIntegerItem(addr);
4273 args_dict->GetAsDictionary()->AddItem(
"solib_addresses", addresses);
4283 if (
m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
4286 std::chrono::seconds(10));
4289 packet <<
"jGetLoadedDynamicLibrariesInfos:";
4290 args_dict->Dump(packet,
false);
4297 packet << (char)(0x7d ^ 0x20);
4306 if (!response.
Empty()) {
4319 if (
m_gdb_comm.GetDynamicLoaderProcessStateSupported()) {
4322 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"jGetDyldProcessState",
4328 if (!response.
Empty()) {
4341 if (
m_gdb_comm.GetSharedCacheInfoSupported()) {
4343 packet <<
"jGetSharedCacheInfo:";
4344 args_dict->Dump(packet,
false);
4351 packet << (char)(0x7d ^ 0x20);
4360 if (!response.
Empty()) {
4371 return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
4384 const uint64_t reasonable_largeish_default = 128 * 1024;
4385 const uint64_t conservative_default = 512;
4388 uint64_t stub_max_size =
m_gdb_comm.GetRemoteMaxPacketSize();
4389 if (stub_max_size !=
UINT64_MAX && stub_max_size != 0) {
4395 if (stub_max_size > reasonable_largeish_default) {
4396 stub_max_size = reasonable_largeish_default;
4402 if (stub_max_size > 70)
4403 stub_max_size -= 32 + 32 + 6;
4409 log->
Warning(
"Packet size is too small. "
4410 "LLDB may face problems while writing memory");
4421 uint64_t user_specified_max) {
4422 if (user_specified_max != 0) {
4450 module_spec = cached->second;
4451 return bool(module_spec);
4454 if (!
m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
4455 LLDB_LOGF(log,
"ProcessGDBRemote::%s - failed to get module info for %s:%s",
4456 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4463 module_spec.
Dump(stream);
4464 LLDB_LOGF(log,
"ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
4465 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4474 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4475 auto module_specs =
m_gdb_comm.GetModulesInfo(module_file_specs, triple);
4477 for (
const FileSpec &spec : module_file_specs)
4482 triple.getTriple())] = spec;
4496typedef std::vector<std::string> stringVec;
4498typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
4499struct RegisterSetInfo {
4503typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
4505struct GdbServerTargetInfo {
4509 RegisterSetMap reg_set_map;
4526 std::map<uint64_t, FieldEnum::Enumerator> enumerators;
4529 "evalue", [&enumerators, &log](
const XMLNode &enumerator_node) {
4530 std::optional<llvm::StringRef> name;
4531 std::optional<uint64_t> value;
4534 [&name, &value, &log](
const llvm::StringRef &attr_name,
4535 const llvm::StringRef &attr_value) {
4536 if (attr_name ==
"name") {
4537 if (attr_value.size())
4540 LLDB_LOG(log,
"ProcessGDBRemote::ParseEnumEvalues "
4541 "Ignoring empty name in evalue");
4542 }
else if (attr_name ==
"value") {
4543 uint64_t parsed_value = 0;
4544 if (llvm::to_integer(attr_value, parsed_value))
4545 value = parsed_value;
4548 "ProcessGDBRemote::ParseEnumEvalues "
4549 "Invalid value \"{0}\" in "
4554 "ProcessGDBRemote::ParseEnumEvalues Ignoring "
4555 "unknown attribute "
4556 "\"{0}\" in evalue",
4564 enumerators.insert_or_assign(
4565 *value, FieldEnum::Enumerator(*value, name->str()));
4572 for (
auto [_, enumerator] : enumerators)
4573 final_enumerators.push_back(enumerator);
4575 return final_enumerators;
4579ParseEnums(XMLNode feature_node,
4580 llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4581 Log *log(
GetLog(GDBRLog::Process));
4585 "enum", [log, ®isters_enum_types](
const XMLNode &enum_node) {
4589 const llvm::StringRef &attr_value) {
4590 if (attr_name ==
"id")
4608 if (!enumerators.empty()) {
4610 "ProcessGDBRemote::ParseEnums Found enum type \"{0}\"",
4612 registers_enum_types.insert_or_assign(
4613 id, std::make_unique<FieldEnum>(
id, enumerators));
4622static std::vector<RegisterFlags::Field> ParseFlagsFields(
4623 XMLNode flags_node,
unsigned size,
4624 const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4625 Log *log(
GetLog(GDBRLog::Process));
4626 const unsigned max_start_bit = size * 8 - 1;
4629 std::vector<RegisterFlags::Field> fields;
4631 ®isters_enum_types](
4634 std::optional<llvm::StringRef> name;
4635 std::optional<unsigned> start;
4636 std::optional<unsigned> end;
4637 std::optional<llvm::StringRef> type;
4640 &log](
const llvm::StringRef &attr_name,
4641 const llvm::StringRef &attr_value) {
4644 if (attr_name ==
"name") {
4647 "ProcessGDBRemote::ParseFlagsFields Found field node name \"{0}\"",
4650 }
else if (attr_name ==
"start") {
4651 unsigned parsed_start = 0;
4652 if (llvm::to_integer(attr_value, parsed_start)) {
4653 if (parsed_start > max_start_bit) {
4655 "ProcessGDBRemote::ParseFlagsFields Invalid start {0} in "
4658 parsed_start, max_start_bit);
4660 start = parsed_start;
4664 "ProcessGDBRemote::ParseFlagsFields Invalid start \"{0}\" in "
4668 }
else if (attr_name ==
"end") {
4669 unsigned parsed_end = 0;
4670 if (llvm::to_integer(attr_value, parsed_end))
4671 if (parsed_end > max_start_bit) {
4673 "ProcessGDBRemote::ParseFlagsFields Invalid end {0} in "
4676 parsed_end, max_start_bit);
4681 "ProcessGDBRemote::ParseFlagsFields Invalid end \"{0}\" in "
4685 }
else if (attr_name ==
"type") {
4690 "ProcessGDBRemote::ParseFlagsFields Ignoring unknown attribute "
4691 "\"{0}\" in field node",
4698 if (name && start && end) {
4702 "ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
4703 "\"{2}\", ignoring",
4704 *start, *end, name->data());
4708 "ProcessGDBRemote::ParseFlagsFields Ignoring field \"{2}\" "
4710 "size > 64 bits, this is not supported",
4714 const FieldEnum *enum_type =
nullptr;
4715 if (type && !type->empty()) {
4716 auto found = registers_enum_types.find(*type);
4717 if (found != registers_enum_types.end()) {
4718 enum_type = found->second.get();
4721 uint64_t max_value =
4724 if (enumerator.m_value > max_value) {
4725 enum_type =
nullptr;
4728 "ProcessGDBRemote::ParseFlagsFields In enum \"{0}\" "
4729 "evalue \"{1}\" with value {2} exceeds the maximum value "
4730 "of field \"{3}\" ({4}), ignoring enum",
4731 type->data(), enumerator.m_name, enumerator.m_value,
4732 name->data(), max_value);
4738 "ProcessGDBRemote::ParseFlagsFields Could not find type "
4740 "for field \"{1}\", ignoring",
4741 type->data(), name->data());
4746 RegisterFlags::Field(name->str(), *start, *end, enum_type));
4757 XMLNode feature_node,
4758 llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4759 const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4760 Log *log(
GetLog(GDBRLog::Process));
4764 [&log, ®isters_flags_types,
4765 ®isters_enum_types](
const XMLNode &flags_node) ->
bool {
4766 LLDB_LOG(log,
"ProcessGDBRemote::ParseFlags Found flags node \"{0}\"",
4769 std::optional<llvm::StringRef>
id;
4770 std::optional<unsigned> size;
4772 [&
id, &size, &log](
const llvm::StringRef &name,
4773 const llvm::StringRef &value) {
4776 }
else if (name ==
"size") {
4777 unsigned parsed_size = 0;
4778 if (llvm::to_integer(value, parsed_size))
4782 "ProcessGDBRemote::ParseFlags Invalid size \"{0}\" "
4788 "ProcessGDBRemote::ParseFlags Ignoring unknown "
4789 "attribute \"{0}\" in flags node",
4797 std::vector<RegisterFlags::Field> fields =
4798 ParseFlagsFields(flags_node, *size, registers_enum_types);
4799 if (fields.size()) {
4801 std::sort(fields.rbegin(), fields.rend());
4802 std::vector<RegisterFlags::Field>::const_iterator overlap =
4803 std::adjacent_find(fields.begin(), fields.end(),
4804 [](
const RegisterFlags::Field &lhs,
4805 const RegisterFlags::Field &rhs) {
4806 return lhs.Overlaps(rhs);
4810 if (overlap == fields.end()) {
4811 if (registers_flags_types.contains(*
id)) {
4825 "ProcessGDBRemote::ParseFlags Definition of flags "
4827 "previous definition, using original definition instead.",
4830 registers_flags_types.insert_or_assign(
4831 *
id, std::make_unique<RegisterFlags>(
id->str(), *size,
4832 std::move(fields)));
4836 std::vector<RegisterFlags::Field>::const_iterator next =
4840 "ProcessGDBRemote::ParseFlags Ignoring flags because fields "
4841 "{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) "
4843 overlap->GetName().c_str(), overlap->GetStart(),
4844 overlap->GetEnd(), next->GetName().c_str(), next->GetStart(),
4850 "ProcessGDBRemote::ParseFlags Ignoring definition of flags "
4851 "\"{0}\" because it contains no fields.",
4861 XMLNode feature_node, GdbServerTargetInfo &target_info,
4862 std::vector<DynamicRegisterInfo::Register> ®isters,
4863 llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
4864 llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4868 Log *log(
GetLog(GDBRLog::Process));
4871 ParseEnums(feature_node, registers_enum_types);
4872 for (
const auto &enum_type : registers_enum_types)
4875 ParseFlags(feature_node, registers_flags_types, registers_enum_types);
4876 for (
const auto &flags : registers_flags_types)
4877 flags.second->DumpToLog(log);
4881 [&target_info, ®isters, ®isters_flags_types,
4882 log](
const XMLNode ®_node) ->
bool {
4883 std::string gdb_group;
4884 std::string gdb_type;
4885 DynamicRegisterInfo::Register reg_info;
4886 bool encoding_set =
false;
4887 bool format_set =
false;
4891 &encoding_set, &format_set, ®_info,
4892 log](
const llvm::StringRef &name,
4893 const llvm::StringRef &value) ->
bool {
4894 if (name ==
"name") {
4896 }
else if (name ==
"bitsize") {
4897 if (llvm::to_integer(value, reg_info.
byte_size))
4899 llvm::divideCeil(reg_info.
byte_size, CHAR_BIT);
4900 }
else if (name ==
"type") {
4901 gdb_type = value.str();
4902 }
else if (name ==
"group") {
4903 gdb_group = value.str();
4904 }
else if (name ==
"regnum") {
4906 }
else if (name ==
"offset") {
4908 }
else if (name ==
"altname") {
4910 }
else if (name ==
"encoding") {
4911 encoding_set =
true;
4913 }
else if (name ==
"format") {
4919 llvm::StringSwitch<lldb::Format>(value)
4930 }
else if (name ==
"group_id") {
4932 llvm::to_integer(value, set_id);
4933 RegisterSetMap::const_iterator pos =
4934 target_info.reg_set_map.find(set_id);
4935 if (pos != target_info.reg_set_map.end())
4936 reg_info.
set_name = pos->second.name;
4937 }
else if (name ==
"gcc_regnum" || name ==
"ehframe_regnum") {
4939 }
else if (name ==
"dwarf_regnum") {
4941 }
else if (name ==
"generic") {
4943 }
else if (name ==
"value_regnums") {
4946 }
else if (name ==
"invalidate_regnums") {
4951 "ProcessGDBRemote::ParseRegisters unhandled reg "
4952 "attribute %s = %s",
4953 name.data(), value.data());
4958 if (!gdb_type.empty()) {
4960 llvm::StringMap<std::unique_ptr<RegisterFlags>>::iterator it =
4961 registers_flags_types.find(gdb_type);
4962 if (it != registers_flags_types.end()) {
4963 auto flags_type = it->second.get();
4964 if (reg_info.
byte_size == flags_type->GetSize())
4968 "ProcessGDBRemote::ParseRegisters Size of register "
4969 "flags %s (%d bytes) for "
4970 "register %s does not match the register size (%d "
4971 "bytes). Ignoring this set of flags.",
4972 flags_type->GetID().c_str(), flags_type->GetSize(),
4979 if (!gdb_type.empty() && !(encoding_set || format_set)) {
4980 if (llvm::StringRef(gdb_type).starts_with(
"int")) {
4983 }
else if (gdb_type ==
"data_ptr" || gdb_type ==
"code_ptr") {
4986 }
else if (gdb_type ==
"float" || gdb_type ==
"ieee_single" ||
4987 gdb_type ==
"ieee_double") {
4990 }
else if (gdb_type ==
"aarch64v" ||
4991 llvm::StringRef(gdb_type).starts_with(
"vec") ||
4992 gdb_type ==
"i387_ext" || gdb_type ==
"uint128" ||
5005 "ProcessGDBRemote::ParseRegisters Could not determine lldb"
5006 "format and encoding for gdb type %s",
5016 if (!gdb_group.empty()) {
5027 "ProcessGDBRemote::%s Skipping zero bitsize register %s",
5030 registers.push_back(reg_info);
5045 ArchSpec &arch_to_use, std::string xml_filename,
5046 std::vector<DynamicRegisterInfo::Register> ®isters) {
5048 llvm::Expected<std::string> raw =
m_gdb_comm.ReadExtFeature(
"features", xml_filename);
5049 if (errorToBool(raw.takeError()))
5054 if (xml_document.
ParseMemory(raw->c_str(), raw->size(),
5055 xml_filename.c_str())) {
5056 GdbServerTargetInfo target_info;
5057 std::vector<XMLNode> feature_nodes;
5063 const XMLNode &node) ->
bool {
5064 llvm::StringRef name = node.
GetName();
5065 if (name ==
"architecture") {
5067 }
else if (name ==
"osabi") {
5069 }
else if (name ==
"xi:include" || name ==
"include") {
5072 target_info.includes.push_back(href);
5073 }
else if (name ==
"feature") {
5074 feature_nodes.push_back(node);
5075 }
else if (name ==
"groups") {
5077 "group", [&target_info](
const XMLNode &node) ->
bool {
5079 RegisterSetInfo set_info;
5082 [&set_id, &set_info](
const llvm::StringRef &name,
5083 const llvm::StringRef &value) ->
bool {
5086 llvm::to_integer(value, set_id);
5093 target_info.reg_set_map[set_id] = set_info;
5106 feature_nodes.push_back(feature_node);
5108 const XMLNode &node) ->
bool {
5109 llvm::StringRef name = node.
GetName();
5110 if (name ==
"xi:include" || name ==
"include") {
5113 target_info.includes.push_back(href);
5127 if (!arch_to_use.
IsValid() && !target_info.arch.empty()) {
5129 arch_to_use.
SetTriple(llvm::StringSwitch<std::string>(target_info.arch)
5130 .Case(
"i386:x86-64",
"x86_64")
5131 .Case(
"riscv:rv64",
"riscv64")
5132 .Case(
"riscv:rv32",
"riscv32")
5133 .Default(target_info.arch) +
5141 for (
auto &feature_node : feature_nodes) {
5142 ParseRegisters(feature_node, target_info, registers,
5146 for (
const auto &include : target_info.includes) {
5158 std::vector<DynamicRegisterInfo::Register> ®isters,
5160 std::map<uint32_t, uint32_t> remote_to_local_map;
5161 uint32_t remote_regnum = 0;
5162 for (
auto it : llvm::enumerate(registers)) {
5170 remote_to_local_map[remote_reg_info.
regnum_remote] = it.index();
5176 auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) {
5177 auto lldb_regit = remote_to_local_map.find(process_regnum);
5178 return lldb_regit != remote_to_local_map.end() ? lldb_regit->second
5182 llvm::transform(remote_reg_info.value_regs,
5183 remote_reg_info.value_regs.begin(), proc_to_lldb);
5184 llvm::transform(remote_reg_info.invalidate_regs,
5185 remote_reg_info.invalidate_regs.begin(), proc_to_lldb);
5192 abi_sp->AugmentRegisterInfo(registers);
5202 if (!
m_gdb_comm.GetQXferFeaturesReadSupported())
5203 return llvm::createStringError(
5204 llvm::inconvertibleErrorCode(),
5205 "the debug server does not support \"qXfer:features:read\"");
5208 return llvm::createStringError(
5209 llvm::inconvertibleErrorCode(),
5210 "the debug server supports \"qXfer:features:read\", but LLDB does not "
5211 "have XML parsing enabled (check LLLDB_ENABLE_LIBXML2)");
5221 std::vector<DynamicRegisterInfo::Register> registers;
5229 ? llvm::ErrorSuccess()
5230 : llvm::createStringError(
5231 llvm::inconvertibleErrorCode(),
5232 "the debug server did not describe any registers");
5238 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5239 "XML parsing not available");
5242 LLDB_LOGF(log,
"ProcessGDBRemote::%s", __FUNCTION__);
5251 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries-svr4",
"");
5253 return raw.takeError();
5256 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5259 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5260 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5261 "Error reading noname.xml");
5265 return llvm::createStringError(
5266 llvm::inconvertibleErrorCode(),
5267 "Error finding library-list-svr4 xml element");
5272 if (!main_lm.empty())
5276 "library", [log, &list](
const XMLNode &library) ->
bool {
5281 [&module](
const llvm::StringRef &name,
5282 const llvm::StringRef &value) ->
bool {
5285 module.set_name(value.str());
5286 else if (name ==
"lm") {
5288 llvm::to_integer(value, uint_value);
5289 module.set_link_map(uint_value);
5290 }
else if (name ==
"l_addr") {
5293 llvm::to_integer(value, uint_value);
5294 module.set_base(uint_value);
5297 module.set_base_is_offset(true);
5298 }
else if (name ==
"l_ld") {
5300 llvm::to_integer(value, uint_value);
5301 module.set_dynamic(uint_value);
5310 bool base_is_offset;
5312 module.get_name(name);
5313 module.get_link_map(lm);
5314 module.get_base(base);
5315 module.get_base_is_offset(base_is_offset);
5316 module.get_dynamic(ld);
5319 "found (link_map:0x%08" PRIx64
", base:0x%08" PRIx64
5320 "[%s], ld:0x%08" PRIx64
", name:'%s')",
5321 lm, base, (base_is_offset ?
"offset" :
"absolute"), ld,
5331 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5332 (
int)list.
m_list.size());
5336 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries",
"");
5339 return raw.takeError();
5341 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5344 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5345 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5346 "Error reading noname.xml");
5350 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5351 "Error finding library-list xml element");
5355 "library", [log, &list](
const XMLNode &library) ->
bool {
5359 module.set_name(name);
5368 llvm::to_integer(address, address_value);
5369 module.set_base(address_value);
5371 module.set_base_is_offset(false);
5376 bool base_is_offset;
5377 module.get_name(name);
5378 module.get_base(base);
5379 module.get_base_is_offset(base_is_offset);
5381 LLDB_LOGF(log,
"found (base:0x%08" PRIx64
"[%s], name:'%s')", base,
5382 (base_is_offset ?
"offset" :
"absolute"), name.c_str());
5391 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5392 (
int)list.
m_list.size());
5395 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5396 "Remote libraries not supported");
5403 bool value_is_offset) {
5418 return module_list.takeError();
5424 std::string mod_name;
5427 bool mod_base_is_offset;
5430 valid &= modInfo.
get_name(mod_name);
5431 valid &= modInfo.
get_base(mod_base);
5444 if (module_sp.get())
5445 new_modules.
Append(module_sp);
5448 if (new_modules.
GetSize() > 0) {
5453 for (
size_t i = 0; i < loaded_modules.
GetSize(); ++i) {
5457 for (
size_t j = 0; j < new_modules.
GetSize(); ++j) {
5466 removed_modules.
Append(loaded_module);
5470 loaded_modules.
Remove(removed_modules);
5471 m_process->GetTarget().ModulesDidUnload(removed_modules,
false);
5487 m_process->GetTarget().ModulesDidLoad(new_modules);
5490 return llvm::ErrorSuccess();
5499 std::string file_path = file.
GetPath(
false);
5500 if (file_path.empty())
5521 "Fetching file load address from remote server returned an error");
5531 "Unknown error happened during sending the load address packet");
5552 std::string input = data.str();
5559 size_t found, pos = 0, len = input.length();
5560 while ((found = input.find(
end_delimiter, pos)) != std::string::npos) {
5562 input.substr(pos, found).c_str());
5563 std::string profile_data =
5578 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
5580 llvm::raw_string_ostream output_stream(output);
5581 llvm::StringRef name, value;
5585 if (name.compare(
"thread_used_id") == 0) {
5587 uint64_t thread_id = threadIDHexExtractor.
GetHexMaxU64(
false, 0);
5589 bool has_used_usec =
false;
5590 uint32_t curr_used_usec = 0;
5591 llvm::StringRef usec_name, usec_value;
5592 uint32_t input_file_pos = profileDataExtractor.
GetFilePos();
5594 if (usec_name ==
"thread_used_usec") {
5595 has_used_usec =
true;
5596 usec_value.getAsInteger(0, curr_used_usec);
5600 profileDataExtractor.
SetFilePos(input_file_pos);
5604 if (has_used_usec) {
5605 uint32_t prev_used_usec = 0;
5606 std::map<uint64_t, uint32_t>::iterator iterator =
5609 prev_used_usec = iterator->second;
5611 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
5613 bool good_first_time =
5614 (prev_used_usec == 0) && (real_used_usec > 250000);
5615 bool good_subsequent_time =
5616 (prev_used_usec > 0) &&
5619 if (good_first_time || good_subsequent_time) {
5623 output_stream << name <<
":";
5625 output_stream << index_id <<
";";
5627 output_stream << usec_name <<
":" << usec_value <<
";";
5630 llvm::StringRef local_name, local_value;
5636 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
5639 output_stream << name <<
":" << value <<
";";
5642 output_stream << name <<
":" << value <<
";";
5677 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5678 "qSaveCore returned an error");
5683 for (
auto x : llvm::split(response.
GetStringRef(),
';')) {
5684 if (x.consume_front(
"core-path:"))
5690 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5691 "qSaveCore returned no core path");
5694 FileSpec remote_core{llvm::StringRef(path)};
5700 platform.
Unlink(remote_core);
5702 return error.ToError();
5708 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5709 "Unable to send qSaveCore");
5722 "GDBRemoteCommunicationClientBase::%s() received $J packet "
5723 "but was not a StructuredData packet: packet starts with "
5736 json_sp->Dump(json_str,
true);
5739 "ProcessGDBRemote::%s() "
5740 "received Async StructuredData packet: %s",
5741 __FUNCTION__, json_str.
GetData());
5744 "ProcessGDBRemote::%s"
5745 "() received StructuredData packet:"
5755 if (structured_data_sp)
5763 "Tests packet speeds of various sizes to determine "
5764 "the performance characteristics of the GDB remote "
5769 "The number of packets to send of each varying size "
5770 "(default is 1000).",
5773 "The maximum number of bytes to send in a packet. Sizes "
5774 "increase in powers of 2 while the size is less than or "
5775 "equal to this option value. (default 1024).",
5778 "The maximum number of bytes to receive in a packet. Sizes "
5779 "increase in powers of 2 while the size is less than or "
5780 "equal to this option value. (default 1024).",
5783 "Print the output as JSON data for easy parsing.", false, true) {
5803 if (!output_stream_sp)
5804 output_stream_sp =
m_interpreter.GetDebugger().GetAsyncOutputStream();
5807 const uint32_t num_packets =
5809 const uint64_t max_send =
m_max_send.GetOptionValue().GetCurrentValue();
5810 const uint64_t max_recv =
m_max_recv.GetOptionValue().GetCurrentValue();
5811 const bool json =
m_json.GetOptionValue().GetCurrentValue();
5812 const uint64_t k_recv_amount =
5815 num_packets, max_send, max_recv, k_recv_amount, json,
5840 "Dumps the packet history buffer. ", nullptr) {}
5861 interpreter,
"process plugin packet xfer-size",
5862 "Maximum size that lldb will try to read/write one one chunk.",
5873 "amount to be transferred when "
5884 uint64_t user_specified_max = strtoul(packet_size,
nullptr, 10);
5885 if (errno == 0 && user_specified_max != 0) {
5900 "Send a custom packet through the GDB remote "
5901 "protocol and print the answer. "
5902 "The packet header and footer will automatically "
5903 "be added to the packet prior to sending and "
5904 "stripped from the result.",
5915 "'%s' takes a one or more packet content arguments",
5923 for (
size_t i = 0; i < argc; ++i) {
5930 output_strm.
Printf(
" packet: %s\n", packet_cstr);
5931 std::string response_str = std::string(response.
GetStringRef());
5933 if (strstr(packet_cstr,
"qGetProfileData") !=
nullptr) {
5937 if (response_str.empty())
5938 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
5951 "Send a qRcmd packet through the GDB remote protocol "
5952 "and print the response. "
5953 "The argument passed to this command will be hex "
5954 "encoded into a valid 'qRcmd' packet, sent and the "
5955 "response will be printed.") {}
5961 if (command.empty()) {
5978 [&output_strm](llvm::StringRef output) { output_strm << output; });
5981 const std::string &response_str = std::string(response.
GetStringRef());
5983 if (response_str.empty())
5984 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
5996 "Commands that deal with GDB remote packets.",
6025 interpreter,
"process plugin",
6026 "Commands for operating on a ProcessGDBRemote process.",
6027 "process plugin <subcommand> [<subcommand-options>]") {
6038 m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(
6039 GetTarget().GetDebugger().GetCommandInterpreter());
6068 addr_t addr = wp_res_sp->GetLoadAddress();
6069 size_t size = wp_res_sp->GetByteSize();
6071 m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,
6089 follow_pid = parent_pid;
6090 follow_tid = parent_tid;
6091 detach_pid = child_pid;
6092 detach_tid = child_tid;
6095 follow_pid = child_pid;
6096 follow_tid = child_tid;
6097 detach_pid = parent_pid;
6098 detach_tid = parent_tid;
6103 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6104 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to set pid/tid");
6118 if (!
m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) ||
6119 !
m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) {
6120 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to reset pid/tid");
6124 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6127 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach packet send failed: {0}",
6128 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6146 "ProcessGDBRemote::DidFork() called for child_pid: {0}, child_tid {1}",
6147 child_pid, child_tid);
6159 detach_pid = child_pid;
6160 detach_tid = child_tid;
6163 detach_pid =
m_gdb_comm.GetCurrentProcessID();
6169 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6170 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to set pid/tid");
6178 if (!
m_gdb_comm.SetCurrentThread(child_tid, child_pid) ||
6179 !
m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) {
6180 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to reset pid/tid");
6186 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6190 "ProcessGDBRemote::DidFork() detach packet send failed: {0}",
6191 error.AsCString() ?
error.AsCString() :
"<unknown error>");
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(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_LOGV(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 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 FileSpec GetDebugserverPath(Platform &platform)
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 IsEnabled() const
Tells whether the current breakpoint site is enabled or not.
void SetEnabled(bool enabled)
Sets whether the current breakpoint site is enabled or not.
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.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
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.
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
const FileSpec & GetFileSpec() const
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)
void void void void void Warning(const char *fmt,...) __attribute__((format(printf
lldb::offset_t GetBlocksize() const
OptionalBool GetFlash() 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.
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.
lldb::StateType GetPrivateState()
void SetUnixSignals(lldb::UnixSignalsSP &&signals_sp)
virtual void ModulesDidLoad(ModuleList &module_list)
void ResumePrivateStateThread()
void MapSupportedStructuredDataPlugins(const StructuredData::Array &supported_type_names)
Loads any plugins associated with asynchronous structured data and maps the relevant supported type n...
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::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.
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.
ThreadSafeValue< lldb::StateType > m_public_state
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
uint32_t AssignIndexIDToThread(uint64_t thread_id)
virtual bool SetExitStatus(int exit_status, llvm::StringRef exit_string)
Set accessor for the process exit status (return code).
MemoryCache m_memory_cache
uint32_t GetAddressByteSize() const
uint32_t GetStopID() const
void SetPrivateState(lldb::StateType state)
void SetSTDIOFileDescriptor(int file_descriptor)
Associates a file descriptor with the process' STDIO handling and configures an asynchronous reading ...
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
ThreadList m_thread_list
The threads for this process as the user will see them.
const lldb::UnixSignalsSP & GetUnixSignals()
std::weak_ptr< Target > m_target_wp
The target that owns this process.
virtual llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > ReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buffer)
Read from multiple memory ranges and write the results into buffer.
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
friend class DynamicLoader
size_t GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site)
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)
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
void ForEach(std::function< bool(llvm::StringRef key, Object *object)> const &callback) const
Dictionary * GetAsDictionary()
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
std::shared_ptr< Array > ArraySP
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.
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)
llvm::Expected< std::string > ReadExtFeature(llvm::StringRef object, llvm::StringRef annex)
void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm)
bool GetQXferLibrariesSVR4ReadSupported()
bool GetQXferLibrariesReadSupported()
void DumpHistory(Stream &strm)
Status FlashErase(lldb::addr_t addr, size_t size)
Status DisableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
friend class ThreadGDBRemote
DataExtractor GetAuxvData() override
GDBRemoteCommunicationClient & GetGDBRemote()
Status DoConnectRemote(llvm::StringRef remote_url) override
Attach to a remote system via a URL.
void HandleAsyncStructuredDataPacket(llvm::StringRef data) override
Process asynchronously-received structured data.
void KillDebugserverProcess()
Status DoDestroy() override
Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info)
StructuredData::ObjectSP m_jstopinfo_sp
virtual std::shared_ptr< ThreadGDBRemote > CreateThread(lldb::tid_t tid)
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)
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 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...
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
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 DidForkSwitchSoftwareBreakpoints(bool enable)
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)
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::SmallVector< llvm::MutableArrayRef< uint8_t > > ReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buf) override
Override of ReadMemoryRanges that uses MultiMemRead to optimize this operation.
bool UpdateThreadIDList()
static llvm::StringRef GetPluginNameStatic()
void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override
Called after a reported fork.
StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos() override
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.
void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override
Called after a reported vfork.
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.
lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr, bool value_is_offset)
void SetLastStopPacket(const StringExtractorGDBRemote &response)
lldb::thread_result_t AsyncThread()
Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries) override
llvm::Error LoadModules() override
Sometimes processes know how to retrieve and load shared libraries.
uint64_t m_max_memory_size
void HandleAsyncMisc(llvm::StringRef data) override
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path, bool can_connect)
void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple) override
llvm::VersionTuple GetHostMacCatalystVersion() override
void DidForkSwitchHardwareTraps(bool enable)
HostThread m_async_thread
StructuredData::ObjectSP GetDynamicLoaderProcessState() override
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override
Try to fetch the module specification for a module with the given file name and architecture.
llvm::StringMap< std::unique_ptr< RegisterFlags > > m_registers_flags_types
Status DoWillLaunch(Module *module) override
Called before launching to a process.
void DidAttach(ArchSpec &process_arch) override
Called after attaching a process.
llvm::Expected< bool > SaveCore(llvm::StringRef outfile) override
Save core dump into the specified file.
std::atomic< lldb::pid_t > m_debugserver_pid
llvm::Expected< std::string > TraceGetState(llvm::StringRef type) override
Get the current tracing state of the process and its threads.
bool IsAlive() override
Check if a process is still alive.
void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override
void SetQueueInfo(std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue)
void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr)
lldb::RegisterContextSP GetRegisterContext() override
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.
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
std::shared_ptr< lldb_private::Target > TargetSP
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