9#include "lldb/Host/Config.h"
14#include <netinet/in.h>
17#include <sys/socket.h>
22#include <sys/sysctl.h>
104#include "llvm/ADT/STLExtras.h"
105#include "llvm/ADT/ScopeExit.h"
106#include "llvm/ADT/StringMap.h"
107#include "llvm/ADT/StringSwitch.h"
108#include "llvm/Support/Chrono.h"
109#include "llvm/Support/ErrorExtras.h"
110#include "llvm/Support/FormatAdapters.h"
111#include "llvm/Support/Threading.h"
112#include "llvm/Support/raw_ostream.h"
114#if defined(__APPLE__)
115#define DEBUGSERVER_BASENAME "debugserver"
117#define DEBUGSERVER_BASENAME "lldb-server.exe"
119#define DEBUGSERVER_BASENAME "lldb-server"
139 llvm::consumeError(file.takeError());
143 ((
Process *)p)->DumpPluginHistory(stream);
149#define LLDB_PROPERTIES_processgdbremote
150#include "ProcessGDBRemoteProperties.inc"
153#define LLDB_PROPERTIES_processgdbremote
154#include "ProcessGDBRemotePropertiesEnum.inc"
159 static llvm::StringRef GetSettingName() {
163 PluginProperties() : Properties() {
164 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
165 m_collection_sp->Initialize(g_processgdbremote_properties_def);
168 ~PluginProperties()
override =
default;
170 uint64_t GetPacketTimeout() {
171 const uint32_t idx = ePropertyPacketTimeout;
172 return GetPropertyAtIndexAs<uint64_t>(
173 idx, g_processgdbremote_properties[idx].default_uint_value);
176 bool SetPacketTimeout(uint64_t timeout) {
177 const uint32_t idx = ePropertyPacketTimeout;
178 return SetPropertyAtIndex(idx, timeout);
181 FileSpec GetTargetDefinitionFile()
const {
182 const uint32_t idx = ePropertyTargetDefinitionFile;
183 return GetPropertyAtIndexAs<FileSpec>(idx, {});
186 bool GetUseSVR4()
const {
187 const uint32_t idx = ePropertyUseSVR4;
188 return GetPropertyAtIndexAs<bool>(
189 idx, g_processgdbremote_properties[idx].default_uint_value != 0);
192 bool GetUseGPacketForReading()
const {
193 const uint32_t idx = ePropertyUseGPacketForReading;
194 return GetPropertyAtIndexAs<bool>(idx,
true);
197 uint64_t GetPacketTestDelay()
const {
198 const uint32_t idx = ePropertyPacketTestDelay;
199 return GetPropertyAtIndexAs<uint64_t>(
200 idx, g_processgdbremote_properties[idx].default_uint_value);
204std::chrono::seconds ResumeTimeout() {
return std::chrono::seconds(5); }
206static std::pair<uint16_t, uint16_t> GetClientTerminalSize() {
208 CONSOLE_SCREEN_BUFFER_INFO csbi{};
209 HANDLE h = ::GetStdHandle(STD_OUTPUT_HANDLE);
210 if (h != INVALID_HANDLE_VALUE && ::GetConsoleScreenBufferInfo(h, &csbi)) {
211 int cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
212 int rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
213 if (cols > 0 && rows > 0)
214 return {
static_cast<uint16_t
>(cols),
static_cast<uint16_t
>(rows)};
216#elif LLDB_ENABLE_POSIX
218 if (::ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0 &&
220 return {ws.ws_col, ws.ws_row};
228 static PluginProperties g_settings;
236#if defined(__APPLE__)
237#define LOW_PORT (IPPORT_RESERVED)
238#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
240#define LOW_PORT (1024u)
241#define HIGH_PORT (49151u)
245 return "GDB Remote protocol based debugging plug-in.";
254 const FileSpec *crash_file_path,
bool can_connect) {
270 return std::chrono::milliseconds(
279 bool plugin_specified_by_name) {
280 if (plugin_specified_by_name)
284 Module *exe_module = target_sp->GetExecutableModulePointer();
288 switch (exe_objfile->
GetType()) {
312 :
Process(target_sp, listener_sp),
316 Listener::MakeListener(
"lldb.process.gdb-remote.async-listener")),
327 "async thread should exit");
329 "async thread continue");
331 "async thread did exit");
335 const uint32_t async_event_mask =
341 "ProcessGDBRemote::%s failed to listen for "
342 "m_async_broadcaster events",
346 const uint64_t timeout_seconds =
348 if (timeout_seconds > 0)
349 m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
357 llvm::sys::TimePoint<> now = std::chrono::system_clock::now();
358 std::string name = llvm::formatv(
359 "gdb-remote-packet-history-{0:%Y-%m-%dT%H-%M-%S}.txt", now);
361 std::move(name), [
this]() -> std::string {
392std::shared_ptr<ThreadGDBRemote>
394 return std::make_shared<ThreadGDBRemote>(*
this, tid);
398 const FileSpec &target_definition_fspec) {
404 if (module_object_sp) {
407 "gdb-server-target-definition",
error));
409 if (target_definition_sp) {
411 target_definition_sp->GetValueForKey(
"host-info"));
413 if (
auto host_info_dict = target_object->GetAsDictionary()) {
415 host_info_dict->GetValueForKey(
"triple");
416 if (
auto triple_string_value = triple_value->GetAsString()) {
417 std::string triple_string =
418 std::string(triple_string_value->GetValue());
419 ArchSpec host_arch(triple_string.c_str());
428 target_definition_sp->GetValueForKey(
"breakpoint-pc-offset");
429 if (breakpoint_pc_offset_value) {
430 if (
auto breakpoint_pc_int_value =
431 breakpoint_pc_offset_value->GetAsSignedInteger())
436 *target_definition_sp,
GetTarget().GetArchitecture()) > 0) {
445 const llvm::StringRef &comma_separated_register_numbers,
446 std::vector<uint32_t> ®nums,
int base) {
448 for (llvm::StringRef x : llvm::split(comma_separated_register_numbers,
',')) {
450 if (llvm::to_integer(x, reg, base))
451 regnums.push_back(reg);
453 return regnums.size();
465 const auto host_packet_timeout =
m_gdb_comm.GetHostDefaultPacketTimeout();
466 if (host_packet_timeout > std::chrono::seconds(0)) {
484 if (target_definition_fspec) {
490 target_definition_fspec.
GetPath() +
501 if (remote_process_arch.
IsValid())
502 arch_to_use = remote_process_arch;
504 arch_to_use = remote_host_arch;
507 arch_to_use = target_arch;
510 if (!register_info_err) {
517 "Failed to read register information from target XML: {0}");
518 LLDB_LOG(log,
"Now trying to use qRegisterInfo instead.");
521 std::vector<DynamicRegisterInfo::Register> registers;
522 uint32_t reg_num = 0;
526 const int packet_len =
527 ::snprintf(packet,
sizeof(packet),
"qRegisterInfo%x", reg_num);
528 assert(packet_len < (
int)
sizeof(packet));
531 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
535 llvm::StringRef name;
536 llvm::StringRef value;
540 if (name ==
"name") {
542 }
else if (name ==
"alt-name") {
544 }
else if (name ==
"bitsize") {
547 }
else if (name ==
"offset") {
549 }
else if (name ==
"encoding") {
553 }
else if (name ==
"format") {
557 llvm::StringSwitch<Format>(value)
599 }
else if (name ==
"set") {
601 }
else if (name ==
"gcc" || name ==
"ehframe") {
603 }
else if (name ==
"dwarf") {
605 }
else if (name ==
"generic") {
607 }
else if (name ==
"container-regs") {
609 }
else if (name ==
"invalidate-regs") {
615 registers.push_back(reg_info);
628 "the debug server supports Target Description XML but LLDB does "
629 "not have XML parsing enabled. Using \"qRegisterInfo\" was also "
630 "not possible. Register information may be incorrect or missing",
640 if (registers.empty()) {
642 if (!registers.empty())
645 "All other methods failed, using fallback register information.");
660 bool wait_for_launch) {
692 if (
m_gdb_comm.GetProcessArchitecture().IsValid()) {
695 if (
m_gdb_comm.GetHostArchitecture().IsValid()) {
706 "Process %" PRIu64
" was reported after connecting to "
707 "'%s', but state was not stopped: %s",
711 "Process %" PRIu64
" was reported after connecting to '%s', "
712 "but no stop reply packet was received",
713 pid, remote_url.str().c_str());
717 "ProcessGDBRemote::%s pid %" PRIu64
718 ": normalizing target architecture initial triple: %s "
719 "(GetTarget().GetArchitecture().IsValid() %s, "
720 "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
721 __FUNCTION__,
GetID(),
722 GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
724 m_gdb_comm.GetHostArchitecture().IsValid() ?
"true" :
"false");
730 if (
m_gdb_comm.GetProcessArchitecture().IsValid())
737 "ProcessGDBRemote::%s pid %" PRIu64
738 ": normalized target architecture triple: %s",
739 __FUNCTION__,
GetID(),
740 GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
757 LLDB_LOGF(log,
"ProcessGDBRemote::%s() entered", __FUNCTION__);
759 uint32_t launch_flags = launch_info.
GetFlags().
Get();
782 if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
784 "ProcessGDBRemote::%s provided with STDIO paths via "
785 "launch_info: stdin=%s, stdout=%s, stderr=%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>");
791 LLDB_LOGF(log,
"ProcessGDBRemote::%s no STDIO paths given via launch_info",
794 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
795 if (stdin_file_spec || disable_stdio) {
810 if (
error.Success()) {
812 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
817 if (!stdin_file_spec)
819 FileSpec::Style::native);
820 if (!stdout_file_spec)
822 FileSpec::Style::native);
823 if (!stderr_file_spec)
825 FileSpec::Style::native);
826 }
else if (platform_sp && platform_sp->IsHost()) {
831 if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
835 if (!stdin_file_spec)
836 stdin_file_spec = secondary_name;
838 if (!stdout_file_spec)
839 stdout_file_spec = secondary_name;
841 if (!stderr_file_spec)
842 stderr_file_spec = secondary_name;
846 "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
847 "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
850 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
851 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
852 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
856 "ProcessGDBRemote::%s final STDIO paths after all "
857 "adjustments: stdin=%s, stdout=%s, stderr=%s",
859 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
860 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
861 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
865 if (stdout_file_spec)
867 if (stderr_file_spec)
870 if (launch_flags & eLaunchFlagUsePipes) {
873 auto [terminal_cols, terminal_rows] = GetClientTerminalSize();
874 m_gdb_comm.SetSTDIOWindowSize(terminal_cols, terminal_rows);
877 m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
878 m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
881 GetTarget().GetArchitecture().GetArchitectureName());
884 if (launch_event_data !=
nullptr && *launch_event_data !=
'\0')
885 m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
897 std::chrono::seconds(10));
903 const llvm::Triple &remote_triple =
905 if (remote_triple.getOS() != llvm::Triple::UnknownOS) {
906 FileSpec remote_exe_file(exe_file.GetPath(
false),
909 0, remote_exe_file.
GetPath(
true));
912 exe_file.GetPath(
true));
915 if (llvm::Error err =
m_gdb_comm.LaunchProcess(args)) {
918 llvm::fmt_consume(std::move(err)));
925 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
947 if (!disable_stdio) {
957 std::make_shared<IOHandlerProcessSTDIOWindows>(
this);
963 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
error.AsCString());
973 if (!connect_url.empty()) {
974 LLDB_LOGF(log,
"ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
975 connect_url.str().c_str());
976 std::unique_ptr<ConnectionFileDescriptor> conn_up(
979 const uint32_t max_retry_count = 50;
980 uint32_t retry_count = 0;
989 if (retry_count >= max_retry_count)
992 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1009 if (
error.Success())
1016 m_gdb_comm.GetListThreadsInStopReplySupported();
1026 auto handle_cmds = [&] (
const Args &args) ->
void {
1030 entry.c_str(), response);
1036 handle_cmds(platform_sp->GetExtraStartupCommands());
1053 if (remote_process_arch.
IsValid()) {
1054 process_arch = remote_process_arch;
1055 LLDB_LOG(log,
"gdb-remote had process architecture, using {0} {1}",
1059 process_arch =
m_gdb_comm.GetHostArchitecture();
1061 "gdb-remote did not have process architecture, using gdb-remote "
1062 "host architecture {0} {1}",
1073 LLDB_LOG(log,
"analyzing target arch, currently {0} {1}",
1085 if ((process_arch.
GetMachine() == llvm::Triple::arm ||
1086 process_arch.
GetMachine() == llvm::Triple::thumb) &&
1087 process_arch.
GetTriple().getVendor() == llvm::Triple::Apple) {
1090 "remote process is ARM/Apple, "
1091 "setting target arch to {0} {1}",
1096 const llvm::Triple &remote_triple = process_arch.
GetTriple();
1097 llvm::Triple new_target_triple = target_arch.
GetTriple();
1098 if (new_target_triple.getVendorName().size() == 0) {
1099 new_target_triple.setVendor(remote_triple.getVendor());
1101 if (new_target_triple.getOSName().size() == 0) {
1102 new_target_triple.setOS(remote_triple.getOS());
1104 if (new_target_triple.getEnvironmentName().size() == 0)
1105 new_target_triple.setEnvironment(remote_triple.getEnvironment());
1108 ArchSpec new_target_arch = target_arch;
1109 new_target_arch.
SetTriple(new_target_triple);
1115 "final target arch after adjustments for remote architecture: "
1134 m_gdb_comm.GetSupportedStructuredDataPlugins())
1143 if (platform_sp && platform_sp->IsConnected())
1151 llvm::Expected<std::vector<AcceleratorActions>> init_actions =
1152 m_gdb_comm.GetAcceleratorInitializeActions();
1153 if (!init_actions) {
1155 "failed to get accelerator initialize actions: {0}");
1160 "failed to handle accelerator actions: {0}");
1170 UUID standalone_uuid;
1172 bool standalone_value_is_offset;
1173 if (
m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value,
1174 standalone_value_is_offset)) {
1175 if (standalone_uuid.
IsValid()) {
1177 bin_spec.
uuid = standalone_uuid;
1178 bin_spec.
value = standalone_value;
1183 llvm::Expected<ModuleSP> module =
1187 << llvm::toString(module.takeError()) <<
"\n";
1199 std::vector<addr_t> bin_addrs =
m_gdb_comm.GetProcessStandaloneBinaries();
1200 if (bin_addrs.size()) {
1201 for (
addr_t addr : bin_addrs) {
1202 const bool notify =
true;
1209 .LoadPlatformBinaryAndSetup(
this, addr, notify))
1214 bin_spec.
value = addr;
1216 bin_spec.
notify = notify;
1218 llvm::Expected<ModuleSP> module =
1222 << llvm::toString(module.takeError()) <<
"\n";
1232 std::optional<QOffsets> offsets =
m_gdb_comm.GetQOffsets();
1237 size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==
1238 offsets->offsets.size();
1242 bool changed =
false;
1243 module_sp->SetLoadAddress(
GetTarget(), offsets->offsets[0],
1248 m_process->GetTarget().ModulesDidLoad(list);
1262 LLDB_LOGF(log,
"ProcessGDBRemote::%s()", __FUNCTION__);
1268 if (
error.Success()) {
1272 const int packet_len =
1273 ::snprintf(packet,
sizeof(packet),
"vAttach;%" PRIx64, attach_pid);
1276 std::make_shared<EventDataBytes>(llvm::StringRef(packet, packet_len));
1291 if (process_name && process_name[0]) {
1293 if (
error.Success()) {
1299 if (!
m_gdb_comm.GetVAttachOrWaitSupported()) {
1314 auto data_sp = std::make_shared<EventDataBytes>(packet.
GetString());
1335llvm::Expected<std::string>
1340llvm::Expected<std::vector<uint8_t>>
1352 process_arch.
Clear();
1368 return m_gdb_comm.GetReverseStepSupported() ||
1375 LLDB_LOGF(log,
"ProcessGDBRemote::Resume(%s)",
1380 if (listener_sp->StartListeningForEvents(
1382 listener_sp->StartListeningForEvents(
1389 bool continue_packet_error =
false;
1403 std::string pid_prefix;
1405 pid_prefix = llvm::formatv(
"p{0:x-}.",
GetID());
1407 if (num_continue_c_tids == num_threads ||
1412 continue_packet.
Format(
"vCont;c:{0}-1", pid_prefix);
1420 for (tid_collection::const_iterator
1423 t_pos != t_end; ++t_pos)
1424 continue_packet.
Format(
";c:{0}{1:x-}", pid_prefix, *t_pos);
1426 continue_packet_error =
true;
1431 for (tid_sig_collection::const_iterator
1434 s_pos != s_end; ++s_pos)
1435 continue_packet.
Format(
";C{0:x-2}:{1}{2:x-}", s_pos->second,
1436 pid_prefix, s_pos->first);
1438 continue_packet_error =
true;
1443 for (tid_collection::const_iterator
1446 t_pos != t_end; ++t_pos)
1447 continue_packet.
Format(
";s:{0}{1:x-}", pid_prefix, *t_pos);
1449 continue_packet_error =
true;
1454 for (tid_sig_collection::const_iterator
1457 s_pos != s_end; ++s_pos)
1458 continue_packet.
Format(
";S{0:x-2}:{1}{2:x-}", s_pos->second,
1459 pid_prefix, s_pos->first);
1461 continue_packet_error =
true;
1464 if (continue_packet_error)
1465 continue_packet.
Clear();
1468 continue_packet_error =
true;
1474 if (num_continue_c_tids > 0) {
1475 if (num_continue_c_tids == num_threads) {
1479 continue_packet_error =
false;
1480 }
else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
1481 num_continue_s_tids == 0 && num_continue_S_tids == 0) {
1485 continue_packet_error =
false;
1489 if (continue_packet_error && num_continue_C_tids > 0) {
1490 if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
1491 num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
1492 num_continue_S_tids == 0) {
1495 if (num_continue_C_tids > 1) {
1500 if (num_continue_C_tids > 1) {
1501 continue_packet_error =
false;
1504 continue_packet_error =
true;
1507 if (!continue_packet_error)
1511 continue_packet_error =
false;
1514 if (!continue_packet_error) {
1516 continue_packet.
Printf(
"C%2.2x", continue_signo);
1521 if (continue_packet_error && num_continue_s_tids > 0) {
1522 if (num_continue_s_tids == num_threads) {
1528 continue_packet_error =
false;
1529 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1530 num_continue_s_tids == 1 && num_continue_S_tids == 0) {
1534 continue_packet_error =
false;
1538 if (!continue_packet_error && num_continue_S_tids > 0) {
1539 if (num_continue_S_tids == num_threads) {
1542 continue_packet_error =
false;
1543 if (num_continue_S_tids > 1) {
1544 for (
size_t i = 1; i < num_threads; ++i) {
1546 continue_packet_error =
true;
1549 if (!continue_packet_error) {
1552 continue_packet.
Printf(
"S%2.2x", step_signo);
1554 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1555 num_continue_s_tids == 0 && num_continue_S_tids == 1) {
1559 continue_packet_error =
false;
1565 if (num_continue_s_tids > 0 || num_continue_S_tids > 0) {
1567 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1568 "support reverse-stepping");
1570 "target does not support reverse-stepping");
1573 if (num_continue_S_tids > 0) {
1576 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1578 "can't deliver signals while running in reverse");
1581 if (num_continue_s_tids > 1) {
1582 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: can't step multiple "
1583 "threads in reverse");
1585 "can't step multiple threads while reverse-stepping");
1591 if (!
m_gdb_comm.GetReverseContinueSupported()) {
1592 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1593 "support reverse-continue");
1595 "target does not support reverse execution of processes");
1598 if (num_continue_C_tids > 0) {
1601 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1603 "can't deliver signals while running in reverse");
1611 continue_packet_error =
false;
1614 if (continue_packet_error) {
1616 "can't make continue packet for this resume");
1621 "Trying to resume but the async thread is dead.");
1622 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Trying to resume but the "
1623 "async thread is dead.");
1628 std::make_shared<EventDataBytes>(continue_packet.
GetString());
1631 if (!listener_sp->GetEvent(event_sp, ResumeTimeout())) {
1633 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Resume timed out.");
1636 "Broadcast continue, but the async thread was "
1637 "killed before we got an ack back.");
1639 "ProcessGDBRemote::DoResume: Broadcast continue, but the "
1640 "async thread was killed before we got an ack back.");
1656 llvm::StringRef value) {
1662 auto pid_tid = thread_ids.
GetPidTid(pid);
1663 if (pid_tid && pid_tid->first == pid) {
1669 }
while (thread_ids.
GetChar() ==
',');
1675 llvm::StringRef value) {
1677 for (llvm::StringRef x : llvm::split(value,
',')) {
1679 if (llvm::to_integer(x,
pc, 16))
1691 if (thread_infos && thread_infos->
GetSize() > 0) {
1715 const llvm::StringRef stop_info_str = stop_info.
GetStringRef();
1718 const size_t thread_pcs_pos = stop_info_str.find(
";thread-pcs:");
1719 if (thread_pcs_pos != llvm::StringRef::npos) {
1720 const size_t start = thread_pcs_pos + strlen(
";thread-pcs:");
1721 const size_t end = stop_info_str.find(
';', start);
1722 if (end != llvm::StringRef::npos) {
1723 llvm::StringRef value = stop_info_str.substr(start, end - start);
1728 const size_t threads_pos = stop_info_str.find(
";threads:");
1729 if (threads_pos != llvm::StringRef::npos) {
1730 const size_t start = threads_pos + strlen(
";threads:");
1731 const size_t end = stop_info_str.find(
';', start);
1732 if (end != llvm::StringRef::npos) {
1733 llvm::StringRef value = stop_info_str.substr(start, end - start);
1741 bool sequence_mutex_unavailable =
false;
1743 if (sequence_mutex_unavailable) {
1758 if (num_thread_ids == 0) {
1764 ThreadList old_thread_list_copy(old_thread_list);
1765 if (num_thread_ids > 0) {
1766 for (
size_t i = 0; i < num_thread_ids; ++i) {
1773 thread_sp.get(), thread_sp->GetID());
1776 thread_sp.get(), thread_sp->GetID());
1786 size_t old_num_thread_ids = old_thread_list_copy.
GetSize(
false);
1787 for (
size_t i = 0; i < old_num_thread_ids; i++) {
1789 if (old_thread_sp) {
1790 lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
1805 uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1818 if (thread_infos_sp) {
1822 const size_t n = thread_infos->
GetSize();
1823 for (
size_t i = 0; i < n; ++i) {
1829 if (tid == thread->GetID())
1853 addr_t pc = thread->GetRegisterContext()->GetPC();
1855 thread->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1857 thread->SetThreadStoppedAtUnexecutedBP(
pc);
1865 if (
GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
1875 for (
const auto &pair : expedited_register_map) {
1876 uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1886 reg_value_extractor.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
1894 uint8_t signo,
const std::string &thread_name,
const std::string &reason,
1895 const std::string &description, uint32_t exc_type,
1896 const std::vector<addr_t> &exc_data,
addr_t thread_dispatch_qaddr,
1897 bool queue_vars_valid,
1899 LazyBool associated_with_dispatch_queue,
addr_t dispatch_queue_t,
1900 std::string &queue_name,
QueueKind queue_kind, uint64_t queue_serial,
1901 std::vector<lldb::addr_t> &added_binaries,
1926 reg_ctx_sp->InvalidateIfNeeded(
true);
1934 if (reg_ctx_sp->ReconfigureRegisterInfo()) {
1937 reg_ctx_sp->InvalidateAllRegisters();
1944 thread_sp->SetName(thread_name.empty() ?
nullptr : thread_name.c_str());
1949 if (queue_vars_valid)
1950 gdb_thread->
SetQueueInfo(std::move(queue_name), queue_kind, queue_serial,
1951 dispatch_queue_t, associated_with_dispatch_queue);
1965 StopInfoSP current_stop_info_sp = thread_sp->GetPrivateStopInfo(
false);
1967 current_stop_info_sp) {
1968 thread_sp->SetStopInfo(current_stop_info_sp);
1972 if (!thread_sp->StopInfoIsUpToDate()) {
1975 addr_t pc = thread_sp->GetRegisterContext()->GetPC();
1977 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1979 thread_sp->SetThreadStoppedAtUnexecutedBP(
pc);
1981 if (exc_type != 0) {
1989 if (interrupt_thread)
1990 thread_sp = interrupt_thread;
1992 const size_t exc_data_size = exc_data.size();
1993 thread_sp->SetStopInfo(
1995 *thread_sp, exc_type, exc_data_size,
1996 exc_data_size >= 1 ? exc_data[0] : 0,
1997 exc_data_size >= 2 ? exc_data[1] : 0,
1998 exc_data_size >= 3 ? exc_data[2] : 0));
2001 bool handled =
false;
2002 bool did_exec =
false;
2005 if (!reason.empty() && reason !=
"none") {
2006 if (reason ==
"trace") {
2009 }
else if (reason ==
"breakpoint") {
2010 thread_sp->SetThreadHitBreakpointSite();
2018 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2019 thread_sp->SetStopInfo(
2021 *thread_sp, bp_site_sp->GetID()));
2024 thread_sp->SetStopInfo(invalid_stop_info_sp);
2027 }
else if (reason ==
"trap") {
2029 }
else if (reason ==
"watchpoint") {
2065 bool silently_continue =
false;
2075 silently_continue =
true;
2079 if (!wp_resource_sp) {
2081 LLDB_LOGF(log,
"failed to find watchpoint");
2088 watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
2091 *thread_sp, watch_id, silently_continue));
2093 }
else if (reason ==
"exception") {
2095 *thread_sp, description.c_str()));
2097 }
else if (reason ==
"history boundary") {
2099 *thread_sp, description.c_str()));
2101 }
else if (reason ==
"exec") {
2103 thread_sp->SetStopInfo(
2106 }
else if (reason ==
"processor trace") {
2108 *thread_sp, description.c_str()));
2109 }
else if (reason ==
"fork") {
2114 thread_sp->SetStopInfo(
2117 }
else if (reason ==
"vfork") {
2123 *thread_sp, child_pid, child_tid));
2125 }
else if (reason ==
"vforkdone") {
2126 thread_sp->SetStopInfo(
2132 if (!handled && signo && !did_exec) {
2153 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
2163 thread_sp->SetThreadHitBreakpointSite();
2165 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2167 thread_sp->GetRegisterContext()->SetPC(
pc);
2168 thread_sp->SetStopInfo(
2170 *thread_sp, bp_site_sp->GetID()));
2173 thread_sp->SetStopInfo(invalid_stop_info_sp);
2179 thread_sp->SetStopInfo(
2183 *thread_sp, signo, description.c_str()));
2194 if (interrupt_thread)
2195 thread_sp = interrupt_thread;
2198 *thread_sp, signo, description.c_str()));
2202 if (!description.empty()) {
2205 const char *stop_info_desc = stop_info_sp->GetDescription();
2206 if (!stop_info_desc || !stop_info_desc[0])
2207 stop_info_sp->SetDescription(description.c_str());
2210 *thread_sp, description.c_str()));
2220 const std::string &description) {
2229 *thread_sp, signo, description.c_str()));
2238 static constexpr llvm::StringLiteral g_key_tid(
"tid");
2239 static constexpr llvm::StringLiteral g_key_name(
"name");
2240 static constexpr llvm::StringLiteral g_key_reason(
"reason");
2241 static constexpr llvm::StringLiteral g_key_metype(
"metype");
2242 static constexpr llvm::StringLiteral g_key_medata(
"medata");
2243 static constexpr llvm::StringLiteral g_key_qaddr(
"qaddr");
2244 static constexpr llvm::StringLiteral g_key_dispatch_queue_t(
2245 "dispatch_queue_t");
2246 static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(
2247 "associated_with_dispatch_queue");
2248 static constexpr llvm::StringLiteral g_key_queue_name(
"qname");
2249 static constexpr llvm::StringLiteral g_key_queue_kind(
"qkind");
2250 static constexpr llvm::StringLiteral g_key_queue_serial_number(
"qserialnum");
2251 static constexpr llvm::StringLiteral g_key_registers(
"registers");
2252 static constexpr llvm::StringLiteral g_key_memory(
"memory");
2253 static constexpr llvm::StringLiteral g_key_description(
"description");
2254 static constexpr llvm::StringLiteral g_key_signal(
"signal");
2255 static constexpr llvm::StringLiteral g_key_added_binaries(
"added-binaries");
2256 static constexpr llvm::StringLiteral g_key_detailed_binaries_info(
2257 "detailed-binaries-info");
2262 std::string thread_name;
2264 std::string description;
2265 uint32_t exc_type = 0;
2266 std::vector<addr_t> exc_data;
2269 bool queue_vars_valid =
false;
2272 std::string queue_name;
2274 uint64_t queue_serial_number = 0;
2275 std::vector<addr_t> added_binaries;
2281 thread_dict->
ForEach([
this, &tid, &expedited_register_map, &thread_name,
2282 &signo, &reason, &description, &exc_type, &exc_data,
2283 &thread_dispatch_qaddr, &queue_vars_valid,
2284 &associated_with_dispatch_queue, &dispatch_queue_t,
2285 &queue_name, &queue_kind, &queue_serial_number,
2286 &added_binaries, &detailed_binaries_info](
2287 llvm::StringRef key,
2289 if (key == g_key_tid) {
2292 }
else if (key == g_key_metype) {
2294 exc_type =
object->GetUnsignedIntegerValue(0);
2295 }
else if (key == g_key_medata) {
2300 exc_data.push_back(object->GetUnsignedIntegerValue());
2304 }
else if (key == g_key_name) {
2305 thread_name = std::string(object->GetStringValue());
2306 }
else if (key == g_key_qaddr) {
2307 thread_dispatch_qaddr =
2309 }
else if (key == g_key_queue_name) {
2310 queue_vars_valid =
true;
2311 queue_name = std::string(object->GetStringValue());
2312 }
else if (key == g_key_queue_kind) {
2313 std::string queue_kind_str = std::string(object->GetStringValue());
2314 if (queue_kind_str ==
"serial") {
2315 queue_vars_valid =
true;
2317 }
else if (queue_kind_str ==
"concurrent") {
2318 queue_vars_valid =
true;
2321 }
else if (key == g_key_queue_serial_number) {
2322 queue_serial_number =
object->GetUnsignedIntegerValue(0);
2323 if (queue_serial_number != 0)
2324 queue_vars_valid =
true;
2325 }
else if (key == g_key_dispatch_queue_t) {
2326 dispatch_queue_t =
object->GetUnsignedIntegerValue(0);
2328 queue_vars_valid =
true;
2329 }
else if (key == g_key_associated_with_dispatch_queue) {
2330 queue_vars_valid =
true;
2331 bool associated =
object->GetBooleanValue();
2336 }
else if (key == g_key_reason) {
2337 reason = std::string(object->GetStringValue());
2338 }
else if (key == g_key_description) {
2339 description = std::string(object->GetStringValue());
2340 }
else if (key == g_key_registers) {
2343 if (registers_dict) {
2345 [&expedited_register_map](llvm::StringRef key,
2348 if (llvm::to_integer(key, reg))
2349 expedited_register_map[reg] =
2350 std::string(object->GetStringValue());
2354 }
else if (key == g_key_memory) {
2360 if (mem_cache_dict) {
2363 "address", mem_cache_addr)) {
2365 llvm::StringRef str;
2370 const size_t byte_size = bytes.
GetStringRef().size() / 2;
2373 const size_t bytes_copied =
2375 if (bytes_copied == byte_size)
2385 }
else if (key == g_key_signal)
2387 else if (key == g_key_added_binaries) {
2390 array->
ForEach([&added_binaries](
2393 object->GetAsUnsignedInteger();
2397 added_binaries.push_back(value);
2402 }
else if (key == g_key_detailed_binaries_info) {
2407 if (object->GetAsDictionary()) {
2409 object->Dump(json_str);
2410 detailed_binaries_info =
2418 tid, expedited_register_map, signo, thread_name, reason, description,
2419 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2420 associated_with_dispatch_queue, dispatch_queue_t, queue_name, queue_kind,
2421 queue_serial_number, added_binaries, detailed_binaries_info);
2427 const char stop_type = stop_packet.
GetChar();
2428 switch (stop_type) {
2447 const uint8_t signo = stop_packet.
GetHexU8();
2448 llvm::StringRef key;
2449 llvm::StringRef value;
2450 std::string thread_name;
2452 std::string description;
2453 std::vector<addr_t> added_binaries;
2455 uint32_t exc_type = 0;
2456 std::vector<addr_t> exc_data;
2458 bool queue_vars_valid =
2462 std::string queue_name;
2464 uint64_t queue_serial_number = 0;
2468 if (key.compare(
"metype") == 0) {
2470 value.getAsInteger(
BASE_16, exc_type);
2471 }
else if (key.compare(
"medata") == 0) {
2474 value.getAsInteger(
BASE_16, x);
2475 exc_data.push_back(x);
2476 }
else if (key.compare(
"thread") == 0) {
2479 auto pid_tid = thread_id.
GetPidTid(pid);
2481 stop_pid = pid_tid->first;
2482 tid = pid_tid->second;
2485 }
else if (key.compare(
"threads") == 0) {
2486 std::lock_guard<std::recursive_mutex> guard(
2489 }
else if (key.compare(
"thread-pcs") == 0) {
2494 while (!value.empty()) {
2495 llvm::StringRef pc_str;
2496 std::tie(pc_str, value) = value.split(
',');
2501 }
else if (key.compare(
"jstopinfo") == 0) {
2510 }
else if (key.compare(
"hexname") == 0) {
2514 }
else if (key.compare(
"name") == 0) {
2515 thread_name = std::string(value);
2516 }
else if (key.compare(
"qaddr") == 0) {
2517 value.getAsInteger(
BASE_16, thread_dispatch_qaddr);
2518 }
else if (key.compare(
"dispatch_queue_t") == 0) {
2519 queue_vars_valid =
true;
2520 value.getAsInteger(
BASE_16, dispatch_queue_t);
2521 }
else if (key.compare(
"qname") == 0) {
2522 queue_vars_valid =
true;
2526 }
else if (key.compare(
"qkind") == 0) {
2527 queue_kind = llvm::StringSwitch<QueueKind>(value)
2532 }
else if (key.compare(
"qserialnum") == 0) {
2533 if (!value.getAsInteger(
BASE_10, queue_serial_number))
2534 queue_vars_valid =
true;
2535 }
else if (key.compare(
"reason") == 0) {
2536 reason = std::string(value);
2537 }
else if (key.compare(
"description") == 0) {
2541 }
else if (key.compare(
"memory") == 0) {
2555 llvm::StringRef addr_str, bytes_str;
2556 std::tie(addr_str, bytes_str) = value.split(
'=');
2557 if (!addr_str.empty() && !bytes_str.empty()) {
2564 const size_t bytes_copied =
2566 if (bytes_copied == byte_size)
2570 }
else if (key.compare(
"watch") == 0 || key.compare(
"rwatch") == 0 ||
2571 key.compare(
"awatch") == 0) {
2574 value.getAsInteger(
BASE_16, wp_addr);
2582 reason =
"watchpoint";
2584 ostr.
Printf(
"%" PRIu64, wp_addr);
2585 description = std::string(ostr.
GetString());
2586 }
else if (key.compare(
"swbreak") == 0 || key.compare(
"hwbreak") == 0) {
2587 reason =
"breakpoint";
2588 }
else if (key.compare(
"replaylog") == 0) {
2589 reason =
"history boundary";
2590 }
else if (key.compare(
"library") == 0) {
2596 }
else if (key.compare(
"fork") == 0 || key.compare(
"vfork") == 0) {
2602 LLDB_LOG(log,
"Invalid PID/TID to fork: {0}", value);
2608 ostr.
Printf(
"%" PRIu64
" %" PRIu64, pid_tid->first, pid_tid->second);
2609 description = std::string(ostr.
GetString());
2610 }
else if (key.compare(
"addressing_bits") == 0) {
2611 uint64_t addressing_bits;
2612 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2615 }
else if (key.compare(
"low_mem_addressing_bits") == 0) {
2616 uint64_t addressing_bits;
2617 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2620 }
else if (key.compare(
"high_mem_addressing_bits") == 0) {
2621 uint64_t addressing_bits;
2622 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2625 }
else if (key ==
"added-binaries") {
2629 while (!value.empty()) {
2630 llvm::StringRef pc_str;
2631 std::tie(pc_str, value) = value.split(
',');
2634 added_binaries.push_back(
pc);
2636 }
else if (key ==
"detailed-binaries-info") {
2644 }
else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
2646 if (!key.getAsInteger(
BASE_16, reg))
2647 expedited_register_map[reg] = std::string(std::move(value));
2657 "Received stop for incorrect PID = {0} (inferior PID = {1})",
2679 tid, expedited_register_map, signo, thread_name, reason, description,
2680 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2681 associated_with_dispatch_queue, dispatch_queue_t, queue_name,
2682 queue_kind, queue_serial_number, added_binaries,
2683 detailed_binaries_info);
2731 if (!selected_thread_sp ||
2732 selected_thread_sp->GetID() != primary_thread_sp->GetID())
2733 m_thread_list.SetSelectedThreadByID(primary_thread_sp->GetID());
2760 LLDB_LOGF(log,
"ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
2764 if (
error.Success())
2766 "ProcessGDBRemote::DoDetach() detach packet sent successfully");
2769 "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
2770 error.AsCString() ?
error.AsCString() :
"<unknown error>");
2773 if (!
error.Success())
2788 LLDB_LOGF(log,
"ProcessGDBRemote::DoDestroy()");
2791 int exit_status = SIGABRT;
2792 std::string exit_string;
2799 exit_status = kill_res.get();
2800#if defined(__APPLE__)
2812 if (platform_sp && platform_sp->IsHost()) {
2815 reap_pid = waitpid(
GetID(), &status, WNOHANG);
2816 LLDB_LOGF(log,
"Reaped pid: %d, status: %d.\n", reap_pid, status);
2820 exit_string.assign(
"killed");
2822 exit_string.assign(llvm::toString(kill_res.takeError()));
2825 exit_string.assign(
"killed or interrupted while attaching.");
2831 exit_string.assign(
"destroying when not connected to debugserver");
2852 const bool did_exec =
2853 response.
GetStringRef().find(
";reason:exec;") != std::string::npos;
2856 LLDB_LOGF(log,
"ProcessGDBRemote::SetLastStopPacket () - detected exec");
2861 m_gdb_comm.ResetDiscoverableSettings(did_exec);
2886 LLDB_LOG_ERROR(log, list.takeError(),
"Failed to read module list: {0}.");
2888 addr = list->m_link_map;
2908 const size_t n = thread_infos->
GetSize();
2909 for (
size_t i = 0; i < n; ++i) {
2933 xPacketState x_state =
m_gdb_comm.GetxPacketState();
2936 size_t max_memory_size = x_state != xPacketState::Unimplemented
2939 if (size > max_memory_size) {
2943 size = max_memory_size;
2956 llvm::formatv(
";address_space:{0};", llvm::utohexstr(addr_space,
true));
2957 if (info->is_thread_specific) {
2958 std::optional<lldb::tid_t> tid = process_addr.
GetThreadID();
2961 "address space \"%s\" is thread specific, but no thread was "
2963 info->name.c_str());
2966 suffix += llvm::formatv(
"thread:{0};", llvm::utohexstr(*tid,
true));
2972 ::snprintf(packet,
sizeof(packet),
"%c%" PRIx64
",%" PRIx64
"%s",
2973 x_state != xPacketState::Unimplemented ?
'x' :
'm',
2974 (uint64_t)addr, (uint64_t)size, suffix.c_str());
2975 assert(packet_len + 1 < (
int)
sizeof(packet));
2978 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
2983 if (x_state != xPacketState::Unimplemented) {
2988 llvm::StringRef data_received = response.
GetStringRef();
2989 if (x_state == xPacketState::Prefixed &&
2990 !data_received.consume_front(
"b")) {
2992 "unexpected response to GDB server memory read packet '{0}': "
2994 packet, data_received);
2999 size_t memcpy_size = std::min(size, data_received.size());
3000 memcpy(buf, data_received.data(), memcpy_size);
3004 llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size),
'\xdd');
3008 "memory read failed for 0x%" PRIx64, addr);
3011 "GDB server does not support reading memory");
3014 "unexpected response to GDB server memory read packet '%s': '%s'",
3026 uint64_t max_packet_size,
3030 constexpr uint64_t range_overhead = 33;
3031 uint64_t current_size = 0;
3032 for (
auto [idx, range] : llvm::enumerate(ranges)) {
3033 uint64_t potential_size = current_size + range.size + range_overhead;
3034 if (potential_size > max_packet_size) {
3037 "MultiMemRead input has a range (base = {0:x}, size = {1}) "
3038 "bigger than the maximum allowed by remote",
3039 range.base, range.size);
3043 return ranges.size();
3046llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>
3049 llvm::MutableArrayRef<uint8_t> buffer) {
3053 const llvm::ArrayRef<Range<lldb::addr_t, size_t>> original_ranges = ranges;
3054 llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> memory_regions;
3056 while (!ranges.empty()) {
3057 uint64_t num_ranges =
3059 if (num_ranges == 0)
3062 auto ranges_for_request = ranges.take_front(num_ranges);
3063 ranges = ranges.drop_front(num_ranges);
3065 llvm::Expected<StringExtractorGDBRemote> response =
3069 "MultiMemRead error response: {0}");
3073 llvm::StringRef response_str = response->GetStringRef();
3074 const unsigned expected_num_ranges = ranges_for_request.size();
3076 response_str, buffer, expected_num_ranges, memory_regions)) {
3078 "MultiMemRead error parsing response: {0}");
3082 return memory_regions;
3085llvm::Expected<StringExtractorGDBRemote>
3088 std::string packet_str;
3089 llvm::raw_string_ostream stream(packet_str);
3090 stream <<
"MultiMemRead:ranges:";
3092 auto range_to_stream = [&](
auto range) {
3094 stream << llvm::formatv(
"{0:x-},{1:x-}", range.base, range.size);
3096 llvm::interleave(ranges, stream, range_to_stream,
",");
3101 m_gdb_comm.SendPacketAndWaitForResponse(packet_str.data(), response,
3104 return llvm::createStringErrorV(
"MultiMemRead failed to send packet: '{0}'",
3108 return llvm::createStringErrorV(
"MultiMemRead failed: '{0}'",
3112 return llvm::createStringErrorV(
"MultiMemRead unexpected response: '{0}'",
3119 llvm::StringRef response_str, llvm::MutableArrayRef<uint8_t> buffer,
3120 unsigned expected_num_ranges,
3123 auto [sizes_str, memory_data] = response_str.split(
';');
3124 if (sizes_str.size() == response_str.size())
3125 return llvm::createStringErrorV(
3126 "MultiMemRead response missing field separator ';' in: '{0}'",
3130 for (llvm::StringRef size_str : llvm::split(sizes_str,
',')) {
3132 if (size_str.getAsInteger(
BASE_16, read_size))
3133 return llvm::createStringErrorV(
3134 "MultiMemRead response has invalid size string: {0}", size_str);
3136 if (memory_data.size() < read_size)
3137 return llvm::createStringErrorV(
"MultiMemRead response did not have "
3138 "enough data, requested sizes: {0}",
3141 llvm::StringRef region_to_read = memory_data.take_front(read_size);
3142 memory_data = memory_data.drop_front(read_size);
3144 assert(buffer.size() >= read_size);
3145 llvm::MutableArrayRef<uint8_t> region_to_write =
3146 buffer.take_front(read_size);
3147 buffer = buffer.drop_front(read_size);
3149 memcpy(region_to_write.data(), region_to_read.data(), read_size);
3150 memory_regions.push_back(region_to_write);
3153 return llvm::Error::success();
3157 return m_gdb_comm.GetMemoryTaggingSupported();
3160llvm::Expected<std::vector<uint8_t>>
3167 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3168 "Error reading memory tags from remote");
3172 llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
3173 std::vector<uint8_t> got;
3174 got.reserve(tag_data.size());
3175 std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
3181 const std::vector<uint8_t> &tags) {
3184 return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
3188 std::vector<ObjectFile::LoadableData> entries) {
3198 if (
error.Success())
3212 for (
size_t i = 0; i < size; ++i)
3237 if (blocksize == 0) {
3245 lldb::addr_t block_start_addr = addr - (addr % blocksize);
3246 size += (addr - block_start_addr);
3247 if ((size % blocksize) != 0)
3248 size += (blocksize - size % blocksize);
3264 auto overlap = last_range.GetRangeEnd() - range.
GetRangeBase();
3285 "flash erase failed for 0x%" PRIx64, addr);
3288 "GDB server does not support flashing");
3291 "unexpected response to GDB server flash erase packet '%s': '%s'",
3308 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"vFlashDone", response,
3318 "GDB server does not support flashing");
3321 "unexpected response to GDB server flash done packet: '%s'",
3336 if (size > max_memory_size) {
3340 size = max_memory_size;
3360 if (!
error.Success())
3362 packet.
Printf(
"vFlashWrite:%" PRIx64
":", addr);
3365 packet.
Printf(
"M%" PRIx64
",%" PRIx64
":", addr, (uint64_t)size);
3378 "memory write failed for 0x%" PRIx64, addr);
3381 "GDB server does not support writing memory");
3384 "unexpected response to GDB server memory write packet '%s': '%s'",
3394 uint32_t permissions,
3400 allocated_addr =
m_gdb_comm.AllocateMemory(size, permissions);
3403 return allocated_addr;
3409 if (permissions & lldb::ePermissionsReadable)
3411 if (permissions & lldb::ePermissionsWritable)
3413 if (permissions & lldb::ePermissionsExecutable)
3422 "ProcessGDBRemote::%s no direct stub support for memory "
3423 "allocation, and InferiorCallMmap also failed - is stub "
3424 "missing register context save/restore capability?",
3431 "unable to allocate %" PRIu64
" bytes of memory with permissions %s",
3435 return allocated_addr;
3450 return m_gdb_comm.GetWatchpointReportedAfter();
3457 switch (supported) {
3462 "tried to deallocate memory without ever allocating memory");
3468 "unable to deallocate memory at 0x%" PRIx64, addr);
3480 "unable to deallocate memory at 0x%" PRIx64, addr);
3513 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3515 if (error_no == 0) {
3518 return llvm::Error::success();
3521 if (error_no != UINT8_MAX)
3522 return llvm::createStringErrorV(
3523 "error sending the breakpoint request: {0}", error_no);
3524 return llvm::createStringError(
"error sending the breakpoint request");
3526 LLDB_LOG(log,
"Software breakpoints are unsupported");
3531 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3533 if (error_no == 0) {
3536 return llvm::Error::success();
3539 if (error_no != UINT8_MAX)
3540 return llvm::createStringErrorV(
3541 "error sending the hardware breakpoint request: {0} "
3542 "(hardware breakpoint resources might be exhausted or unavailable)",
3544 return llvm::createStringError(
3545 "error sending the hardware breakpoint request "
3546 "(hardware breakpoint resources might be exhausted or unavailable)");
3548 LLDB_LOG(log,
"Hardware breakpoints are unsupported");
3552 return llvm::createStringError(
"hardware breakpoints are not supported");
3568 return error.takeError();
3574 return llvm::createStringError(
"unknown error");
3579 return llvm::createStringError(
"unknown error");
3583 return llvm::Error::success();
3587 assert(bp_site !=
nullptr);
3598 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3599 ") address = 0x%" PRIx64,
3600 site_id, (uint64_t)addr);
3605 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3606 ") address = 0x%" PRIx64
" -- SUCCESS (already enabled)",
3607 site_id, (uint64_t)addr);
3615 assert(bp_site !=
nullptr);
3620 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3621 ") addr = 0x%8.8" PRIx64,
3622 site_id, (uint64_t)addr);
3626 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3627 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3628 site_id, (uint64_t)addr);
3639 bool read = wp_res_sp->WatchpointResourceRead();
3640 bool write = wp_res_sp->WatchpointResourceWrite();
3642 assert((read || write) &&
3643 "WatchpointResource type is neither read nor write");
3659 addr_t addr = wp_sp->GetLoadAddress();
3661 LLDB_LOGF(log,
"ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
")",
3663 if (wp_sp->IsEnabled()) {
3665 "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
3666 ") addr = 0x%8.8" PRIx64
": watchpoint already enabled.",
3667 watchID, (uint64_t)addr);
3671 bool read = wp_sp->WatchpointRead();
3672 bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
3673 size_t size = wp_sp->GetByteSize();
3676 WatchpointHardwareFeature supported_features =
3679 std::vector<WatchpointResourceSP> resources =
3681 addr, size, read, write, supported_features, target_arch);
3706 bool set_all_resources =
true;
3707 std::vector<WatchpointResourceSP> succesfully_set_resources;
3708 for (
const auto &wp_res_sp : resources) {
3709 addr_t addr = wp_res_sp->GetLoadAddress();
3710 size_t size = wp_res_sp->GetByteSize();
3712 if (!
m_gdb_comm.SupportsGDBStoppointPacket(type) ||
3713 m_gdb_comm.SendGDBStoppointTypePacket(type,
true, addr, size,
3715 set_all_resources =
false;
3718 succesfully_set_resources.push_back(wp_res_sp);
3721 if (set_all_resources) {
3722 wp_sp->SetEnabled(
true, notify);
3723 for (
const auto &wp_res_sp : resources) {
3726 wp_res_sp->AddConstituent(wp_sp);
3734 for (
const auto &wp_res_sp : succesfully_set_resources) {
3735 addr_t addr = wp_res_sp->GetLoadAddress();
3736 size_t size = wp_res_sp->GetByteSize();
3738 m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3742 "Setting one of the watchpoint resources failed");
3758 addr_t addr = wp_sp->GetLoadAddress();
3761 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3762 ") addr = 0x%8.8" PRIx64,
3763 watchID, (uint64_t)addr);
3765 if (!wp_sp->IsEnabled()) {
3767 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3768 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3769 watchID, (uint64_t)addr);
3773 wp_sp->SetEnabled(
false, notify);
3777 if (wp_sp->IsHardware()) {
3778 bool disabled_all =
true;
3780 std::vector<WatchpointResourceSP> unused_resources;
3782 if (wp_res_sp->ConstituentsContains(wp_sp)) {
3784 addr_t addr = wp_res_sp->GetLoadAddress();
3785 size_t size = wp_res_sp->GetByteSize();
3786 if (
m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3788 disabled_all =
false;
3790 wp_res_sp->RemoveConstituent(wp_sp);
3791 if (wp_res_sp->GetNumberOfConstituents() == 0)
3792 unused_resources.push_back(wp_res_sp);
3796 for (
auto &wp_res_sp : unused_resources)
3799 wp_sp->SetEnabled(
false, notify);
3802 "Failure disabling one of the watchpoint locations");
3815 LLDB_LOGF(log,
"ProcessGDBRemote::DoSignal (signal = %d)", signo);
3830 if (platform_sp && !platform_sp->IsHost())
3835 const char *error_string =
error.AsCString();
3836 if (error_string ==
nullptr)
3845 static FileSpec g_debugserver_file_spec;
3852 std::string env_debugserver_path = host_env.lookup(
"LLDB_DEBUGSERVER_PATH");
3853 if (!env_debugserver_path.empty()) {
3854 debugserver_file_spec.
SetFile(env_debugserver_path,
3855 FileSpec::Style::native);
3856 LLDB_LOG(log,
"gdb-remote stub exe path set from environment variable: {0}",
3857 env_debugserver_path);
3859 debugserver_file_spec = g_debugserver_file_spec;
3861 return debugserver_file_spec;
3864 debugserver_file_spec = HostInfo::GetSupportExeDir();
3865 if (debugserver_file_spec) {
3868 LLDB_LOG(log,
"found gdb-remote stub exe '{0}'", debugserver_file_spec);
3870 g_debugserver_file_spec = debugserver_file_spec;
3873 if (!debugserver_file_spec) {
3876 LLDB_LOG(log,
"could not find gdb-remote stub exe '{0}'",
3877 debugserver_file_spec);
3881 g_debugserver_file_spec.
Clear();
3884 return debugserver_file_spec;
3889 using namespace std::placeholders;
3899 const std::weak_ptr<ProcessGDBRemote> this_wp =
3900 std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3907#if defined(__APPLE__)
3911 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
3913 struct kinfo_proc processInfo;
3914 size_t bufsize =
sizeof(processInfo);
3915 if (sysctl(mib, (
unsigned)(
sizeof(mib) /
sizeof(
int)), &processInfo, &bufsize,
3918 if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
3919 debugserver_path =
FileSpec(
"/Library/Apple/usr/libexec/oah/debugserver");
3926 "'. Please ensure it is properly installed "
3927 "and available in your PATH");
3942 debugserver_launch_info,
nullptr);
3947 LLDB_LOGF(log,
"failed to start debugserver process: %s",
3957 m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>(
3958 std::move(socket_pair->second)));
3972 std::weak_ptr<ProcessGDBRemote> process_wp,
lldb::pid_t debugserver_pid,
3981 "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
3982 ", signo=%i (0x%x), exit_status=%i)",
3983 __FUNCTION__, debugserver_pid, signo, signo, exit_status);
3985 std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
3986 LLDB_LOGF(log,
"ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
3987 static_cast<void *
>(process_sp.get()));
3988 if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
3994 std::this_thread::sleep_for(std::chrono::milliseconds(500));
3998 const StateType state = process_sp->GetState();
4007 llvm::StringRef signal_name =
4008 process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);
4010 if (!signal_name.empty())
4011 stream.
Format(format_str, signal_name);
4013 stream.
Format(format_str, signo);
4015 process_sp->SetExitStatus(-1, stream.
GetString());
4038 debugger, PluginProperties::GetSettingName())) {
4039 const bool is_global_setting =
true;
4042 "Properties for the gdb-remote process plug-in.", is_global_setting);
4049 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
4056 llvm::Expected<HostThread> async_thread =
4060 if (!async_thread) {
4062 "failed to launch host thread: {0}");
4068 "ProcessGDBRemote::%s () - Called when Async thread was "
4078 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
4093 "ProcessGDBRemote::%s () - Called when Async thread was not running.",
4099 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread starting...",
4100 __FUNCTION__,
GetID());
4118 "ProcessGDBRemote::%s(pid = %" PRIu64
4119 ") listener.WaitForEvent (NULL, event_sp)...",
4120 __FUNCTION__,
GetID());
4123 const uint32_t event_type = event_sp->GetType();
4126 "ProcessGDBRemote::%s(pid = %" PRIu64
4127 ") Got an event of type: %d...",
4128 __FUNCTION__,
GetID(), event_type);
4130 switch (event_type) {
4135 if (continue_packet) {
4136 const char *continue_cstr =
4137 (
const char *)continue_packet->
GetBytes();
4138 const size_t continue_cstr_len = continue_packet->
GetByteSize();
4140 "ProcessGDBRemote::%s(pid = %" PRIu64
4141 ") got eBroadcastBitAsyncContinue: %s",
4142 __FUNCTION__,
GetID(), continue_cstr);
4144 if (::strstr(continue_cstr,
"vAttach") ==
nullptr)
4151 llvm::StringRef(continue_cstr, continue_cstr_len),
4162 switch (stop_state) {
4175 int exit_status = response.
GetHexU8();
4176 std::string desc_string;
4178 llvm::StringRef desc_str;
4179 llvm::StringRef desc_token;
4181 if (desc_token !=
"description")
4196 if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4199 "System Integrity Protection");
4200 }
else if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4220 "ProcessGDBRemote::%s(pid = %" PRIu64
4221 ") got eBroadcastBitAsyncThreadShouldExit...",
4222 __FUNCTION__,
GetID());
4228 "ProcessGDBRemote::%s(pid = %" PRIu64
4229 ") got unknown event 0x%8.8x",
4230 __FUNCTION__,
GetID(), event_type);
4237 "ProcessGDBRemote::%s(pid = %" PRIu64
4238 ") listener.WaitForEvent (NULL, event_sp) => false",
4239 __FUNCTION__,
GetID());
4244 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread exiting...",
4245 __FUNCTION__,
GetID());
4277 LLDB_LOGF(log,
"Hit New Thread Notification breakpoint.");
4284class AcceleratorBreakpointCallbackBaton
4285 :
public TypedBaton<AcceleratorBreakpointHitArgs> {
4287 explicit AcceleratorBreakpointCallbackBaton(
4288 std::unique_ptr<AcceleratorBreakpointHitArgs> data)
4307 "ProcessGDBRemote::HandleAcceleratorActions skipping already "
4308 "processed actions for plugin '{0}' with identifier {1}",
4310 return llvm::Error::success();
4327 return llvm::Error::success();
4337 std::string exe_path = connect_info.
exe_path.value_or(
"");
4341 &platform_options, accelerator_target_sp);
4343 return error.takeError();
4344 if (!accelerator_target_sp)
4345 return llvm::createStringError(
"failed to create accelerator target");
4347 PlatformSP platform_sp = accelerator_target_sp->GetPlatform();
4349 return llvm::createStringErrorV(
4350 "no platform '{0}' compatible with triple '{1}' for the accelerator "
4355 ? platform_sp->ConnectProcessSynchronous(
4359 : platform_sp->ConnectProcess(connect_info.
connect_url,
4361 accelerator_target_sp.get(),
error);
4363 return error.takeError();
4365 return llvm::createStringError(
"failed to connect to the accelerator");
4367 accelerator_target_sp->SetTargetSessionName(actions.
session_name);
4370 auto event_sp = std::make_shared<Event>(
4373 accelerator_target_sp));
4375 return llvm::Error::success();
4381 llvm::Error
error = llvm::Error::success();
4385 auto args_up = std::make_unique<AcceleratorBreakpointHitArgs>();
4387 args_up->breakpoint = bp;
4394 error = llvm::joinErrors(
4396 llvm::createStringErrorV(
4397 "accelerator breakpoint {0} specifies both a by_name and a "
4398 "by_address specification",
4406 bp_modules.
GetSize() ? &bp_modules :
nullptr,
4408 bp.
by_name->function_name.c_str(),
4409 eFunctionNameTypeFull,
4421 error = llvm::joinErrors(
4423 llvm::createStringErrorV(
4424 "accelerator breakpoint {0} has neither a by_name nor a "
4425 "by_address specification",
4431 error = llvm::joinErrors(
4433 llvm::createStringErrorV(
"failed to set accelerator breakpoint {0}",
4441 llvm::formatv(
"accelerator-plugin ({0})", actions.
plugin_name);
4442 bp_sp->SetBreakpointKind(kind.c_str());
4443 auto baton_sp = std::make_shared<AcceleratorBreakpointCallbackBaton>(
4444 std::move(args_up));
4472 for (
size_t i = 0; i < symbol_names.size(); ++i) {
4480 addr_t load_addr = sc.symbol->GetAddress().GetLoadAddress(&target);
4489 llvm::Expected<AcceleratorBreakpointHitResponse> response =
4493 "accelerator breakpoint hit notification failed: {0}");
4501 if (response->disable_bp) {
4503 bp_sp->SetEnabled(
false);
4508 if (response->actions) {
4512 std::string message = llvm::toString(std::move(
error));
4513 LLDB_LOG(log,
"failed to handle accelerator actions: {0}", message);
4515 "error: accelerator plugin '%s': %s\n",
4516 response->actions->plugin_name.c_str(), message.c_str());
4521 return !response->auto_resume_native;
4526 LLDB_LOG(log,
"Check if need to update ignored signals");
4540 LLDB_LOG(log,
"Signals' version hasn't changed. version={0}",
4545 auto signals_to_ignore =
4550 "Signals' version changed. old version={0}, new version={1}, "
4551 "signals ignored={2}, update result={3}",
4553 signals_to_ignore.size(),
error);
4555 if (
error.Success())
4570 platform_sp->SetThreadCreationBreakpoint(
GetTarget());
4573 log,
"Successfully created new thread notification breakpoint %i",
4578 LLDB_LOGF(log,
"Failed to create new thread notification breakpoint.");
4607 return_value =
m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
4608 if (return_value != 0) {
4611 "Sending events is not supported for this process.");
4621 if (
m_gdb_comm.GetQXferAuxvReadSupported()) {
4622 llvm::Expected<std::string> response =
m_gdb_comm.ReadExtFeature(
"auxv",
"");
4624 buf = std::make_shared<DataBufferHeap>(response->c_str(),
4625 response->length());
4636 if (
m_gdb_comm.GetThreadExtendedInfoSupported()) {
4642 args_dict->GetAsDictionary()->AddIntegerItem(
"thread", tid);
4645 packet <<
"jThreadExtendedInfo:";
4646 args_dict->Dump(packet,
false);
4653 packet << (char)(0x7d ^ 0x20);
4662 if (!response.
Empty()) {
4675 args_dict->GetAsDictionary()->AddIntegerItem(
"image_list_address",
4676 image_list_address);
4677 args_dict->GetAsDictionary()->AddIntegerItem(
"image_count", image_count);
4684 std::string info_level_str;
4686 info_level_str =
"address-only";
4688 info_level_str =
"address-name";
4690 info_level_str =
"address-name-uuid";
4692 info_level_str =
"full";
4694 return info_level_str;
4701 args_dict->GetAsDictionary()->AddBooleanItem(
"fetch_all_solibs",
true);
4703 args_dict->GetAsDictionary()->AddBooleanItem(
"report_load_commands",
false);
4705 if (!info_level_str.empty())
4706 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4707 info_level_str.c_str());
4714 const std::vector<lldb::addr_t> &load_addresses) {
4718 for (
auto addr : load_addresses)
4719 addresses->AddIntegerItem(addr);
4721 args_dict->GetAsDictionary()->AddItem(
"solib_addresses", addresses);
4724 if (!info_level_str.empty())
4725 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4726 info_level_str.c_str());
4736 if (
m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
4739 std::chrono::seconds(10));
4742 packet <<
"jGetLoadedDynamicLibrariesInfos:";
4743 args_dict->Dump(packet,
false);
4750 packet << (char)(0x7d ^ 0x20);
4759 if (!response.
Empty()) {
4772 if (
m_gdb_comm.GetDynamicLoaderProcessStateSupported()) {
4775 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"jGetDyldProcessState",
4781 if (!response.
Empty()) {
4798 packet <<
"jGetSharedCacheInfo:";
4799 args_dict->Dump(packet,
false);
4808 if (response.
Empty())
4817 if (!dict->
HasKey(
"shared_cache_uuid"))
4819 llvm::StringRef uuid_str;
4821 uuid_str ==
"00000000-0000-0000-0000-000000000000")
4823 if (dict->
HasKey(
"shared_cache_path")) {
4837 HostInfo::SharedCacheIndexFiles(sc_path, uuid, sc_mode);
4848 return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
4861 const uint64_t reasonable_largeish_default = 128 * 1024;
4862 const uint64_t conservative_default = 512;
4865 uint64_t stub_max_size =
m_gdb_comm.GetRemoteMaxPacketSize();
4866 if (stub_max_size !=
UINT64_MAX && stub_max_size != 0) {
4872 if (stub_max_size > reasonable_largeish_default) {
4873 stub_max_size = reasonable_largeish_default;
4879 if (stub_max_size > 70)
4880 stub_max_size -= 32 + 32 + 6;
4885 LLDB_LOG(log,
"warning: Packet size is too small. "
4886 "LLDB may face problems while writing memory");
4897 uint64_t user_specified_max) {
4898 if (user_specified_max != 0) {
4926 module_spec = cached->second;
4927 return bool(module_spec);
4930 if (!
m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
4931 LLDB_LOGF(log,
"ProcessGDBRemote::%s - failed to get module info for %s:%s",
4932 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4939 module_spec.
Dump(stream);
4940 LLDB_LOGF(log,
"ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
4941 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4950 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4951 auto module_specs =
m_gdb_comm.GetModulesInfo(module_file_specs, triple);
4953 for (
const FileSpec &spec : module_file_specs)
4958 triple.getTriple())] = spec;
4972typedef std::vector<std::string> stringVec;
4974typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
4975struct RegisterSetInfo {
4979typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
4981struct GdbServerTargetInfo {
4985 RegisterSetMap reg_set_map;
4988using RegisterTypeMap = llvm::StringMap<const RegisterType *>;
4991ParseEnumEvalues(
const XMLNode &enum_node) {
5005 std::map<uint64_t, RegisterTypeEnum::Enumerator> enumerators;
5008 "evalue", [&enumerators, &log](
const XMLNode &enumerator_node) {
5009 std::optional<llvm::StringRef> name;
5010 std::optional<uint64_t> value;
5013 [&name, &value, &log](
const llvm::StringRef &attr_name,
5014 const llvm::StringRef &attr_value) {
5015 if (attr_name ==
"name") {
5016 if (attr_value.size())
5019 LLDB_LOG(log,
"ProcessGDBRemote::ParseEnumEvalues "
5020 "Ignoring empty name in evalue");
5021 }
else if (attr_name ==
"value") {
5022 uint64_t parsed_value = 0;
5023 if (llvm::to_integer(attr_value, parsed_value))
5024 value = parsed_value;
5027 "ProcessGDBRemote::ParseEnumEvalues "
5028 "Invalid value \"{0}\" in "
5033 "ProcessGDBRemote::ParseEnumEvalues Ignoring "
5034 "unknown attribute "
5035 "\"{0}\" in evalue",
5043 enumerators.insert_or_assign(
5044 *value, RegisterTypeEnum::Enumerator(*value, name->str()));
5051 for (
auto [_, enumerator] : enumerators)
5052 final_enumerators.push_back(enumerator);
5054 return final_enumerators;
5058ParseEnums(XMLNode feature_node, RegisterTypeMap &feature_register_types,
5059 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5064 "enum", [log, &feature_register_types,
5065 &owned_register_types](
const XMLNode &enum_node) {
5069 const llvm::StringRef &attr_value) {
5070 if (attr_name ==
"id")
5088 ParseEnumEvalues(enum_node);
5089 if (!enumerators.empty()) {
5091 "ProcessGDBRemote::ParseEnums Found enum type \"{0}\"",
5094 std::make_unique<RegisterTypeEnum>(
id, enumerators);
5095 const RegisterTypeEnum *enum_type_ptr = enum_type.get();
5096 auto [it, inserted] =
5097 feature_register_types.try_emplace(
id, enum_type_ptr);
5099 owned_register_types.push_back(std::move(enum_type));
5100 }
else if (llvm::isa<RegisterTypeEnum>(it->second)) {
5105 owned_register_types.push_back(std::move(enum_type));
5106 it->second = enum_type_ptr;
5110 "ProcessGDBRemote::ParseEnums Ignoring enum type \"{0}\" "
5111 "because another type with that id already exists",
5122static std::vector<RegisterTypeFlags::Field>
5123ParseFlagsFields(XMLNode flags_node,
unsigned size,
5124 const RegisterTypeMap &feature_register_types) {
5126 const unsigned max_start_bit = size * 8 - 1;
5129 std::vector<RegisterTypeFlags::Field> fields;
5131 &feature_register_types](
5134 std::optional<llvm::StringRef> name;
5135 std::optional<unsigned> start;
5136 std::optional<unsigned> end;
5137 std::optional<llvm::StringRef> type;
5140 &log](
const llvm::StringRef &attr_name,
5141 const llvm::StringRef &attr_value) {
5144 if (attr_name ==
"name") {
5147 "ProcessGDBRemote::ParseFlagsFields Found field node name \"{0}\"",
5150 }
else if (attr_name ==
"start") {
5151 unsigned parsed_start = 0;
5152 if (llvm::to_integer(attr_value, parsed_start)) {
5153 if (parsed_start > max_start_bit) {
5155 "ProcessGDBRemote::ParseFlagsFields Invalid start {0} in "
5158 parsed_start, max_start_bit);
5160 start = parsed_start;
5164 "ProcessGDBRemote::ParseFlagsFields Invalid start \"{0}\" in "
5168 }
else if (attr_name ==
"end") {
5169 unsigned parsed_end = 0;
5170 if (llvm::to_integer(attr_value, parsed_end))
5171 if (parsed_end > max_start_bit) {
5173 "ProcessGDBRemote::ParseFlagsFields Invalid end {0} in "
5176 parsed_end, max_start_bit);
5181 "ProcessGDBRemote::ParseFlagsFields Invalid end \"{0}\" in "
5185 }
else if (attr_name ==
"type") {
5190 "ProcessGDBRemote::ParseFlagsFields Ignoring unknown attribute "
5191 "\"{0}\" in field node",
5198 if (name && start && end) {
5202 "ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
5203 "\"{2}\", ignoring",
5204 *start, *end, name->data());
5208 "ProcessGDBRemote::ParseFlagsFields Ignoring field \"{}\" "
5209 "that has size > 64 bits, this is not supported",
5213 const RegisterTypeEnum *enum_type =
nullptr;
5214 if (type && !type->empty()) {
5215 auto found = feature_register_types.find(*type);
5216 if (found != feature_register_types.end()) {
5217 enum_type = llvm::dyn_cast<RegisterTypeEnum>(found->second);
5221 "ProcessGDBRemote::ParseFlagsFields Type \"{0}\" for "
5222 "field \"{1}\" is not an enum, ignoring",
5223 type->data(), name->data());
5228 uint64_t max_value =
5231 if (enumerator.m_value > max_value) {
5232 enum_type =
nullptr;
5235 "ProcessGDBRemote::ParseFlagsFields In enum \"{0}\" "
5236 "evalue \"{1}\" with value {2} exceeds the maximum "
5237 "value of field \"{3}\" ({4}), ignoring enum",
5238 type->data(), enumerator.m_name, enumerator.m_value,
5239 name->data(), max_value);
5246 "ProcessGDBRemote::ParseFlagsFields Could not find type "
5248 "for field \"{1}\", ignoring",
5249 type->data(), name->data());
5254 RegisterTypeFlags::Field(name->str(), *start, *end, enum_type));
5265 XMLNode feature_node, RegisterTypeMap &feature_register_types,
5266 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5271 [&log, &feature_register_types,
5272 &owned_register_types](
const XMLNode &flags_node) ->
bool {
5273 LLDB_LOG(log,
"ProcessGDBRemote::ParseFlags Found flags node \"{0}\"",
5276 std::optional<llvm::StringRef>
id;
5277 std::optional<unsigned> size;
5279 [&
id, &size, &log](
const llvm::StringRef &name,
5280 const llvm::StringRef &value) {
5283 }
else if (name ==
"size") {
5284 unsigned parsed_size = 0;
5285 if (llvm::to_integer(value, parsed_size))
5289 "ProcessGDBRemote::ParseFlags Invalid size \"{0}\" "
5295 "ProcessGDBRemote::ParseFlags Ignoring unknown "
5296 "attribute \"{0}\" in flags node",
5304 std::vector<RegisterTypeFlags::Field> fields =
5305 ParseFlagsFields(flags_node, *size, feature_register_types);
5306 if (fields.size()) {
5308 std::sort(fields.rbegin(), fields.rend());
5309 std::vector<RegisterTypeFlags::Field>::const_iterator overlap =
5310 std::adjacent_find(fields.begin(), fields.end(),
5311 [](
const RegisterTypeFlags::Field &lhs,
5312 const RegisterTypeFlags::Field &rhs) {
5313 return lhs.Overlaps(rhs);
5317 if (overlap == fields.end()) {
5318 if (feature_register_types.contains(*
id)) {
5323 "ProcessGDBRemote::ParseFlags Definition of flags \"{0}\" "
5324 "conflicts with an existing type, ignoring this "
5328 auto flags_type = std::make_unique<RegisterTypeFlags>(
5329 id->str(), *size, std::move(fields));
5330 feature_register_types.try_emplace(*
id, flags_type.get());
5331 owned_register_types.push_back(std::move(flags_type));
5335 std::vector<RegisterTypeFlags::Field>::const_iterator next =
5339 "ProcessGDBRemote::ParseFlags Ignoring flags because fields "
5340 "{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) "
5342 overlap->GetName().c_str(), overlap->GetStart(),
5343 overlap->GetEnd(), next->GetName().c_str(), next->GetStart(),
5349 "ProcessGDBRemote::ParseFlags Ignoring definition of flags "
5350 "\"{0}\" because it contains no fields.",
5359static const RegisterTypeBuiltin *
5360ResolveGDBBuiltinType(llvm::StringRef type_name) {
5364 static const RegisterTypeBuiltin bool_type(
"bool",
eEncodingUint,
5366 static const RegisterTypeBuiltin int8_type(
"int8",
eEncodingSint,
5368 static const RegisterTypeBuiltin int16_type(
"int16",
eEncodingSint,
5370 static const RegisterTypeBuiltin int32_type(
"int32",
eEncodingSint,
5372 static const RegisterTypeBuiltin int64_type(
"int64",
eEncodingSint,
5374 static const RegisterTypeBuiltin int128_type(
"int128",
eEncodingSint,
5376 static const RegisterTypeBuiltin uint8_type(
"uint8",
eEncodingUint,
5378 static const RegisterTypeBuiltin uint16_type(
"uint16",
eEncodingUint,
5380 static const RegisterTypeBuiltin uint32_type(
"uint32",
eEncodingUint,
5382 static const RegisterTypeBuiltin uint64_type(
"uint64",
eEncodingUint,
5384 static const RegisterTypeBuiltin uint128_type(
"uint128",
eEncodingUint,
5386 static const RegisterTypeBuiltin code_ptr_type(
5388 static const RegisterTypeBuiltin data_ptr_type(
5390 static const RegisterTypeBuiltin ieee_half_type(
"ieee_half",
eEncodingIEEE754,
5392 static const RegisterTypeBuiltin ieee_single_type(
5394 static const RegisterTypeBuiltin ieee_double_type(
5396 static const RegisterTypeBuiltin i387_ext_type(
"i387_ext",
eEncodingIEEE754,
5398 static const RegisterTypeBuiltin bfloat16_type(
"bfloat16",
eEncodingIEEE754,
5401 return llvm::StringSwitch<const RegisterTypeBuiltin *>(type_name)
5402 .Case(
"bool", &bool_type)
5403 .Case(
"int8", &int8_type)
5404 .Case(
"int16", &int16_type)
5405 .Case(
"int32", &int32_type)
5406 .Case(
"int64", &int64_type)
5407 .Case(
"int128", &int128_type)
5408 .Case(
"uint8", &uint8_type)
5409 .Case(
"uint16", &uint16_type)
5410 .Case(
"uint32", &uint32_type)
5411 .Case(
"uint64", &uint64_type)
5412 .Case(
"uint128", &uint128_type)
5413 .Case(
"code_ptr", &code_ptr_type)
5414 .Case(
"data_ptr", &data_ptr_type)
5415 .Case(
"ieee_half", &ieee_half_type)
5416 .Case(
"ieee_single", &ieee_single_type)
5417 .Case(
"ieee_double", &ieee_double_type)
5418 .Case(
"i387_ext", &i387_ext_type)
5419 .Case(
"bfloat16", &bfloat16_type)
5423static const RegisterType *
5424ResolveGDBType(llvm::StringRef type_name,
5425 const RegisterTypeMap &feature_register_types) {
5426 auto type_it = feature_register_types.find(type_name);
5427 if (type_it != feature_register_types.end())
5428 return type_it->second;
5429 return ResolveGDBBuiltinType(type_name);
5433ParseVector(
const XMLNode &vector_node, RegisterTypeMap &feature_register_types,
5434 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5436 std::optional<llvm::StringRef>
id;
5437 std::optional<llvm::StringRef> element_type_name;
5438 std::optional<uint32_t> count;
5441 [&
id, &element_type_name, &count, log](llvm::StringRef name,
5442 llvm::StringRef value) {
5445 }
else if (name ==
"type") {
5446 element_type_name = value;
5447 }
else if (name ==
"count") {
5448 uint32_t parsed_count = 0;
5449 if (llvm::to_integer(value, parsed_count))
5450 count = parsed_count;
5452 LLDB_LOG(log,
"ProcessGDBRemote::ParseVector Invalid count \"{0}\"",
5456 "ProcessGDBRemote::ParseVector Ignoring unknown attribute "
5466 if (!
id ||
id->empty() || !element_type_name || element_type_name->empty() ||
5467 !count || *count == 0 || *count > max_vector_count) {
5468 LLDB_LOG(log,
"ProcessGDBRemote::ParseVector Ignoring vector with invalid "
5469 "id, type, or count");
5473 if (feature_register_types.contains(*
id)) {
5475 "ProcessGDBRemote::ParseVector Ignoring duplicate type \"{0}\"",
5480 const RegisterType *element_type =
5481 ResolveGDBType(*element_type_name, feature_register_types);
5482 if (!element_type) {
5484 "ProcessGDBRemote::ParseVector Could not resolve element type "
5485 "\"{0}\" for vector \"{1}\"",
5486 *element_type_name, *
id);
5490 if (!llvm::isa<RegisterTypeBuiltin, RegisterTypeVector>(element_type)) {
5492 "ProcessGDBRemote::ParseVector Found element type \"{0}\" for "
5493 "vector \"{1}\", but it is not a builtin or vector type",
5494 *element_type_name, *
id);
5498 std::optional<uint64_t> element_size = element_type->
GetByteSize();
5502 "ProcessGDBRemote::ParseVector Size of vector \"{0}\" is too "
5509 std::make_unique<RegisterTypeVector>(
id->str(), element_type, *count);
5510 feature_register_types.try_emplace(*
id, vector_type.get());
5511 owned_register_types.push_back(std::move(vector_type));
5515ParseVectors(XMLNode feature_node, RegisterTypeMap &feature_register_types,
5516 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5518 "vector", [&feature_register_types,
5519 &owned_register_types](
const XMLNode &vector_node) {
5520 ParseVector(vector_node, feature_register_types, owned_register_types);
5526 XMLNode feature_node, GdbServerTargetInfo &target_info,
5527 std::vector<DynamicRegisterInfo::Register> ®isters,
5528 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5533 RegisterTypeMap feature_register_types;
5536 ParseEnums(feature_node, feature_register_types, owned_register_types);
5537 for (
const auto ®ister_type : feature_register_types)
5538 if (
const auto *enum_type =
5539 llvm::dyn_cast<RegisterTypeEnum>(register_type.second))
5542 ParseFlags(feature_node, feature_register_types, owned_register_types);
5543 for (
const auto ®ister_type : feature_register_types)
5544 if (
const auto *flags_type =
5545 llvm::dyn_cast<RegisterTypeFlags>(register_type.second))
5546 flags_type->DumpToLog(log);
5548 ParseVectors(feature_node, feature_register_types, owned_register_types);
5549 for (
const auto ®ister_type : feature_register_types)
5550 if (
const auto *vector_type =
5551 llvm::dyn_cast<RegisterTypeVector>(register_type.second))
5552 vector_type->DumpToLog(log);
5556 [&target_info, ®isters, &feature_register_types,
5557 log](
const XMLNode ®_node) ->
bool {
5558 std::string gdb_group;
5559 std::string gdb_type;
5560 DynamicRegisterInfo::Register reg_info;
5561 bool encoding_set =
false;
5562 bool format_set =
false;
5566 &encoding_set, &format_set, ®_info,
5567 log](
const llvm::StringRef &name,
5568 const llvm::StringRef &value) ->
bool {
5569 if (name ==
"name") {
5571 }
else if (name ==
"bitsize") {
5572 if (llvm::to_integer(value, reg_info.
byte_size))
5574 llvm::divideCeil(reg_info.
byte_size, CHAR_BIT);
5575 }
else if (name ==
"type") {
5576 gdb_type = value.str();
5577 }
else if (name ==
"group") {
5578 gdb_group = value.str();
5579 }
else if (name ==
"regnum") {
5581 }
else if (name ==
"offset") {
5583 }
else if (name ==
"altname") {
5585 }
else if (name ==
"encoding") {
5586 encoding_set =
true;
5588 }
else if (name ==
"format") {
5594 llvm::StringSwitch<lldb::Format>(value)
5605 }
else if (name ==
"group_id") {
5607 llvm::to_integer(value, set_id);
5608 RegisterSetMap::const_iterator pos =
5609 target_info.reg_set_map.find(set_id);
5610 if (pos != target_info.reg_set_map.end())
5611 reg_info.
set_name = pos->second.name;
5612 }
else if (name ==
"gcc_regnum" || name ==
"ehframe_regnum") {
5614 }
else if (name ==
"dwarf_regnum") {
5616 }
else if (name ==
"generic") {
5618 }
else if (name ==
"value_regnums") {
5621 }
else if (name ==
"invalidate_regnums") {
5626 "ProcessGDBRemote::ParseRegisters unhandled reg "
5627 "attribute %s = %s",
5628 name.data(), value.data());
5633 if (!gdb_type.empty()) {
5635 auto it = feature_register_types.find(gdb_type);
5636 if (it != feature_register_types.end()) {
5637 if (
const auto *vector_type =
5638 llvm::dyn_cast<RegisterTypeVector>(it->second)) {
5639 std::optional<uint64_t> type_size = vector_type->GetByteSize();
5642 "ProcessGDBRemote::ParseRegisters Register {0} is "
5643 "too large for vector type {1}",
5644 reg_info.
name, vector_type->GetID());
5645 }
else if (!vector_type->IsByteSizeCompatible(
5649 "ProcessGDBRemote::ParseRegisters Size of register "
5650 "{0} is incompatible with vector type {1}",
5651 reg_info.
name, vector_type->GetID());
5655 "ProcessGDBRemote::ParseRegisters Size of register type "
5656 "{0} ({1} bytes) for register {2} does not match the "
5657 "register size ({3} bytes). Ignoring this type.",
5658 vector_type->GetID(), *type_size, reg_info.
name,
5663 if (!encoding_set) {
5665 encoding_set =
true;
5672 }
else if (
const auto *flags_type =
5673 llvm::dyn_cast<RegisterTypeFlags>(it->second)) {
5674 if (reg_info.
byte_size == flags_type->GetSize())
5679 "ProcessGDBRemote::ParseRegisters Size of register flags "
5680 "{0} ({1} bytes) for register {2} does not match the "
5681 "register size ({3} bytes). Ignoring this set of flags.",
5682 flags_type->GetID().c_str(), flags_type->GetSize(),
5690 if (!gdb_type.empty() && !(encoding_set || format_set)) {
5691 if (llvm::StringRef(gdb_type).starts_with(
"int")) {
5694 }
else if (gdb_type ==
"data_ptr" || gdb_type ==
"code_ptr") {
5697 }
else if (gdb_type ==
"float" || gdb_type ==
"ieee_single" ||
5698 gdb_type ==
"ieee_double") {
5701 }
else if (gdb_type ==
"aarch64v" ||
5702 llvm::StringRef(gdb_type).starts_with(
"vec") ||
5703 gdb_type ==
"i387_ext" || gdb_type ==
"uint128" ||
5716 "ProcessGDBRemote::ParseRegisters Could not determine lldb"
5717 "format and encoding for gdb type %s",
5727 if (!gdb_group.empty()) {
5738 "ProcessGDBRemote::{0} Skipping zero bitsize register {1}",
5739 __FUNCTION__, reg_info.
name);
5741 registers.push_back(reg_info);
5756 ArchSpec &arch_to_use, std::string xml_filename,
5757 std::vector<DynamicRegisterInfo::Register> ®isters) {
5759 llvm::Expected<std::string> raw =
m_gdb_comm.ReadExtFeature(
"features", xml_filename);
5760 if (errorToBool(raw.takeError()))
5765 if (xml_document.
ParseMemory(raw->c_str(), raw->size(),
5766 xml_filename.c_str())) {
5767 GdbServerTargetInfo target_info;
5768 std::vector<XMLNode> feature_nodes;
5774 const XMLNode &node) ->
bool {
5775 llvm::StringRef name = node.
GetName();
5776 if (name ==
"architecture") {
5778 }
else if (name ==
"osabi") {
5780 }
else if (name ==
"xi:include" || name ==
"include") {
5783 target_info.includes.push_back(href);
5784 }
else if (name ==
"feature") {
5785 feature_nodes.push_back(node);
5786 }
else if (name ==
"groups") {
5788 "group", [&target_info](
const XMLNode &node) ->
bool {
5790 RegisterSetInfo set_info;
5793 [&set_id, &set_info](
const llvm::StringRef &name,
5794 const llvm::StringRef &value) ->
bool {
5797 llvm::to_integer(value, set_id);
5804 target_info.reg_set_map[set_id] = set_info;
5817 feature_nodes.push_back(feature_node);
5819 const XMLNode &node) ->
bool {
5820 llvm::StringRef name = node.
GetName();
5821 if (name ==
"xi:include" || name ==
"include") {
5824 target_info.includes.push_back(href);
5838 if (!arch_to_use.
IsValid() && !target_info.arch.empty()) {
5840 arch_to_use.
SetTriple(llvm::StringSwitch<std::string>(target_info.arch)
5841 .Case(
"i386:x86-64",
"x86_64")
5842 .Case(
"riscv:rv64",
"riscv64")
5843 .Case(
"riscv:rv32",
"riscv32")
5844 .Default(target_info.arch) +
5852 for (
auto &feature_node : feature_nodes) {
5856 for (
const auto &include : target_info.includes) {
5868 std::vector<DynamicRegisterInfo::Register> ®isters,
5870 std::map<uint32_t, uint32_t> remote_to_local_map;
5871 uint32_t remote_regnum = 0;
5872 for (
auto it : llvm::enumerate(registers)) {
5880 remote_to_local_map[remote_reg_info.
regnum_remote] = it.index();
5886 auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) {
5887 auto lldb_regit = remote_to_local_map.find(process_regnum);
5888 return lldb_regit != remote_to_local_map.end() ? lldb_regit->second
5892 llvm::transform(remote_reg_info.value_regs,
5893 remote_reg_info.value_regs.begin(), proc_to_lldb);
5894 llvm::transform(remote_reg_info.invalidate_regs,
5895 remote_reg_info.invalidate_regs.begin(), proc_to_lldb);
5902 abi_sp->AugmentRegisterInfo(registers);
5912 if (!
m_gdb_comm.GetQXferFeaturesReadSupported())
5913 return llvm::createStringError(
5914 llvm::inconvertibleErrorCode(),
5915 "the debug server does not support \"qXfer:features:read\"");
5918 return llvm::createStringError(
5919 llvm::inconvertibleErrorCode(),
5920 "the debug server supports \"qXfer:features:read\", but LLDB does not "
5921 "have XML parsing enabled (check LLLDB_ENABLE_LIBXML2)");
5923 std::vector<DynamicRegisterInfo::Register> registers;
5931 ? llvm::ErrorSuccess()
5932 : llvm::createStringError(
5933 llvm::inconvertibleErrorCode(),
5934 "the debug server did not describe any registers");
5940 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5941 "XML parsing not available");
5944 LLDB_LOGF(log,
"ProcessGDBRemote::%s", __FUNCTION__);
5953 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries-svr4",
"");
5955 return raw.takeError();
5958 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5961 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5962 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5963 "Error reading noname.xml");
5967 return llvm::createStringError(
5968 llvm::inconvertibleErrorCode(),
5969 "Error finding library-list-svr4 xml element");
5974 if (!main_lm.empty())
5978 "library", [log, &list](
const XMLNode &library) ->
bool {
5983 [&module](
const llvm::StringRef &name,
5984 const llvm::StringRef &value) ->
bool {
5987 module.set_name(value.str());
5988 else if (name ==
"lm") {
5990 llvm::to_integer(value, uint_value);
5991 module.set_link_map(uint_value);
5992 }
else if (name ==
"l_addr") {
5995 llvm::to_integer(value, uint_value);
5996 module.set_base(uint_value);
5999 module.set_base_is_offset(true);
6000 }
else if (name ==
"l_ld") {
6002 llvm::to_integer(value, uint_value);
6003 module.set_dynamic(uint_value);
6012 bool base_is_offset;
6014 module.get_name(name);
6015 module.get_link_map(lm);
6016 module.get_base(base);
6017 module.get_base_is_offset(base_is_offset);
6018 module.get_dynamic(ld);
6021 "found (link_map:0x%08" PRIx64
", base:0x%08" PRIx64
6022 "[%s], ld:0x%08" PRIx64
", name:'%s')",
6023 lm, base, (base_is_offset ?
"offset" :
"absolute"), ld,
6032 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
6033 (
int)list.
m_list.size());
6037 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries",
"");
6040 return raw.takeError();
6042 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
6045 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
6046 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6047 "Error reading noname.xml");
6051 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6052 "Error finding library-list xml element");
6056 "library", [log, &list](
const XMLNode &library) ->
bool {
6060 module.set_name(name);
6069 llvm::to_integer(address, address_value);
6070 module.set_base(address_value);
6072 module.set_base_is_offset(false);
6077 bool base_is_offset;
6078 module.get_name(name);
6079 module.get_base(base);
6080 module.get_base_is_offset(base_is_offset);
6082 LLDB_LOGF(log,
"found (base:0x%08" PRIx64
"[%s], name:'%s')", base,
6083 (base_is_offset ?
"offset" :
"absolute"), name.c_str());
6091 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
6092 (
int)list.
m_list.size());
6095 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6096 "Remote libraries not supported");
6103 bool value_is_offset) {
6118 return module_list.takeError();
6124 std::string mod_name;
6127 bool mod_base_is_offset;
6130 valid &= modInfo.
get_name(mod_name);
6131 valid &= modInfo.
get_base(mod_base);
6144 if (module_sp.get())
6145 new_modules.
Append(module_sp);
6148 if (new_modules.
GetSize() > 0) {
6153 for (
size_t i = 0; i < loaded_modules.
GetSize(); ++i) {
6157 for (
size_t j = 0; j < new_modules.
GetSize(); ++j) {
6166 removed_modules.
Append(loaded_module);
6170 loaded_modules.
Remove(removed_modules);
6171 m_process->GetTarget().ModulesDidUnload(removed_modules,
false);
6190 m_process->GetTarget().ModulesDidLoad(new_modules);
6193 return llvm::ErrorSuccess();
6202 std::string file_path = file.
GetPath(
false);
6203 if (file_path.empty())
6224 "Fetching file load address from remote server returned an error");
6234 "Unknown error happened during sending the load address packet");
6255 std::string input = data.str();
6262 size_t found, pos = 0, len = input.length();
6263 while ((found = input.find(
end_delimiter, pos)) != std::string::npos) {
6265 input.substr(pos, found).c_str());
6266 std::string profile_data =
6281 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
6283 llvm::raw_string_ostream output_stream(output);
6284 llvm::StringRef name, value;
6288 if (name.compare(
"thread_used_id") == 0) {
6290 uint64_t thread_id = threadIDHexExtractor.
GetHexMaxU64(
false, 0);
6292 bool has_used_usec =
false;
6293 uint32_t curr_used_usec = 0;
6294 llvm::StringRef usec_name, usec_value;
6295 uint32_t input_file_pos = profileDataExtractor.
GetFilePos();
6297 if (usec_name ==
"thread_used_usec") {
6298 has_used_usec =
true;
6299 usec_value.getAsInteger(
BASE_10, curr_used_usec);
6303 profileDataExtractor.
SetFilePos(input_file_pos);
6307 if (has_used_usec) {
6308 uint32_t prev_used_usec = 0;
6309 std::map<uint64_t, uint32_t>::iterator iterator =
6312 prev_used_usec = iterator->second;
6314 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
6316 bool good_first_time =
6317 (prev_used_usec == 0) && (real_used_usec > 250000);
6318 bool good_subsequent_time =
6319 (prev_used_usec > 0) &&
6322 if (good_first_time || good_subsequent_time) {
6326 output_stream << name <<
":";
6328 output_stream << index_id <<
";";
6330 output_stream << usec_name <<
":" << usec_value <<
";";
6333 llvm::StringRef local_name, local_value;
6339 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
6342 output_stream << name <<
":" << value <<
";";
6345 output_stream << name <<
":" << value <<
";";
6380 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6381 "qSaveCore returned an error");
6386 for (
auto x : llvm::split(response.
GetStringRef(),
';')) {
6387 if (x.consume_front(
"core-path:"))
6393 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6394 "qSaveCore returned no core path");
6397 FileSpec remote_core{llvm::StringRef(path)};
6403 platform.
Unlink(remote_core);
6405 return error.ToError();
6411 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6412 "Unable to send qSaveCore");
6424 "GDBRemoteCommunicationClientBase::%s() received $J packet "
6425 "but was not a StructuredData packet: packet starts with "
6437 json_sp->Dump(json_str,
true);
6440 "ProcessGDBRemote::%s() "
6441 "received Async StructuredData packet: %s",
6442 __FUNCTION__, json_str.
GetData());
6445 "ProcessGDBRemote::%s"
6446 "() received StructuredData packet:"
6456 if (structured_data_sp)
6464 "Tests packet speeds of various sizes to determine "
6465 "the performance characteristics of the GDB remote "
6470 "The number of packets to send of each varying size "
6471 "(default is 1000).",
6474 "The maximum number of bytes to send in a packet. Sizes "
6475 "increase in powers of 2 while the size is less than or "
6476 "equal to this option value. (default 1024).",
6479 "The maximum number of bytes to receive in a packet. Sizes "
6480 "increase in powers of 2 while the size is less than or "
6481 "equal to this option value. (default 1024).",
6484 "Print the output as JSON data for easy parsing.", false, true) {
6504 if (!output_stream_sp)
6505 output_stream_sp =
m_interpreter.GetDebugger().GetAsyncOutputStream();
6508 const uint32_t num_packets =
6510 const uint64_t max_send =
m_max_send.GetOptionValue().GetCurrentValue();
6511 const uint64_t max_recv =
m_max_recv.GetOptionValue().GetCurrentValue();
6512 const bool json =
m_json.GetOptionValue().GetCurrentValue();
6513 const uint64_t k_recv_amount =
6516 num_packets, max_send, max_recv, k_recv_amount, json,
6541 "Dumps the packet history buffer. ", nullptr) {}
6562 interpreter,
"process plugin packet xfer-size",
6563 "Maximum size that lldb will try to read/write one one chunk.",
6574 "amount to be transferred when "
6585 uint64_t user_specified_max = strtoul(packet_size,
nullptr, 10);
6586 if (errno == 0 && user_specified_max != 0) {
6601 "Send a custom packet through the GDB remote "
6602 "protocol and print the answer. "
6603 "The packet header and footer will automatically "
6604 "be added to the packet prior to sending and "
6605 "stripped from the result.",
6616 "'%s' takes a one or more packet content arguments",
6624 for (
size_t i = 0; i < argc; ++i) {
6631 output_strm.
Printf(
" packet: %s\n", packet_cstr);
6632 std::string response_str = std::string(response.
GetStringRef());
6634 if (strstr(packet_cstr,
"qGetProfileData") !=
nullptr) {
6638 if (response_str.empty())
6639 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6652 "Send a qRcmd packet through the GDB remote protocol "
6653 "and print the response. "
6654 "The argument passed to this command will be hex "
6655 "encoded into a valid 'qRcmd' packet, sent and the "
6656 "response will be printed.") {}
6662 if (command.empty()) {
6679 [&output_strm](llvm::StringRef output) { output_strm << output; });
6682 const std::string &response_str = std::string(response.
GetStringRef());
6684 if (response_str.empty())
6685 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6697 "Commands that deal with GDB remote packets.",
6726 interpreter,
"process plugin",
6727 "Commands for operating on a ProcessGDBRemote process.",
6728 "process plugin <subcommand> [<subcommand-options>]") {
6739 m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(
6740 GetTarget().GetDebugger().GetCommandInterpreter());
6745 bool enable,
bool is_expression_fork) {
6751 if (!enable && is_expression_fork) {
6752 if (
auto entry =
GetTarget().GetEntryPointAddress())
6753 entry_addr = entry->GetOpcodeLoadAddress(&
GetTarget());
6767 "DidForkSwitchSoftwareBreakpoints: retaining expression-"
6768 "return trap at {0:x} in forked child",
6792 addr_t addr = wp_res_sp->GetLoadAddress();
6793 size_t size = wp_res_sp->GetByteSize();
6795 m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,
6801 bool is_expression_fork) {
6810 bool overrode_follow_mode =
false;
6813 if (is_expression_fork) {
6814 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6815 "to parent during expression evaluation");
6817 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6818 "to parent during expression evaluation. Child process "
6819 "{0} is available for manual attachment.",
6823 overrode_follow_mode =
true;
6834 switch (follow_fork_mode) {
6836 follow_pid = parent_pid;
6837 follow_tid = parent_tid;
6838 detach_pid = child_pid;
6839 detach_tid = child_tid;
6842 follow_pid = child_pid;
6843 follow_tid = child_tid;
6844 detach_pid = parent_pid;
6845 detach_tid = parent_tid;
6850 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6851 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to set pid/tid");
6865 if (!
m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) ||
6866 !
m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) {
6867 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to reset pid/tid");
6871 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6874 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6876 if (
error.Fail() && keep_stopped) {
6877 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach-and-stay-stopped not "
6878 "supported, falling back to normal detach");
6879 keep_stopped =
false;
6883 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach packet send failed: {0}",
6884 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6890 if (overrode_follow_mode && !is_expression_fork) {
6894 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
6895 "'parent' because an expression is being evaluated.\n"
6896 "Child process %" PRIu64
6897 " has been detached%s.\n"
6898 "You can attach to it with: process attach -p %" PRIu64
6901 keep_stopped ?
" and stopped" :
" (running)",
6917 bool is_expression_fork) {
6922 "ProcessGDBRemote::DidVFork() called for child_pid: {0}, child_tid {1}",
6923 child_pid, child_tid);
6929 bool overrode_follow_mode =
false;
6932 if (is_expression_fork) {
6933 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6934 "to parent during expression evaluation");
6936 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6937 "to parent during expression evaluation. Child process "
6938 "{0} is available for manual attachment.",
6942 overrode_follow_mode =
true;
6952 switch (follow_fork_mode) {
6954 detach_pid = child_pid;
6955 detach_tid = child_tid;
6958 detach_pid =
m_gdb_comm.GetCurrentProcessID();
6964 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6965 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to set pid/tid");
6973 if (!
m_gdb_comm.SetCurrentThread(child_tid, child_pid) ||
6974 !
m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) {
6975 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to reset pid/tid");
6981 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6982 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6984 if (
error.Fail() && keep_stopped) {
6985 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() detach-and-stay-stopped not "
6986 "supported, falling back to normal detach");
6987 keep_stopped =
false;
6992 "ProcessGDBRemote::DidVFork() detach packet send failed: {0}",
6993 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6997 if (overrode_follow_mode && !is_expression_fork) {
7001 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
7002 "'parent' because an expression is being evaluated.\n"
7003 "Child process %" PRIu64
7004 " has been detached%s.\n"
7005 "You can attach to it with: process attach -p %" PRIu64
7008 keep_stopped ?
" and stopped" :
" (running)",
7041 llvm::Error joined = llvm::Error::success();
7042 for (
auto &[site, action] : site_to_action) {
7046 joined = llvm::joinErrors(std::move(joined), std::move(
error));
7054static llvm::SmallVector<std::optional<uint8_t>>
7056 llvm::SmallVector<std::optional<uint8_t>> results;
7060 parsed ? parsed->GetAsDictionary() :
nullptr;
7068 llvm::StringRef token;
7069 if (
auto *
string = object->GetAsString())
7070 token =
string->GetValue();
7071 if (token ==
"OK") {
7072 results.push_back(std::nullopt);
7075 if (token.size() != 3 || !token.starts_with(
"E")) {
7076 results.push_back(uint8_t(0xff));
7079 uint8_t error_code = 0;
7080 if (token.drop_front(1).getAsInteger(
BASE_16, error_code))
7081 results.push_back(0xff);
7083 results.push_back(error_code);
7092static std::optional<GDBStoppointType>
7101 return std::nullopt;
7110 return std::nullopt;
7112 llvm_unreachable(
"unhandled BreakpointSite type");
7116struct BreakpointPacketInfo {
7117 BreakpointSite &site;
7118 size_t trap_opcode_size;
7123std::string to_string(
const BreakpointPacketInfo &info) {
7124 char packet = info.is_enable ?
'Z' :
'z';
7125 return llvm::formatv(
"{0}{1},{2:x-},{3:x-}", packet,
7127 info.trap_opcode_size)
7134 if (site_to_action.empty())
7135 return llvm::Error::success();
7136 if (!
m_gdb_comm.GetMultiBreakpointSupported())
7141 std::vector<BreakpointPacketInfo> breakpoint_infos;
7142 for (
auto [site, action] : site_to_action) {
7144 std::optional<GDBStoppointType> type =
7148 LLDB_LOG(log,
"MultiBreakpoint: site {0} at {1:x} can't be batched",
7149 site->GetID(), site->GetLoadAddress());
7153 breakpoint_infos.push_back(
7158 stream <<
"jMultiBreakpoint:";
7160 auto args_array = std::make_shared<StructuredData::Array>();
7161 for (
auto &bp_info : breakpoint_infos)
7162 args_array->AddStringItem(to_string(bp_info));
7165 packet_dict.
AddItem(
"breakpoint_requests", args_array);
7166 packet_dict.
Dump(stream,
false);
7170 llvm::Expected<StringExtractorGDBRemote> response =
7175 LLDB_LOG_ERROR(log, response.takeError(),
"jMultiBreakpoint failed: {0}");
7179 llvm::SmallVector<std::optional<uint8_t>> results =
7183 if (results.size() != breakpoint_infos.size())
7184 return llvm::createStringErrorV(
7185 "MultiBreakpoint response count mismatch (expected {0}, got {1})",
7186 site_to_action.size(), results.size());
7188 llvm::Error joined = llvm::Error::success();
7189 for (
auto [error_code, bp_info] :
7190 llvm::zip_equal(results, breakpoint_infos)) {
7193 auto error = llvm::createStringErrorV(
7194 "MultiBreakpoint: site {0} at {1:x} failed with E{2}",
7195 bp_info.site.GetID(), bp_info.site.GetLoadAddress(), error_code);
7196 joined = llvm::joinErrors(std::move(joined), std::move(
error));
7200 if (bp_info.is_enable)
static llvm::raw_ostream & error(Stream &strm)
static PluginProperties & GetGlobalPluginProperties()
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF_VERBOSE(log,...)
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_LOG_VERBOSE(log,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
static PluginProperties & GetGlobalPluginProperties()
static const char *const s_async_json_packet_prefix
#define DEBUGSERVER_BASENAME
static size_t SplitCommaSeparatedRegisterNumberString(const llvm::StringRef &comma_separated_register_numbers, std::vector< uint32_t > ®nums, int base)
static const char * end_delimiter
static GDBStoppointType GetGDBStoppointType(const WatchpointResourceSP &wp_res_sp)
static StructuredData::ObjectSP ParseStructuredDataPacket(llvm::StringRef packet)
static std::string BinaryInformationLevelToJSONKey(BinaryInformationLevel info_level)
static uint64_t ComputeNumRangesMultiMemRead(uint64_t max_packet_size, llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges)
Returns the number of ranges that is safe to request using MultiMemRead while respecting max_packet_s...
static std::optional< GDBStoppointType > GetStoppointType(BreakpointSite &site, bool insert, GDBRemoteCommunicationClient &gdb_comm)
Determine the GDB stoppoint type for a breakpoint site by checking which packet types the remote supp...
static FileSpec GetDebugserverPath(Platform &platform)
static llvm::SmallVector< std::optional< uint8_t > > ParseMultiBreakpointResponse(llvm::StringRef response_str)
Parse a MultiBreakpoint response into per-request results.
static const int end_delimiter_len
CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
~CommandObjectMultiwordProcessGDBRemote() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectProcessGDBRemotePacketHistory() override=default
CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter)
~CommandObjectProcessGDBRemotePacketMonitor() override=default
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override
CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter)
CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter)
~CommandObjectProcessGDBRemotePacketSend() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectProcessGDBRemotePacketXferSize() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter)
~CommandObjectProcessGDBRemotePacket() override=default
CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter)
Options * GetOptions() override
OptionGroupBoolean m_json
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectProcessGDBRemoteSpeedTest() override=default
OptionGroupOptions m_option_group
OptionGroupUInt64 m_max_send
OptionGroupUInt64 m_num_packets
CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter)
OptionGroupUInt64 m_max_recv
static lldb::ABISP FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch)
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetHighmemAddressableBits(uint32_t highmem_addressing_bits)
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
void SetLowmemAddressableBits(uint32_t lowmem_addressing_bits)
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
void Clear()
Clears the object state.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
A command line argument class.
static lldb::Encoding StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value=lldb::eEncodingInvalid)
static uint32_t StringToGenericRegister(llvm::StringRef s)
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
void ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char='\0')
Replaces the argument value at index idx to arg_str if idx is a valid argument index.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Class that manages the actual breakpoint that will be inserted into the running program.
BreakpointSite::Type GetType() const
void SetType(BreakpointSite::Type type)
void BroadcastEvent(lldb::EventSP &event_sp)
Broadcast an event which has no associated data.
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
friend class CommandInterpreter
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help="", llvm::StringRef syntax="", uint32_t flags=0)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
CommandInterpreter & m_interpreter
void SetStatus(lldb::ReturnStatus status)
void SetImmediateOutputStream(const lldb::StreamSP &stream_sp)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
lldb::StreamSP GetImmediateOutputStream() const
Stream & GetOutputStream()
A uniqued constant string class.
void SetCString(const char *cstr)
Set the C string value.
void SetString(llvm::StringRef s)
A subclass of DataBuffer that stores a data buffer on the heap.
lldb::StreamUP GetAsyncErrorStream()
TargetList & GetTargetList()
Get accessor for the target list.
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
lldb::StreamUP GetAsyncOutputStream()
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
ArtifactProviderID AddArtifactProvider(std::string name, ArtifactProvider provider)
Register provider to contribute file name.
void RemoveArtifactProvider(ArtifactProviderID id)
Unregister a provider. Thread-safe.
static Diagnostics & Instance()
static llvm::Expected< lldb::ModuleSP > LocateAndLoadBinary(Process *process, BinarySpec &bin_spec)
Find a binary and load it into a Target.
virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Locates or creates a module given by file and updates/loads the resulting module at the virtual base ...
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
const void * GetBytes() const
static const EventDataBytes * GetEventDataFromEvent(const Event *event_ptr)
size_t GetByteSize() const
lldb::ProcessSP GetProcessSP() const
Get accessor that creates a strong reference from the weak process reference contained in this object...
Represents a file descriptor action to be performed during process launch.
Action GetAction() const
Get the type of action.
const FileSpec & GetFileSpec() const
Get the file specification for open actions.
void Append(const FileSpec &file)
Append a FileSpec object to the list.
size_t GetSize() const
Get the number of files in the file list.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
void AppendPathComponent(llvm::StringRef component)
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Clear()
Clears the object state.
static const char * DEV_NULL
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
ValueType Get() const
Get accessor for all flags.
static Environment GetEnvironment()
static void Kill(lldb::pid_t pid, int signo)
static lldb::ListenerSP MakeListener(llvm::StringRef name)
bool get_name(std::string &out) const
bool get_link_map(lldb::addr_t &out) const
bool get_base_is_offset(bool &out) const
bool get_base(lldb::addr_t &out) const
void add(const LoadedModuleInfo &mod)
std::vector< LoadedModuleInfo > m_list
void PutCString(const char *cstr)
LazyBool GetFlash() const
lldb::offset_t GetBlocksize() const
lldb::SymbolSharedCacheUse GetSharedCacheBinaryLoading() const
A collection class for Module objects.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
static ModuleListProperties & GetGlobalModuleListProperties()
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
size_t GetSize() const
Gets the size of the module list.
void ForEach(std::function< IterationAction(const lldb::ModuleSP &module_sp)> const &callback) const
Applies 'callback' to each module in this ModuleList.
void Dump(Stream &strm) const
A class that describes an executable image and its associated object and symbol files.
virtual ObjectFile * GetObjectFile()
Get the object file representation for the current architecture.
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
A plug-in interface definition class for object file parsers.
@ eTypeExecutable
A normal executable.
@ eTypeDebugInfo
An object file that contains only debug information.
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
@ eTypeObjectFile
An intermediate object file.
@ eTypeDynamicLinker
The platform's dynamic linker executable.
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
@ eTypeSharedLibrary
A shared library that can be used during execution.
@ eTypeJIT
JIT code that has symbols, sections and possibly debug info.
A command line option parsing protocol class.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool CreateSettingForProcessPlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, llvm::StringRef description, bool is_global_property)
static lldb::OptionValuePropertiesSP GetSettingForProcessPlugin(Debugger &debugger, llvm::StringRef setting_name)
static bool UnregisterPlugin(ABICreateInstance create_callback)
An address in a process, qualified by an address space.
lldb::addr_t GetValue() const
std::optional< lldb::tid_t > GetThreadID() const
lldb::addr_space_t GetAddressSpace() const
bool GetIgnoreExisting() const
bool GetDetachOnError() const
bool GetWaitForLaunch() const
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
lldb::pid_t GetProcessID() const
FileSpec & GetExecutableFile()
uint32_t GetUserID() const
Environment & GetEnvironment()
void SetUserID(uint32_t uid)
const char * GetLaunchEventData() const
const FileAction * GetFileActionForFD(int fd) const
void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback)
void SetLaunchInSeparateProcessGroup(bool separate)
const FileSpec & GetWorkingDirectory() const
Args GetExtraStartupCommands() const
FollowForkMode GetFollowForkMode() const
std::chrono::seconds GetInterruptTimeout() const
A plug-in interface definition class for debugging a process.
lldb::IOHandlerSP m_process_input_reader
std::mutex m_process_input_reader_mutex
StopPointSiteList< lldb_private::BreakpointSite > & GetBreakpointSiteList()
virtual Status DisableSoftwareBreakpoint(BreakpointSite *bp_site)
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
ThreadList & GetThreadList()
void SetAddressableBitMasks(AddressableBits bit_masks)
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
void SetUnixSignals(lldb::UnixSignalsSP &&signals_sp)
virtual void ModulesDidLoad(ModuleList &module_list)
virtual llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buffer)
Reads each range individually via ReadMemoryFromInferior, bypassing the memory cache.
void ResumePrivateStateThread()
void MapSupportedStructuredDataPlugins(const StructuredData::Array &supported_type_names)
Loads any plugins associated with asynchronous structured data and maps the relevant supported type n...
std::map< lldb::BreakpointSiteSP, BreakpointAction, SiteIDCmp > BreakpointSiteToActionMap
virtual SystemRuntime * GetSystemRuntime()
Get the system runtime plug-in for this process.
std::map< uint64_t, uint32_t > m_thread_id_to_index_id_map
lldb::StateType GetPrivateState() const
void SetBreakpointSiteEnabled(BreakpointSite &site, bool is_enabled=true)
lldb::DynamicLoaderUP m_dyld_up
virtual Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries)
StopPointSiteList< lldb_private::WatchpointResource > m_watchpoint_resource_list
Watchpoint resources currently in use.
bool IsBreakpointSitePhysicallyEnabled(const BreakpointSite &site)
std::vector< AddressSpaceInfo > m_address_spaces
A list of address spaces for this process.
void AppendSTDOUT(const char *s, size_t len)
bool HasAssignedIndexIDToThread(uint64_t sb_thread_id)
lldb::ByteOrder GetByteOrder() const
void UpdateThreadListIfNeeded()
bool IsValid() const
Return whether this object is valid (i.e.
virtual void DidExec()
Called after a process re-execs itself.
void BroadcastAsyncProfileData(const std::string &one_profile_data)
lldb::UnixSignalsSP m_unix_signals_sp
lldb::tid_t m_interrupt_tid
virtual Status EnableSoftwareBreakpoint(BreakpointSite *bp_site)
bool RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp)
Route the incoming structured data dictionary to the right plugin.
virtual bool IsAlive()
Check if a process is still alive.
ThreadList m_thread_list_real
The threads for this process as are known to the protocol we are debugging with.
lldb::StateType m_last_broadcast_state
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
uint32_t AssignIndexIDToThread(uint64_t thread_id)
virtual bool SetExitStatus(int exit_status, llvm::StringRef exit_string)
Set accessor for the process exit status (return code).
MemoryCache m_memory_cache
uint32_t GetAddressByteSize() const
uint32_t GetStopID() const
void SetPrivateState(lldb::StateType state)
llvm::Expected< AddressSpaceInfo > GetAddressSpaceInfo(llvm::StringRef address_space_name)
lldb::StateType GetPublicState() const
void SetSTDIOFileDescriptor(int file_descriptor)
Associates a file descriptor with the process' STDIO handling and configures an asynchronous reading ...
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
ThreadList m_thread_list
The threads for this process as the user will see them.
const lldb::UnixSignalsSP & GetUnixSignals()
std::weak_ptr< Target > m_target_wp
The target that owns this process.
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
friend class DynamicLoader
size_t GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site)
const ProcessModID & GetModIDRef() const
ThreadedCommunication m_stdio_communication
Target & GetTarget()
Get the target object pointer for this module.
lldb::OptionValuePropertiesSP GetValueProperties() const
A pseudo terminal helper class.
llvm::Error OpenFirstAvailablePrimary(int oflag)
Open the first available pseudo terminal.
@ invalid_fd
Invalid file descriptor value.
int GetPrimaryFileDescriptor() const
The primary file descriptor accessor.
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
std::string GetSecondaryName() const
Get the name of the secondary pseudo terminal.
std::vector< Enumerator > Enumerators
const Enumerators & GetEnumerators() const
void DumpToLog(Log *log) const
unsigned GetSizeInBits() const
Get size of the field in bits. Will always be at least 1.
uint64_t GetMaxValue() const
The maximum unsigned value that could be contained in this field.
virtual std::optional< uint64_t > GetByteSize() const
Return this type's fixed size in bytes, if it has one.
virtual StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Status &error)
virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error)
Status CompleteSending(lldb::pid_t child_pid)
shared_fd_t GetSendableFD()
static llvm::Expected< Pair > CreatePair(std::optional< SocketProtocol > protocol=std::nullopt)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
static lldb::StopInfoSP CreateStopReasonWithMachException(Thread &thread, uint32_t exc_type, uint32_t exc_data_count, uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, bool pc_already_adjusted=true, bool adjust_pc_if_needed=false)
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread)
static lldb::StopInfoSP CreateStopReasonVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonWithInterrupt(Thread &thread, int signo, const char *description)
static lldb::StopInfoSP CreateStopReasonWithSignal(Thread &thread, int signo, const char *description=nullptr, std::optional< int > code=std::nullopt)
static lldb::StopInfoSP CreateStopReasonFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonVForkDone(Thread &thread)
static lldb::StopInfoSP CreateStopReasonWithWatchpointID(Thread &thread, lldb::break_id_t watch_id, bool silently_continue=false)
static lldb::StopInfoSP CreateStopReasonWithException(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(Thread &thread, lldb::break_id_t break_id)
static lldb::StopInfoSP CreateStopReasonHistoryBoundary(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonProcessorTrace(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread)
void ForEach(std::function< void(StopPointSite *)> const &callback)
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
ExecutionContextRef exe_ctx_ref
lldb::break_id_t GetID() const
virtual lldb::addr_t GetLoadAddress() const
bool HardwareRequired() const
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
const char * GetData() const
void Flush() override
Flush the stream.
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
size_t PutStringAsRawHex8(llvm::StringRef s)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
ObjectSP GetItemAtIndex(size_t idx) const
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
ObjectSP GetValueForKey(llvm::StringRef key) const
bool HasKey(llvm::StringRef key) const
void AddItem(llvm::StringRef key, ObjectSP value_sp)
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
void ForEach(std::function< bool(llvm::StringRef key, Object *object)> const &callback) const
Dictionary * GetAsDictionary()
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
uint64_t GetUnsignedIntegerValue(uint64_t fail_value=0)
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
std::shared_ptr< Array > ArraySP
Integer< uint64_t > UnsignedInteger
Defines a list of symbol context objects.
Defines a symbol context baton that can be handed other debug core functions.
A plug-in interface definition class for system runtimes.
virtual void AddThreadExtendedInfoPacketHints(lldb_private::StructuredData::ObjectSP dict)
Add key-value pairs to the StructuredData dictionary object with information debugserver may need whe...
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
Module * GetExecutableModulePointer()
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Debugger & GetDebugger() const
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
lldb::PlatformSP GetPlatform()
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
@ eBroadcastBitNewTargetCreated
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
bool MergeArchitecture(const ArchSpec &arch_spec)
void AddThreadSortedByIndexID(const lldb::ThreadSP &thread_sp)
static llvm::Expected< HostThread > LaunchThread(llvm::StringRef name, std::function< lldb::thread_result_t()> thread_function, size_t min_stack_byte_size=0)
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid, bool can_update=true)
Represents UUID's of various sizes.
bool SetFromStringRef(llvm::StringRef str)
static lldb::UnixSignalsSP Create(const ArchSpec &arch)
static std::vector< lldb::WatchpointResourceSP > AtomizeWatchpointRequest(lldb::addr_t addr, size_t size, bool read, bool write, WatchpointHardwareFeature supported_features, ArchSpec &arch)
Convert a user's watchpoint request into an array of memory regions, each region watched by one hardw...
XMLNode GetRootElement(const char *required_name=nullptr)
bool ParseMemory(const char *xml, size_t xml_length, const char *url="untitled.xml")
void ForEachChildElement(NodeCallback const &callback) const
llvm::StringRef GetName() const
bool GetElementText(std::string &text) const
std::string GetAttributeValue(const char *name, const char *fail_value=nullptr) const
void ForEachChildElementWithName(const char *name, NodeCallback const &callback) const
XMLNode FindFirstChildElementWithName(const char *name) const
void ForEachAttribute(AttributeCallback const &callback) const
@ eBroadcastBitRunPacketSent
PacketResult SendPacketAndReceiveResponseWithOutputSupport(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout, llvm::function_ref< void(llvm::StringRef)> output_callback)
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0), bool sync_on_timeout=true)
lldb::StateType SendContinuePacketAndWaitForResponse(ContinueDelegate &delegate, const UnixSignals &signals, llvm::StringRef payload, std::chrono::seconds interrupt_timeout, StringExtractorGDBRemote &response)
bool SupportsGDBStoppointPacket(GDBStoppointType type)
llvm::Expected< std::string > ReadExtFeature(llvm::StringRef object, llvm::StringRef annex)
void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm)
bool GetQXferLibrariesSVR4ReadSupported()
bool GetQXferLibrariesReadSupported()
void DumpHistory(Stream &strm)
Status FlashErase(lldb::addr_t addr, size_t size)
Status DisableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buf) override
Override of DoReadMemoryRanges that uses MultiMemRead to perform this operation in a single packet.
friend class ThreadGDBRemote
DataExtractor GetAuxvData() override
GDBRemoteCommunicationClient & GetGDBRemote()
static bool AcceleratorBreakpointHitCallback(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
Breakpoint callback invoked when an accelerator-plugin-requested breakpoint is hit.
Status DoConnectRemote(llvm::StringRef remote_url) override
Attach to a remote system via a URL.
void HandleAsyncStructuredDataPacket(llvm::StringRef data) override
Process asynchronously-received structured data.
void KillDebugserverProcess()
Status DoDestroy() override
llvm::Error DoDisableBreakpointSite(BreakpointSite &bp_site)
Disable a single breakpoint site directly by sending the appropriate z packet or restoring the origin...
std::vector< std::unique_ptr< RegisterType > > m_register_types
Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info)
StructuredData::ObjectSP m_jstopinfo_sp
virtual std::shared_ptr< ThreadGDBRemote > CreateThread(lldb::tid_t tid)
StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(lldb::addr_t image_list_address, lldb::addr_t image_count) override
Retrieve the list of shared libraries that are loaded for this process This method is used on pre-mac...
llvm::Error HandleAcceleratorActions(const AcceleratorActions &actions)
Handle a set of actions requested by an accelerator plugin.
StructuredData::ObjectSP m_shared_cache_info_sp
StructuredData::ObjectSP m_jthreadsinfo_sp
lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet)
static void MonitorDebugserverProcess(std::weak_ptr< ProcessGDBRemote > process_wp, lldb::pid_t pid, int signo, int exit_status)
StructuredData::ObjectSP GetSharedCacheInfo() override
Status DisableBreakpointSite(BreakpointSite *bp_site) override
Status EnableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
Status DoSignal(int signal) override
Sends a process a UNIX signal signal.
Status DoDeallocateMemory(lldb::addr_t ptr) override
Actually deallocate memory in the process.
Broadcaster m_async_broadcaster
bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec)
llvm::Error UpdateBreakpointSitesNotBatched(const BreakpointSiteToActionMap &site_to_action)
bool StopNoticingNewThreads() override
Call this to turn off the stop & notice new threads mode.
static bool NewThreadNotifyBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid, bool is_expression_fork=false) override
Called after a reported fork.
void DumpPluginHistory(Stream &s) override
The underlying plugin might store the low-level communication history for this session.
FlashRangeVector m_erased_flash_ranges
Status DoDetach(bool keep_stopped) override
Detaches from a running or stopped process.
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) override
Actually allocate memory in the process.
tid_sig_collection m_continue_C_tids
bool HasErased(FlashRange range)
std::optional< bool > DoGetWatchpointReportedAfter() override
Provide an override value in the subclass for lldb's CPU-based logic for whether watchpoint exception...
void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid, bool is_expression_fork=false) override
Called after a reported vfork.
Status WillLaunchOrAttach()
std::optional< uint32_t > GetWatchpointSlotCount() override
Get the number of watchpoints supported by this target.
GDBRemoteCommunicationClient m_gdb_comm
llvm::Expected< std::vector< uint8_t > > DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) override
Does the final operation to read memory tags.
llvm::DenseMap< ModuleCacheKey, ModuleSpec, ModuleCacheInfo > m_cached_module_specs
Status DoWillAttachToProcessWithID(lldb::pid_t pid) override
Called before attaching to a process.
friend class GDBRemoteCommunicationClient
void DidForkSwitchSoftwareBreakpoints(bool enable, bool is_expression_fork=false)
Status DoResume(lldb::RunDirection direction) override
Resumes all of a process's threads as configured using the Thread run control functions.
Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo ®ion_info) override
DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has removed non address bits from loa...
void DidLaunchOrAttach(ArchSpec &process_arch)
size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value)
FlashRangeVector::Entry FlashRange
Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded, lldb::addr_t &load_addr) override
Try to find the load address of a file.
MMapMap m_addr_to_mmap_size
bool GetThreadStopInfoFromJSON(ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp)
void DidLaunch() override
Called after launching a process.
void SetUserSpecifiedMaxMemoryTransferSize(uint64_t user_specified_max)
void AddRemoteRegisters(std::vector< DynamicRegisterInfo::Register > ®isters, const ArchSpec &arch_to_use)
Status UpdateAutomaticSignalFiltering() override
void HandleAsyncStdout(llvm::StringRef out) override
static llvm::StringRef GetPluginDescriptionStatic()
tid_sig_collection m_continue_S_tids
bool m_allow_flash_writes
lldb::BreakpointSP m_thread_create_bp_sp
std::map< uint32_t, std::string > ExpeditedRegisterMap
llvm::Error TraceStop(const TraceStopRequest &request) override
Stop tracing a live process or its threads.
StructuredData::ObjectSP GetExtendedInfoForThread(lldb::tid_t tid)
llvm::Error DoEnableBreakpointSite(BreakpointSite &bp_site)
Enable a single breakpoint site by trying Z0 (software), then Z1 (hardware), then manual memory write...
lldb::ThreadSP HandleThreadAsyncInterrupt(uint8_t signo, const std::string &description) override
Handle thread specific async interrupt and return the original thread that requested the async interr...
llvm::Expected< LoadedModuleInfoList > GetLoadedModuleList() override
Query remote GDBServer for a detailed loaded library list.
bool AcceleratorBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
bool m_waiting_for_attach
llvm::Error HandleAcceleratorConnection(const AcceleratorActions &actions)
Create a new target for an accelerator and connect it to the GDB server described by the action's con...
llvm::Error GetGDBServerRegisterInfo(ArchSpec &arch)
Status DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a process ID.
void HandleStopReply() override
Status EstablishConnectionIfNeeded(const ProcessInfo &process_info)
llvm::Error UpdateBreakpointSites(const BreakpointSiteToActionMap &site_to_action) override
bool UpdateThreadIDList()
static llvm::StringRef GetPluginNameStatic()
Status DoHalt(bool &caused_stop) override
Halts a running process.
uint64_t m_last_signals_version
llvm::Expected< TraceSupportedResponse > TraceSupported() override
Get the processor tracing type supported for this process.
std::map< std::string, int64_t > m_processed_accelerator_actions
Tracks the last action identifier handled per accelerator plugin so the same actions are not processe...
llvm::Error TraceStart(const llvm::json::Value &request) override
Start tracing a process or its threads.
void ParseExpeditedRegisters(ExpeditedRegisterMap &expedited_register_map, lldb::ThreadSP thread_sp)
size_t DoReadMemory(const ProcessAddress &process_addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a process.
void WillPublicStop() override
Called when the process is about to broadcast a public stop.
Status SendEventData(const char *data) override
bool StartNoticingNewThreads() override
Call this to set the lldb in the mode where it breaks on new thread creations, and then auto-restarts...
DynamicLoader * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
void RemoveNewThreadBreakpoints()
Remove the breakpoints associated with thread creation from the Target.
ArchSpec GetSystemArchitecture() override
Get the system architecture for this process.
Status ConfigureStructuredData(llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) override
Configure asynchronous structured data feature.
bool SupportsReverseDirection() override
Reports whether this process supports reverse execution.
void DidExec() override
Called after a process re-execs itself.
size_t PutSTDIN(const char *buf, size_t buf_size, Status &error) override
Puts data into this process's STDIN.
static void DebuggerInitialize(Debugger &debugger)
tid_collection m_thread_ids
Status DoAttachToProcessWithName(const char *process_name, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a partial process name.
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
std::optional< StringExtractorGDBRemote > m_last_stop_packet
CommandObject * GetPluginCommandObject() override
Return a multi-word command object that can be used to expose plug-in specific commands.
int64_t m_breakpoint_pc_offset
size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, Status &error) override
Actually do the writing of memory to a process.
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override
Launch a new process.
lldb::CommandObjectSP m_command_sp
void DidVForkDone() override
Called after reported vfork completion.
std::string HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &inputStringExtractor)
bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, std::string xml_filename, std::vector< DynamicRegisterInfo::Register > ®isters)
lldb::tid_t m_last_stop_primary_tid
bool m_use_g_packet_for_reading
Status DoWillAttachToProcessWithName(const char *process_name, bool wait_for_launch) override
Called before attaching to a process.
static std::chrono::seconds GetPacketTimeout()
lldb::ListenerSP m_async_listener_sp
std::pair< std::string, std::string > ModuleCacheKey
bool CalculateThreadStopInfo(ThreadGDBRemote *thread)
lldb::DynamicRegisterInfoSP m_register_info_sp
tid_collection m_continue_c_tids
bool SupportsMemoryTagging() override
Check whether the process supports memory tagging.
void BuildDynamicRegisterInfo(bool force)
tid_collection m_continue_s_tids
size_t UpdateThreadPCsFromStopReplyThreadsValue(llvm::StringRef value)
~ProcessGDBRemote() override
llvm::VersionTuple GetHostOSVersion() override
Sometimes the connection to a process can detect the host OS version that the process is running on.
lldb::tid_t m_initial_tid
llvm::Expected< StringExtractorGDBRemote > SendMultiMemReadPacket(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges)
std::map< uint64_t, uint32_t > m_thread_id_to_used_usec_map
Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, const std::vector< uint8_t > &tags) override
Does the final operation to write memory tags.
llvm::Error ParseMultiMemReadPacket(llvm::StringRef response_str, llvm::MutableArrayRef< uint8_t > buffer, unsigned expected_num_ranges, llvm::SmallVectorImpl< llvm::MutableArrayRef< uint8_t > > &memory_regions)
llvm::Expected< std::vector< uint8_t > > TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override
Get binary data given a trace technology and a data identifier.
llvm::Error HandleAcceleratorBreakpoints(const AcceleratorActions &actions)
Set the breakpoints requested by an accelerator plugin as internal breakpoints with a callback that n...
Status EnableBreakpointSite(BreakpointSite *bp_site) override
void ModulesDidLoad(ModuleList &module_list) override
ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
uint32_t m_vfork_in_progress_count
@ eBroadcastBitAsyncContinue
@ eBroadcastBitAsyncThreadShouldExit
@ eBroadcastBitAsyncThreadDidExit
Status WillResume() override
Called before resuming to a process.
std::mutex m_shared_cache_info_mutex
lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr, bool value_is_offset)
void SetLastStopPacket(const StringExtractorGDBRemote &response)
lldb::thread_result_t AsyncThread()
Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries) override
static std::chrono::milliseconds GetPacketTestDelay()
llvm::Error LoadModules() override
Sometimes processes know how to retrieve and load shared libraries.
uint64_t m_max_memory_size
void HandleAsyncMisc(llvm::StringRef data) override
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path, bool can_connect)
void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple) override
llvm::VersionTuple GetHostMacCatalystVersion() override
void DidForkSwitchHardwareTraps(bool enable)
HostThread m_async_thread
StructuredData::ObjectSP GetDynamicLoaderProcessState() override
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override
Try to fetch the module specification for a module with the given file name and architecture.
Status DoWillLaunch(Module *module) override
Called before launching to a process.
void DidAttach(ArchSpec &process_arch) override
Called after attaching a process.
llvm::Expected< bool > SaveCore(llvm::StringRef outfile) override
Save core dump into the specified file.
std::atomic< lldb::pid_t > m_debugserver_pid
std::optional< Diagnostics::ArtifactProviderID > m_diagnostics_artifact_id
Registration for the packet-history diagnostics provider, if enabled.
llvm::Expected< std::string > TraceGetState(llvm::StringRef type) override
Get the current tracing state of the process and its threads.
bool IsAlive() override
Check if a process is still alive.
void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override
void SetQueueInfo(std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue)
void SetNewlyAddedBinaries(const std::vector< lldb::addr_t > &added_binaries)
void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr)
void PrivateSetRegisterUnavailable(uint32_t reg)
lldb::RegisterContextSP GetRegisterContext() override
void SetDetailedBinariesInfo(StructuredData::ObjectSP &detailed_info)
void SetAssociatedWithLibdispatchQueue(lldb_private::LazyBool associated_with_libdispatch_queue) override
bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef< uint8_t > data)
#define LLDB_INVALID_SITE_ID
#define LLDB_INVALID_WATCH_ID
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_THREAD_ID
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_INVALID_PROCESS_ID
#define LLDB_DEFAULT_ADDRESS_SPACE_ID
#define LLDB_REGNUM_GENERIC_PC
lldb::ByteOrder InlHostByteOrder()
std::vector< DynamicRegisterInfo::Register > GetFallbackRegisters(const ArchSpec &arch_to_use)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length)
bool StateIsRunningState(lldb::StateType state)
Check if a state represents a state where the process or thread is running.
bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr, lldb::addr_t addr, lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset)
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
const char * GetPermissionsAsCString(uint32_t permissions)
void DumpProcessGDBRemotePacketHistory(void *p, const char *path)
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::BreakpointSite > BreakpointSiteSP
RunDirection
Execution directions.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
ConnectionStatus
Connection Status Types.
@ eConnectionStatusSuccess
Success.
std::shared_ptr< lldb_private::UnixSignals > UnixSignalsSP
@ eFormatCString
NULL terminated C strings.
@ eFormatCharArray
Print characters with no single quotes, used for character arrays that can contain non printable char...
@ eFormatInstruction
Disassemble an opcode.
@ eFormatVoid
Do not print this.
@ eFormatComplex
Floating point complex type.
@ eFormatHexFloat
ISO C99 hex float string.
@ eFormatOSType
OS character codes encoded into an integer 'PICT' 'text' etc...
@ eFormatAddressInfo
Describe what an address points to (func + offset with file/line, symbol + offset,...
@ eFormatCharPrintable
Only printable characters, '.' if not printable.
@ eFormatComplexInteger
Integer complex type.
@ eFormatFloat128
Disambiguate between 128-bit long double (which uses eFormatFloat) and __float128 (which uses eFormat...
std::shared_ptr< lldb_private::Platform > PlatformSP
StateType
Process and Thread States.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ eStateConnected
Process is connected to remote debug services, but not launched or attached to anything yet.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateAttaching
Process is currently trying to attach.
@ eStateExited
Process has exited and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eSymbolSharedCacheUseInferiorSharedCacheOnly
@ eSymbolSharedCacheUseHostAndInferiorSharedCache
std::shared_ptr< lldb_private::Stream > StreamSP
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::Process > ProcessSP
Encoding
Register encoding definitions.
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
@ eEncodingSint
signed integer
std::shared_ptr< lldb_private::Event > EventSP
@ eReturnStatusSuccessFinishResult
@ eArgTypeUnsignedInteger
std::shared_ptr< lldb_private::Watchpoint > WatchpointSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::WatchpointResource > WatchpointResourceSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
BinaryInformationLevel
When the Process plugin can retrieve information about all binaries loaded in the target process,...
@ eBinaryInformationLevelAddrName
@ eBinaryInformationLevelAddrNameUUID
@ eBinaryInformationLevelFull
@ eBinaryInformationLevelAddrOnly
std::shared_ptr< lldb_private::Target > TargetSP
std::unique_ptr< lldb_private::Stream > StreamUP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindProcessPlugin
num used by the process plugin - e.g.
Actions to be performed in the native process on behalf of an accelerator plugin.
std::vector< AcceleratorBreakpointInfo > breakpoints
New breakpoints to set. Nothing to set if this is empty.
int64_t identifier
Unique identifier for this action within the plugin.
std::string plugin_name
Unique name identifying the accelerator plugin.
std::optional< AcceleratorConnectionInfo > connect_info
If set, the client should create a new target and connect to the accelerator GDB server described her...
std::string session_name
Human-readable label for the accelerator target.
Sent by the client when a plugin-requested breakpoint is hit.
AcceleratorBreakpointInfo breakpoint
std::vector< SymbolValue > symbol_values
int64_t identifier
Unique breakpoint ID used to identify this breakpoint in the BreakpointWasHit callback.
std::vector< std::string > symbol_names
Symbol names whose values should be supplied when the breakpoint is hit.
std::optional< AcceleratorBreakpointByAddress > by_address
Breakpoint by load address.
std::optional< AcceleratorBreakpointByName > by_name
Breakpoint by function name.
Information the client needs to connect to an accelerator GDB server.
std::string triple
Target triple for the accelerator target.
bool synchronous
If true, connect synchronously: the client blocks until the accelerator process is connected and stop...
std::optional< std::string > exe_path
Path to the executable to use when creating the accelerator target.
std::string connect_url
Connection URL the client should connect to (as in "process connect<url>").
std::string platform_name
Name of the platform to select when creating the accelerator target.
A binary to find and load into a Target.
lldb::addr_t value
Address where the binary should be loaded, or read out of memory.
UUID uuid
UUID of the binary to be loaded.
bool force_symbol_search
Allow the search to do a possibly expensive external search for the ObjectFile and/or SymbolFile.
bool set_address_in_target
Whether the address of the binary should be set in the Target if it is added.
bool notify
Whether ModulesDidLoad should be called once the binary has been added to the Target.
bool value_is_offset
A flag indicating that value is an address, or an offset to be applied to the file addresses.
const RegisterType * register_type
std::vector< uint32_t > value_regs
std::vector< uint32_t > invalidate_regs
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