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")),
326 "async thread should exit");
328 "async thread continue");
330 "async thread did exit");
334 const uint32_t async_event_mask =
340 "ProcessGDBRemote::%s failed to listen for "
341 "m_async_broadcaster events",
345 const uint64_t timeout_seconds =
347 if (timeout_seconds > 0)
348 m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
356 llvm::sys::TimePoint<> now = std::chrono::system_clock::now();
357 std::string name = llvm::formatv(
358 "gdb-remote-packet-history-{0:%Y-%m-%dT%H-%M-%S}.txt", now);
360 std::move(name), [
this]() -> std::string {
391std::shared_ptr<ThreadGDBRemote>
393 return std::make_shared<ThreadGDBRemote>(*
this, tid);
397 const FileSpec &target_definition_fspec) {
403 if (module_object_sp) {
406 "gdb-server-target-definition",
error));
408 if (target_definition_sp) {
410 target_definition_sp->GetValueForKey(
"host-info"));
412 if (
auto host_info_dict = target_object->GetAsDictionary()) {
414 host_info_dict->GetValueForKey(
"triple");
415 if (
auto triple_string_value = triple_value->GetAsString()) {
416 std::string triple_string =
417 std::string(triple_string_value->GetValue());
418 ArchSpec host_arch(triple_string.c_str());
427 target_definition_sp->GetValueForKey(
"breakpoint-pc-offset");
428 if (breakpoint_pc_offset_value) {
429 if (
auto breakpoint_pc_int_value =
430 breakpoint_pc_offset_value->GetAsSignedInteger())
435 *target_definition_sp,
GetTarget().GetArchitecture()) > 0) {
444 const llvm::StringRef &comma_separated_register_numbers,
445 std::vector<uint32_t> ®nums,
int base) {
447 for (llvm::StringRef x : llvm::split(comma_separated_register_numbers,
',')) {
449 if (llvm::to_integer(x, reg, base))
450 regnums.push_back(reg);
452 return regnums.size();
464 const auto host_packet_timeout =
m_gdb_comm.GetHostDefaultPacketTimeout();
465 if (host_packet_timeout > std::chrono::seconds(0)) {
483 if (target_definition_fspec) {
489 target_definition_fspec.
GetPath() +
500 if (remote_process_arch.
IsValid())
501 arch_to_use = remote_process_arch;
503 arch_to_use = remote_host_arch;
506 arch_to_use = target_arch;
509 if (!register_info_err) {
516 "Failed to read register information from target XML: {0}");
517 LLDB_LOG(log,
"Now trying to use qRegisterInfo instead.");
520 std::vector<DynamicRegisterInfo::Register> registers;
521 uint32_t reg_num = 0;
525 const int packet_len =
526 ::snprintf(packet,
sizeof(packet),
"qRegisterInfo%x", reg_num);
527 assert(packet_len < (
int)
sizeof(packet));
530 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
534 llvm::StringRef name;
535 llvm::StringRef value;
539 if (name ==
"name") {
541 }
else if (name ==
"alt-name") {
543 }
else if (name ==
"bitsize") {
546 }
else if (name ==
"offset") {
548 }
else if (name ==
"encoding") {
552 }
else if (name ==
"format") {
556 llvm::StringSwitch<Format>(value)
598 }
else if (name ==
"set") {
600 }
else if (name ==
"gcc" || name ==
"ehframe") {
602 }
else if (name ==
"dwarf") {
604 }
else if (name ==
"generic") {
606 }
else if (name ==
"container-regs") {
608 }
else if (name ==
"invalidate-regs") {
614 registers.push_back(reg_info);
627 "the debug server supports Target Description XML but LLDB does "
628 "not have XML parsing enabled. Using \"qRegisterInfo\" was also "
629 "not possible. Register information may be incorrect or missing",
639 if (registers.empty()) {
641 if (!registers.empty())
644 "All other methods failed, using fallback register information.");
659 bool wait_for_launch) {
691 if (
m_gdb_comm.GetProcessArchitecture().IsValid()) {
694 if (
m_gdb_comm.GetHostArchitecture().IsValid()) {
705 "Process %" PRIu64
" was reported after connecting to "
706 "'%s', but state was not stopped: %s",
710 "Process %" PRIu64
" was reported after connecting to '%s', "
711 "but no stop reply packet was received",
712 pid, remote_url.str().c_str());
716 "ProcessGDBRemote::%s pid %" PRIu64
717 ": normalizing target architecture initial triple: %s "
718 "(GetTarget().GetArchitecture().IsValid() %s, "
719 "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
720 __FUNCTION__,
GetID(),
721 GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
723 m_gdb_comm.GetHostArchitecture().IsValid() ?
"true" :
"false");
729 if (
m_gdb_comm.GetProcessArchitecture().IsValid())
736 "ProcessGDBRemote::%s pid %" PRIu64
737 ": normalized target architecture triple: %s",
738 __FUNCTION__,
GetID(),
739 GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
756 LLDB_LOGF(log,
"ProcessGDBRemote::%s() entered", __FUNCTION__);
758 uint32_t launch_flags = launch_info.
GetFlags().
Get();
781 if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
783 "ProcessGDBRemote::%s provided with STDIO paths via "
784 "launch_info: stdin=%s, stdout=%s, stderr=%s",
786 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
787 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
788 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
790 LLDB_LOGF(log,
"ProcessGDBRemote::%s no STDIO paths given via launch_info",
793 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
794 if (stdin_file_spec || disable_stdio) {
809 if (
error.Success()) {
811 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
816 if (!stdin_file_spec)
818 FileSpec::Style::native);
819 if (!stdout_file_spec)
821 FileSpec::Style::native);
822 if (!stderr_file_spec)
824 FileSpec::Style::native);
825 }
else if (platform_sp && platform_sp->IsHost()) {
830 if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
834 if (!stdin_file_spec)
835 stdin_file_spec = secondary_name;
837 if (!stdout_file_spec)
838 stdout_file_spec = secondary_name;
840 if (!stderr_file_spec)
841 stderr_file_spec = secondary_name;
845 "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
846 "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
849 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
850 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
851 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
855 "ProcessGDBRemote::%s final STDIO paths after all "
856 "adjustments: stdin=%s, stdout=%s, stderr=%s",
858 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
859 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
860 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
864 if (stdout_file_spec)
866 if (stderr_file_spec)
869 if (launch_flags & eLaunchFlagUsePipes) {
872 auto [terminal_cols, terminal_rows] = GetClientTerminalSize();
873 m_gdb_comm.SetSTDIOWindowSize(terminal_cols, terminal_rows);
876 m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
877 m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
880 GetTarget().GetArchitecture().GetArchitectureName());
883 if (launch_event_data !=
nullptr && *launch_event_data !=
'\0')
884 m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
896 std::chrono::seconds(10));
902 const llvm::Triple &remote_triple =
904 if (remote_triple.getOS() != llvm::Triple::UnknownOS) {
905 FileSpec remote_exe_file(exe_file.GetPath(
false),
908 0, remote_exe_file.
GetPath(
true));
911 exe_file.GetPath(
true));
914 if (llvm::Error err =
m_gdb_comm.LaunchProcess(args)) {
917 llvm::fmt_consume(std::move(err)));
924 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
946 if (!disable_stdio) {
960 std::make_shared<IOHandlerProcessSTDIOWindows>(
this);
966 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
error.AsCString());
976 if (!connect_url.empty()) {
977 LLDB_LOGF(log,
"ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
978 connect_url.str().c_str());
979 std::unique_ptr<ConnectionFileDescriptor> conn_up(
982 const uint32_t max_retry_count = 50;
983 uint32_t retry_count = 0;
992 if (retry_count >= max_retry_count)
995 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1001 if (
error.Success())
1012 if (
error.Success())
1019 m_gdb_comm.GetListThreadsInStopReplySupported();
1029 auto handle_cmds = [&] (
const Args &args) ->
void {
1033 entry.c_str(), response);
1039 handle_cmds(platform_sp->GetExtraStartupCommands());
1056 if (remote_process_arch.
IsValid()) {
1057 process_arch = remote_process_arch;
1058 LLDB_LOG(log,
"gdb-remote had process architecture, using {0} {1}",
1062 process_arch =
m_gdb_comm.GetHostArchitecture();
1064 "gdb-remote did not have process architecture, using gdb-remote "
1065 "host architecture {0} {1}",
1076 LLDB_LOG(log,
"analyzing target arch, currently {0} {1}",
1088 if ((process_arch.
GetMachine() == llvm::Triple::arm ||
1089 process_arch.
GetMachine() == llvm::Triple::thumb) &&
1090 process_arch.
GetTriple().getVendor() == llvm::Triple::Apple) {
1093 "remote process is ARM/Apple, "
1094 "setting target arch to {0} {1}",
1099 const llvm::Triple &remote_triple = process_arch.
GetTriple();
1100 llvm::Triple new_target_triple = target_arch.
GetTriple();
1101 if (new_target_triple.getVendorName().size() == 0) {
1102 new_target_triple.setVendor(remote_triple.getVendor());
1104 if (new_target_triple.getOSName().size() == 0) {
1105 new_target_triple.setOS(remote_triple.getOS());
1107 if (new_target_triple.getEnvironmentName().size() == 0)
1108 new_target_triple.setEnvironment(remote_triple.getEnvironment());
1111 ArchSpec new_target_arch = target_arch;
1112 new_target_arch.
SetTriple(new_target_triple);
1118 "final target arch after adjustments for remote architecture: "
1137 m_gdb_comm.GetSupportedStructuredDataPlugins())
1146 if (platform_sp && platform_sp->IsConnected())
1154 llvm::Expected<std::vector<AcceleratorActions>> init_actions =
1155 m_gdb_comm.GetAcceleratorInitializeActions();
1156 if (!init_actions) {
1158 "failed to get accelerator initialize actions: {0}");
1163 "failed to handle accelerator actions: {0}");
1173 UUID standalone_uuid;
1175 bool standalone_value_is_offset;
1176 if (
m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value,
1177 standalone_value_is_offset)) {
1178 if (standalone_uuid.
IsValid()) {
1180 bin_spec.
uuid = standalone_uuid;
1181 bin_spec.
value = standalone_value;
1187 llvm::Expected<ModuleSP> module =
1191 << llvm::toString(module.takeError()) <<
"\n";
1203 std::vector<addr_t> bin_addrs =
m_gdb_comm.GetProcessStandaloneBinaries();
1204 if (bin_addrs.size()) {
1205 for (
addr_t addr : bin_addrs) {
1206 const bool notify =
true;
1213 .LoadPlatformBinaryAndSetup(
this, addr, notify))
1218 bin_spec.
value = addr;
1220 bin_spec.
notify = notify;
1222 llvm::Expected<ModuleSP> module =
1226 << llvm::toString(module.takeError()) <<
"\n";
1236 std::optional<QOffsets> offsets =
m_gdb_comm.GetQOffsets();
1241 size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==
1242 offsets->offsets.size();
1246 bool changed =
false;
1247 module_sp->SetLoadAddress(
GetTarget(), offsets->offsets[0],
1252 m_process->GetTarget().ModulesDidLoad(list);
1266 LLDB_LOGF(log,
"ProcessGDBRemote::%s()", __FUNCTION__);
1272 if (
error.Success()) {
1276 const int packet_len =
1277 ::snprintf(packet,
sizeof(packet),
"vAttach;%" PRIx64, attach_pid);
1280 std::make_shared<EventDataBytes>(llvm::StringRef(packet, packet_len));
1295 if (process_name && process_name[0]) {
1297 if (
error.Success()) {
1303 if (!
m_gdb_comm.GetVAttachOrWaitSupported()) {
1318 auto data_sp = std::make_shared<EventDataBytes>(packet.
GetString());
1339llvm::Expected<std::string>
1344llvm::Expected<std::vector<uint8_t>>
1356 process_arch.
Clear();
1372 return m_gdb_comm.GetReverseStepSupported() ||
1379 LLDB_LOGF(log,
"ProcessGDBRemote::Resume(%s)",
1384 if (listener_sp->StartListeningForEvents(
1386 listener_sp->StartListeningForEvents(
1393 bool continue_packet_error =
false;
1407 std::string pid_prefix;
1409 pid_prefix = llvm::formatv(
"p{0:x-}.",
GetID());
1411 if (num_continue_c_tids == num_threads ||
1416 continue_packet.
Format(
"vCont;c:{0}-1", pid_prefix);
1424 for (tid_collection::const_iterator
1427 t_pos != t_end; ++t_pos)
1428 continue_packet.
Format(
";c:{0}{1:x-}", pid_prefix, *t_pos);
1430 continue_packet_error =
true;
1435 for (tid_sig_collection::const_iterator
1438 s_pos != s_end; ++s_pos)
1439 continue_packet.
Format(
";C{0:x-2}:{1}{2:x-}", s_pos->second,
1440 pid_prefix, s_pos->first);
1442 continue_packet_error =
true;
1447 for (tid_collection::const_iterator
1450 t_pos != t_end; ++t_pos)
1451 continue_packet.
Format(
";s:{0}{1:x-}", pid_prefix, *t_pos);
1453 continue_packet_error =
true;
1458 for (tid_sig_collection::const_iterator
1461 s_pos != s_end; ++s_pos)
1462 continue_packet.
Format(
";S{0:x-2}:{1}{2:x-}", s_pos->second,
1463 pid_prefix, s_pos->first);
1465 continue_packet_error =
true;
1468 if (continue_packet_error)
1469 continue_packet.
Clear();
1472 continue_packet_error =
true;
1478 if (num_continue_c_tids > 0) {
1479 if (num_continue_c_tids == num_threads) {
1483 continue_packet_error =
false;
1484 }
else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
1485 num_continue_s_tids == 0 && num_continue_S_tids == 0) {
1489 continue_packet_error =
false;
1493 if (continue_packet_error && num_continue_C_tids > 0) {
1494 if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
1495 num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
1496 num_continue_S_tids == 0) {
1499 if (num_continue_C_tids > 1) {
1504 if (num_continue_C_tids > 1) {
1505 continue_packet_error =
false;
1508 continue_packet_error =
true;
1511 if (!continue_packet_error)
1515 continue_packet_error =
false;
1518 if (!continue_packet_error) {
1520 continue_packet.
Printf(
"C%2.2x", continue_signo);
1525 if (continue_packet_error && num_continue_s_tids > 0) {
1526 if (num_continue_s_tids == num_threads) {
1532 continue_packet_error =
false;
1533 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1534 num_continue_s_tids == 1 && num_continue_S_tids == 0) {
1538 continue_packet_error =
false;
1542 if (!continue_packet_error && num_continue_S_tids > 0) {
1543 if (num_continue_S_tids == num_threads) {
1546 continue_packet_error =
false;
1547 if (num_continue_S_tids > 1) {
1548 for (
size_t i = 1; i < num_threads; ++i) {
1550 continue_packet_error =
true;
1553 if (!continue_packet_error) {
1556 continue_packet.
Printf(
"S%2.2x", step_signo);
1558 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1559 num_continue_s_tids == 0 && num_continue_S_tids == 1) {
1563 continue_packet_error =
false;
1569 if (num_continue_s_tids > 0 || num_continue_S_tids > 0) {
1571 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1572 "support reverse-stepping");
1574 "target does not support reverse-stepping");
1577 if (num_continue_S_tids > 0) {
1580 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1582 "can't deliver signals while running in reverse");
1585 if (num_continue_s_tids > 1) {
1586 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: can't step multiple "
1587 "threads in reverse");
1589 "can't step multiple threads while reverse-stepping");
1595 if (!
m_gdb_comm.GetReverseContinueSupported()) {
1596 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1597 "support reverse-continue");
1599 "target does not support reverse execution of processes");
1602 if (num_continue_C_tids > 0) {
1605 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1607 "can't deliver signals while running in reverse");
1615 continue_packet_error =
false;
1618 if (continue_packet_error) {
1620 "can't make continue packet for this resume");
1625 "Trying to resume but the async thread is dead.");
1626 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Trying to resume but the "
1627 "async thread is dead.");
1632 std::make_shared<EventDataBytes>(continue_packet.
GetString());
1635 if (!listener_sp->GetEvent(event_sp, ResumeTimeout())) {
1637 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Resume timed out.");
1640 "Broadcast continue, but the async thread was "
1641 "killed before we got an ack back.");
1643 "ProcessGDBRemote::DoResume: Broadcast continue, but the "
1644 "async thread was killed before we got an ack back.");
1660 llvm::StringRef value) {
1666 auto pid_tid = thread_ids.
GetPidTid(pid);
1667 if (pid_tid && pid_tid->first == pid) {
1673 }
while (thread_ids.
GetChar() ==
',');
1679 llvm::StringRef value) {
1681 for (llvm::StringRef x : llvm::split(value,
',')) {
1683 if (llvm::to_integer(x,
pc, 16))
1693 if (threads_info_sp) {
1696 if (thread_infos && thread_infos->
GetSize() > 0) {
1720 const llvm::StringRef stop_info_str = stop_info.
GetStringRef();
1723 const size_t thread_pcs_pos = stop_info_str.find(
";thread-pcs:");
1724 if (thread_pcs_pos != llvm::StringRef::npos) {
1725 const size_t start = thread_pcs_pos + strlen(
";thread-pcs:");
1726 const size_t end = stop_info_str.find(
';', start);
1727 if (end != llvm::StringRef::npos) {
1728 llvm::StringRef value = stop_info_str.substr(start, end - start);
1733 const size_t threads_pos = stop_info_str.find(
";threads:");
1734 if (threads_pos != llvm::StringRef::npos) {
1735 const size_t start = threads_pos + strlen(
";threads:");
1736 const size_t end = stop_info_str.find(
';', start);
1737 if (end != llvm::StringRef::npos) {
1738 llvm::StringRef value = stop_info_str.substr(start, end - start);
1746 bool sequence_mutex_unavailable =
false;
1748 if (sequence_mutex_unavailable) {
1763 if (num_thread_ids == 0) {
1769 ThreadList old_thread_list_copy(old_thread_list);
1770 if (num_thread_ids > 0) {
1771 for (
size_t i = 0; i < num_thread_ids; ++i) {
1778 thread_sp.get(), thread_sp->GetID());
1781 thread_sp.get(), thread_sp->GetID());
1791 size_t old_num_thread_ids = old_thread_list_copy.
GetSize(
false);
1792 for (
size_t i = 0; i < old_num_thread_ids; i++) {
1794 if (old_thread_sp) {
1795 lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
1810 uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1823 if (thread_infos_sp) {
1827 const size_t n = thread_infos->
GetSize();
1828 for (
size_t i = 0; i < n; ++i) {
1834 if (tid == thread->GetID())
1860 addr_t pc = thread->GetRegisterContext()->GetPC();
1862 thread->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1864 thread->SetThreadStoppedAtUnexecutedBP(
pc);
1872 if (
GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
1882 for (
const auto &pair : expedited_register_map) {
1883 uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1893 reg_value_extractor.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
1901 uint8_t signo,
const std::string &thread_name,
const std::string &reason,
1902 const std::string &description, uint32_t exc_type,
1903 const std::vector<addr_t> &exc_data,
addr_t thread_dispatch_qaddr,
1904 bool queue_vars_valid,
1906 LazyBool associated_with_dispatch_queue,
addr_t dispatch_queue_t,
1907 std::string &queue_name,
QueueKind queue_kind, uint64_t queue_serial,
1908 std::vector<lldb::addr_t> &added_binaries,
1933 reg_ctx_sp->InvalidateIfNeeded(
true);
1941 if (reg_ctx_sp->ReconfigureRegisterInfo()) {
1944 reg_ctx_sp->InvalidateAllRegisters();
1951 thread_sp->SetName(thread_name.empty() ?
nullptr : thread_name.c_str());
1956 if (queue_vars_valid)
1957 gdb_thread->
SetQueueInfo(std::move(queue_name), queue_kind, queue_serial,
1958 dispatch_queue_t, associated_with_dispatch_queue);
1972 StopInfoSP current_stop_info_sp = thread_sp->GetPrivateStopInfo(
false);
1974 current_stop_info_sp) {
1975 thread_sp->SetStopInfo(current_stop_info_sp);
1979 if (!thread_sp->StopInfoIsUpToDate()) {
1982 addr_t pc = thread_sp->GetRegisterContext()->GetPC();
1984 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1986 thread_sp->SetThreadStoppedAtUnexecutedBP(
pc);
1988 if (exc_type != 0) {
1996 if (interrupt_thread)
1997 thread_sp = interrupt_thread;
1999 const size_t exc_data_size = exc_data.size();
2000 thread_sp->SetStopInfo(
2002 *thread_sp, exc_type, exc_data_size,
2003 exc_data_size >= 1 ? exc_data[0] : 0,
2004 exc_data_size >= 2 ? exc_data[1] : 0,
2005 exc_data_size >= 3 ? exc_data[2] : 0));
2008 bool handled =
false;
2009 bool did_exec =
false;
2012 if (!reason.empty() && reason !=
"none") {
2013 if (reason ==
"trace") {
2016 }
else if (reason ==
"breakpoint") {
2017 thread_sp->SetThreadHitBreakpointSite();
2025 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2026 thread_sp->SetStopInfo(
2028 *thread_sp, bp_site_sp->GetID()));
2031 thread_sp->SetStopInfo(invalid_stop_info_sp);
2034 }
else if (reason ==
"trap") {
2036 }
else if (reason ==
"watchpoint") {
2072 bool silently_continue =
false;
2082 silently_continue =
true;
2086 if (!wp_resource_sp) {
2088 LLDB_LOGF(log,
"failed to find watchpoint");
2095 watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
2098 *thread_sp, watch_id, silently_continue));
2100 }
else if (reason ==
"exception") {
2102 *thread_sp, description.c_str()));
2104 }
else if (reason ==
"history boundary") {
2106 *thread_sp, description.c_str()));
2108 }
else if (reason ==
"exec") {
2110 thread_sp->SetStopInfo(
2113 }
else if (reason ==
"processor trace") {
2115 *thread_sp, description.c_str()));
2116 }
else if (reason ==
"fork") {
2121 thread_sp->SetStopInfo(
2124 }
else if (reason ==
"vfork") {
2130 *thread_sp, child_pid, child_tid));
2132 }
else if (reason ==
"vforkdone") {
2133 thread_sp->SetStopInfo(
2139 if (!handled && signo && !did_exec) {
2160 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
2170 thread_sp->SetThreadHitBreakpointSite();
2172 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2174 thread_sp->GetRegisterContext()->SetPC(
pc);
2175 thread_sp->SetStopInfo(
2177 *thread_sp, bp_site_sp->GetID()));
2180 thread_sp->SetStopInfo(invalid_stop_info_sp);
2186 thread_sp->SetStopInfo(
2190 *thread_sp, signo, description.c_str()));
2201 if (interrupt_thread)
2202 thread_sp = interrupt_thread;
2205 *thread_sp, signo, description.c_str()));
2209 if (!description.empty()) {
2212 const char *stop_info_desc = stop_info_sp->GetDescription();
2213 if (!stop_info_desc || !stop_info_desc[0])
2214 stop_info_sp->SetDescription(description.c_str());
2217 *thread_sp, description.c_str()));
2227 const std::string &description) {
2236 *thread_sp, signo, description.c_str()));
2245 static constexpr llvm::StringLiteral g_key_tid(
"tid");
2246 static constexpr llvm::StringLiteral g_key_name(
"name");
2247 static constexpr llvm::StringLiteral g_key_reason(
"reason");
2248 static constexpr llvm::StringLiteral g_key_metype(
"metype");
2249 static constexpr llvm::StringLiteral g_key_medata(
"medata");
2250 static constexpr llvm::StringLiteral g_key_qaddr(
"qaddr");
2251 static constexpr llvm::StringLiteral g_key_dispatch_queue_t(
2252 "dispatch_queue_t");
2253 static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(
2254 "associated_with_dispatch_queue");
2255 static constexpr llvm::StringLiteral g_key_queue_name(
"qname");
2256 static constexpr llvm::StringLiteral g_key_queue_kind(
"qkind");
2257 static constexpr llvm::StringLiteral g_key_queue_serial_number(
"qserialnum");
2258 static constexpr llvm::StringLiteral g_key_registers(
"registers");
2259 static constexpr llvm::StringLiteral g_key_memory(
"memory");
2260 static constexpr llvm::StringLiteral g_key_description(
"description");
2261 static constexpr llvm::StringLiteral g_key_signal(
"signal");
2262 static constexpr llvm::StringLiteral g_key_added_binaries(
"added-binaries");
2263 static constexpr llvm::StringLiteral g_key_detailed_binaries_info(
2264 "detailed-binaries-info");
2269 std::string thread_name;
2271 std::string description;
2272 uint32_t exc_type = 0;
2273 std::vector<addr_t> exc_data;
2276 bool queue_vars_valid =
false;
2279 std::string queue_name;
2281 uint64_t queue_serial_number = 0;
2282 std::vector<addr_t> added_binaries;
2288 thread_dict->
ForEach([
this, &tid, &expedited_register_map, &thread_name,
2289 &signo, &reason, &description, &exc_type, &exc_data,
2290 &thread_dispatch_qaddr, &queue_vars_valid,
2291 &associated_with_dispatch_queue, &dispatch_queue_t,
2292 &queue_name, &queue_kind, &queue_serial_number,
2293 &added_binaries, &detailed_binaries_info](
2294 llvm::StringRef key,
2296 if (key == g_key_tid) {
2299 }
else if (key == g_key_metype) {
2301 exc_type =
object->GetUnsignedIntegerValue(0);
2302 }
else if (key == g_key_medata) {
2307 exc_data.push_back(object->GetUnsignedIntegerValue());
2311 }
else if (key == g_key_name) {
2312 thread_name = std::string(object->GetStringValue());
2313 }
else if (key == g_key_qaddr) {
2314 thread_dispatch_qaddr =
2316 }
else if (key == g_key_queue_name) {
2317 queue_vars_valid =
true;
2318 queue_name = std::string(object->GetStringValue());
2319 }
else if (key == g_key_queue_kind) {
2320 std::string queue_kind_str = std::string(object->GetStringValue());
2321 if (queue_kind_str ==
"serial") {
2322 queue_vars_valid =
true;
2324 }
else if (queue_kind_str ==
"concurrent") {
2325 queue_vars_valid =
true;
2328 }
else if (key == g_key_queue_serial_number) {
2329 queue_serial_number =
object->GetUnsignedIntegerValue(0);
2330 if (queue_serial_number != 0)
2331 queue_vars_valid =
true;
2332 }
else if (key == g_key_dispatch_queue_t) {
2333 dispatch_queue_t =
object->GetUnsignedIntegerValue(0);
2335 queue_vars_valid =
true;
2336 }
else if (key == g_key_associated_with_dispatch_queue) {
2337 queue_vars_valid =
true;
2338 bool associated =
object->GetBooleanValue();
2343 }
else if (key == g_key_reason) {
2344 reason = std::string(object->GetStringValue());
2345 }
else if (key == g_key_description) {
2346 description = std::string(object->GetStringValue());
2347 }
else if (key == g_key_registers) {
2350 if (registers_dict) {
2352 [&expedited_register_map](llvm::StringRef key,
2355 if (llvm::to_integer(key, reg))
2356 expedited_register_map[reg] =
2357 std::string(object->GetStringValue());
2361 }
else if (key == g_key_memory) {
2367 if (mem_cache_dict) {
2370 "address", mem_cache_addr)) {
2372 llvm::StringRef str;
2377 const size_t byte_size = bytes.
GetStringRef().size() / 2;
2380 const size_t bytes_copied =
2382 if (bytes_copied == byte_size)
2391 }
else if (key == g_key_signal)
2393 else if (key == g_key_added_binaries) {
2396 array->
ForEach([&added_binaries](
2399 object->GetAsUnsignedInteger();
2403 added_binaries.push_back(value);
2408 }
else if (key == g_key_detailed_binaries_info) {
2413 if (object->GetAsDictionary()) {
2415 object->Dump(json_str);
2416 detailed_binaries_info =
2424 tid, expedited_register_map, signo, thread_name, reason, description,
2425 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2426 associated_with_dispatch_queue, dispatch_queue_t, queue_name, queue_kind,
2427 queue_serial_number, added_binaries, detailed_binaries_info);
2433 const char stop_type = stop_packet.
GetChar();
2434 switch (stop_type) {
2453 const uint8_t signo = stop_packet.
GetHexU8();
2454 llvm::StringRef key;
2455 llvm::StringRef value;
2456 std::string thread_name;
2458 std::string description;
2459 std::vector<addr_t> added_binaries;
2461 uint32_t exc_type = 0;
2462 std::vector<addr_t> exc_data;
2464 bool queue_vars_valid =
2468 std::string queue_name;
2470 uint64_t queue_serial_number = 0;
2474 if (key.compare(
"metype") == 0) {
2476 value.getAsInteger(
BASE_16, exc_type);
2477 }
else if (key.compare(
"medata") == 0) {
2480 value.getAsInteger(
BASE_16, x);
2481 exc_data.push_back(x);
2482 }
else if (key.compare(
"thread") == 0) {
2485 auto pid_tid = thread_id.
GetPidTid(pid);
2487 stop_pid = pid_tid->first;
2488 tid = pid_tid->second;
2491 }
else if (key.compare(
"threads") == 0) {
2492 std::lock_guard<std::recursive_mutex> guard(
2495 }
else if (key.compare(
"thread-pcs") == 0) {
2500 while (!value.empty()) {
2501 llvm::StringRef pc_str;
2502 std::tie(pc_str, value) = value.split(
',');
2507 }
else if (key.compare(
"jstopinfo") == 0) {
2516 }
else if (key.compare(
"hexname") == 0) {
2520 }
else if (key.compare(
"name") == 0) {
2521 thread_name = std::string(value);
2522 }
else if (key.compare(
"qaddr") == 0) {
2523 value.getAsInteger(
BASE_16, thread_dispatch_qaddr);
2524 }
else if (key.compare(
"dispatch_queue_t") == 0) {
2525 queue_vars_valid =
true;
2526 value.getAsInteger(
BASE_16, dispatch_queue_t);
2527 }
else if (key.compare(
"qname") == 0) {
2528 queue_vars_valid =
true;
2532 }
else if (key.compare(
"qkind") == 0) {
2533 queue_kind = llvm::StringSwitch<QueueKind>(value)
2538 }
else if (key.compare(
"qserialnum") == 0) {
2539 if (!value.getAsInteger(
BASE_10, queue_serial_number))
2540 queue_vars_valid =
true;
2541 }
else if (key.compare(
"reason") == 0) {
2542 reason = std::string(value);
2543 }
else if (key.compare(
"description") == 0) {
2547 }
else if (key.compare(
"memory") == 0) {
2561 llvm::StringRef addr_str, bytes_str;
2562 std::tie(addr_str, bytes_str) = value.split(
'=');
2563 if (!addr_str.empty() && !bytes_str.empty()) {
2570 const size_t bytes_copied =
2572 if (bytes_copied == byte_size)
2576 }
else if (key.compare(
"watch") == 0 || key.compare(
"rwatch") == 0 ||
2577 key.compare(
"awatch") == 0) {
2580 value.getAsInteger(
BASE_16, wp_addr);
2588 reason =
"watchpoint";
2590 ostr.
Printf(
"%" PRIu64, wp_addr);
2591 description = std::string(ostr.
GetString());
2592 }
else if (key.compare(
"swbreak") == 0 || key.compare(
"hwbreak") == 0) {
2593 reason =
"breakpoint";
2594 }
else if (key.compare(
"replaylog") == 0) {
2595 reason =
"history boundary";
2596 }
else if (key.compare(
"library") == 0) {
2602 }
else if (key.compare(
"fork") == 0 || key.compare(
"vfork") == 0) {
2608 LLDB_LOG(log,
"Invalid PID/TID to fork: {0}", value);
2614 ostr.
Printf(
"%" PRIu64
" %" PRIu64, pid_tid->first, pid_tid->second);
2615 description = std::string(ostr.
GetString());
2616 }
else if (key.compare(
"addressing_bits") == 0) {
2617 uint64_t addressing_bits;
2618 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2621 }
else if (key.compare(
"low_mem_addressing_bits") == 0) {
2622 uint64_t addressing_bits;
2623 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2626 }
else if (key.compare(
"high_mem_addressing_bits") == 0) {
2627 uint64_t addressing_bits;
2628 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2631 }
else if (key ==
"added-binaries") {
2635 while (!value.empty()) {
2636 llvm::StringRef pc_str;
2637 std::tie(pc_str, value) = value.split(
',');
2640 added_binaries.push_back(
pc);
2642 }
else if (key ==
"detailed-binaries-info") {
2650 }
else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
2652 if (!key.getAsInteger(
BASE_16, reg))
2653 expedited_register_map[reg] = std::string(std::move(value));
2663 "Received stop for incorrect PID = {0} (inferior PID = {1})",
2685 tid, expedited_register_map, signo, thread_name, reason, description,
2686 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2687 associated_with_dispatch_queue, dispatch_queue_t, queue_name,
2688 queue_kind, queue_serial_number, added_binaries,
2689 detailed_binaries_info);
2737 if (!selected_thread_sp ||
2738 selected_thread_sp->GetID() != primary_thread_sp->GetID())
2739 m_thread_list.SetSelectedThreadByID(primary_thread_sp->GetID());
2766 LLDB_LOGF(log,
"ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
2770 if (
error.Success())
2772 "ProcessGDBRemote::DoDetach() detach packet sent successfully");
2775 "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
2776 error.AsCString() ?
error.AsCString() :
"<unknown error>");
2779 if (!
error.Success())
2794 LLDB_LOGF(log,
"ProcessGDBRemote::DoDestroy()");
2797 int exit_status = SIGABRT;
2798 std::string exit_string;
2805 exit_status = kill_res.get();
2806#if defined(__APPLE__)
2818 if (platform_sp && platform_sp->IsHost()) {
2821 reap_pid = waitpid(
GetID(), &status, WNOHANG);
2822 LLDB_LOGF(log,
"Reaped pid: %d, status: %d.\n", reap_pid, status);
2826 exit_string.assign(
"killed");
2828 exit_string.assign(llvm::toString(kill_res.takeError()));
2831 exit_string.assign(
"killed or interrupted while attaching.");
2837 exit_string.assign(
"destroying when not connected to debugserver");
2858 const bool did_exec =
2859 response.
GetStringRef().find(
";reason:exec;") != std::string::npos;
2862 LLDB_LOGF(log,
"ProcessGDBRemote::SetLastStopPacket () - detected exec");
2867 m_gdb_comm.ResetDiscoverableSettings(did_exec);
2892 LLDB_LOG_ERROR(log, list.takeError(),
"Failed to read module list: {0}.");
2894 addr = list->m_link_map;
2910 if (threads_info_sp) {
2915 const size_t n = thread_infos->
GetSize();
2916 for (
size_t i = 0; i < n; ++i) {
2940 xPacketState x_state =
m_gdb_comm.GetxPacketState();
2943 size_t max_memory_size = x_state != xPacketState::Unimplemented
2946 if (size > max_memory_size) {
2950 size = max_memory_size;
2963 llvm::formatv(
";address_space:{0};", llvm::utohexstr(addr_space,
true));
2964 if (info->is_thread_specific) {
2965 std::optional<lldb::tid_t> tid = process_addr.
GetThreadID();
2968 "address space \"%s\" is thread specific, but no thread was "
2970 info->name.c_str());
2973 suffix += llvm::formatv(
"thread:{0};", llvm::utohexstr(*tid,
true));
2979 ::snprintf(packet,
sizeof(packet),
"%c%" PRIx64
",%" PRIx64
"%s",
2980 x_state != xPacketState::Unimplemented ?
'x' :
'm',
2981 (uint64_t)addr, (uint64_t)size, suffix.c_str());
2982 assert(packet_len + 1 < (
int)
sizeof(packet));
2985 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
2990 if (x_state != xPacketState::Unimplemented) {
2995 llvm::StringRef data_received = response.
GetStringRef();
2996 if (x_state == xPacketState::Prefixed &&
2997 !data_received.consume_front(
"b")) {
2999 "unexpected response to GDB server memory read packet '{0}': "
3001 packet, data_received);
3006 size_t memcpy_size = std::min(size, data_received.size());
3007 memcpy(buf, data_received.data(), memcpy_size);
3011 llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size),
'\xdd');
3015 "memory read failed for 0x%" PRIx64, addr);
3018 "GDB server does not support reading memory");
3021 "unexpected response to GDB server memory read packet '%s': '%s'",
3033 uint64_t max_packet_size,
3037 constexpr uint64_t range_overhead = 33;
3038 uint64_t current_size = 0;
3039 for (
auto [idx, range] : llvm::enumerate(ranges)) {
3040 uint64_t potential_size = current_size + range.size + range_overhead;
3041 if (potential_size > max_packet_size) {
3044 "MultiMemRead input has a range (base = {0:x}, size = {1}) "
3045 "bigger than the maximum allowed by remote",
3046 range.base, range.size);
3050 return ranges.size();
3053llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>
3056 llvm::MutableArrayRef<uint8_t> buffer) {
3060 const llvm::ArrayRef<Range<lldb::addr_t, size_t>> original_ranges = ranges;
3061 llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> memory_regions;
3063 while (!ranges.empty()) {
3064 uint64_t num_ranges =
3066 if (num_ranges == 0)
3069 auto ranges_for_request = ranges.take_front(num_ranges);
3070 ranges = ranges.drop_front(num_ranges);
3072 llvm::Expected<StringExtractorGDBRemote> response =
3076 "MultiMemRead error response: {0}");
3080 llvm::StringRef response_str = response->GetStringRef();
3081 const unsigned expected_num_ranges = ranges_for_request.size();
3083 response_str, buffer, expected_num_ranges, memory_regions)) {
3085 "MultiMemRead error parsing response: {0}");
3089 return memory_regions;
3092llvm::Expected<StringExtractorGDBRemote>
3095 std::string packet_str;
3096 llvm::raw_string_ostream stream(packet_str);
3097 stream <<
"MultiMemRead:ranges:";
3099 auto range_to_stream = [&](
auto range) {
3101 stream << llvm::formatv(
"{0:x-},{1:x-}", range.base, range.size);
3103 llvm::interleave(ranges, stream, range_to_stream,
",");
3108 m_gdb_comm.SendPacketAndWaitForResponse(packet_str.data(), response,
3111 return llvm::createStringErrorV(
"MultiMemRead failed to send packet: '{0}'",
3115 return llvm::createStringErrorV(
"MultiMemRead failed: '{0}'",
3119 return llvm::createStringErrorV(
"MultiMemRead unexpected response: '{0}'",
3126 llvm::StringRef response_str, llvm::MutableArrayRef<uint8_t> buffer,
3127 unsigned expected_num_ranges,
3130 auto [sizes_str, memory_data] = response_str.split(
';');
3131 if (sizes_str.size() == response_str.size())
3132 return llvm::createStringErrorV(
3133 "MultiMemRead response missing field separator ';' in: '{0}'",
3137 unsigned num_sizes = 0;
3138 for (llvm::StringRef size_str : llvm::split(sizes_str,
',')) {
3140 if (size_str.getAsInteger(
BASE_16, read_size))
3141 return llvm::createStringErrorV(
3142 "MultiMemRead response has invalid size string: {0}", size_str);
3144 if (memory_data.size() < read_size)
3145 return llvm::createStringErrorV(
"MultiMemRead response did not have "
3146 "enough data, requested sizes: {0}",
3149 if (read_size > buffer.size())
3150 return llvm::createStringErrorV(
3151 "MultiMemRead response size {0} exceeds remaining buffer {1}",
3152 read_size, buffer.size());
3154 llvm::StringRef region_to_read = memory_data.take_front(read_size);
3155 memory_data = memory_data.drop_front(read_size);
3157 llvm::MutableArrayRef<uint8_t> region_to_write =
3158 buffer.take_front(read_size);
3159 buffer = buffer.drop_front(read_size);
3161 memcpy(region_to_write.data(), region_to_read.data(), read_size);
3162 memory_regions.push_back(region_to_write);
3166 if (num_sizes != expected_num_ranges)
3167 return llvm::createStringErrorV(
3168 "MultiMemRead response had {0} sizes, expected {1}", num_sizes,
3169 expected_num_ranges);
3171 return llvm::Error::success();
3175 return m_gdb_comm.GetMemoryTaggingSupported();
3178llvm::Expected<std::vector<uint8_t>>
3185 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3186 "Error reading memory tags from remote");
3190 llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
3191 std::vector<uint8_t> got;
3192 got.reserve(tag_data.size());
3193 std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
3199 const std::vector<uint8_t> &tags) {
3202 return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
3206 std::vector<ObjectFile::LoadableData> entries) {
3216 if (
error.Success())
3230 for (
size_t i = 0; i < size; ++i)
3255 if (blocksize == 0) {
3263 lldb::addr_t block_start_addr = addr - (addr % blocksize);
3264 size += (addr - block_start_addr);
3265 if ((size % blocksize) != 0)
3266 size += (blocksize - size % blocksize);
3282 auto overlap = last_range.GetRangeEnd() - range.
GetRangeBase();
3303 "flash erase failed for 0x%" PRIx64, addr);
3306 "GDB server does not support flashing");
3309 "unexpected response to GDB server flash erase packet '%s': '%s'",
3326 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"vFlashDone", response,
3336 "GDB server does not support flashing");
3339 "unexpected response to GDB server flash done packet: '%s'",
3354 if (size > max_memory_size) {
3358 size = max_memory_size;
3378 if (!
error.Success())
3380 packet.
Printf(
"vFlashWrite:%" PRIx64
":", addr);
3383 packet.
Printf(
"M%" PRIx64
",%" PRIx64
":", addr, (uint64_t)size);
3396 "memory write failed for 0x%" PRIx64, addr);
3399 "GDB server does not support writing memory");
3402 "unexpected response to GDB server memory write packet '%s': '%s'",
3415 ePermissionsWritable |
3416 ePermissionsExecutable);
3428 ConstString(
"mmap"), eFunctionNameTypeFull, options, sc_list);
3433 uint32_t permissions,
3439 allocated_addr =
m_gdb_comm.AllocateMemory(size, permissions);
3442 return allocated_addr;
3448 if (permissions & lldb::ePermissionsReadable)
3450 if (permissions & lldb::ePermissionsWritable)
3452 if (permissions & lldb::ePermissionsExecutable)
3461 "ProcessGDBRemote::%s no direct stub support for memory "
3462 "allocation, and InferiorCallMmap also failed - is stub "
3463 "missing register context save/restore capability?",
3470 "unable to allocate %" PRIu64
" bytes of memory with permissions %s",
3474 return allocated_addr;
3489 return m_gdb_comm.GetWatchpointReportedAfter();
3496 switch (supported) {
3501 "tried to deallocate memory without ever allocating memory");
3507 "unable to deallocate memory at 0x%" PRIx64, addr);
3519 "unable to deallocate memory at 0x%" PRIx64, addr);
3552 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3554 if (error_no == 0) {
3557 return llvm::Error::success();
3560 if (error_no != UINT8_MAX)
3561 return llvm::createStringErrorV(
3562 "error sending the breakpoint request: {0}", error_no);
3563 return llvm::createStringError(
"error sending the breakpoint request");
3565 LLDB_LOG(log,
"Software breakpoints are unsupported");
3570 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3572 if (error_no == 0) {
3575 return llvm::Error::success();
3578 if (error_no != UINT8_MAX)
3579 return llvm::createStringErrorV(
3580 "error sending the hardware breakpoint request: {0} "
3581 "(hardware breakpoint resources might be exhausted or unavailable)",
3583 return llvm::createStringError(
3584 "error sending the hardware breakpoint request "
3585 "(hardware breakpoint resources might be exhausted or unavailable)");
3587 LLDB_LOG(log,
"Hardware breakpoints are unsupported");
3591 return llvm::createStringError(
"hardware breakpoints are not supported");
3607 return error.takeError();
3613 return llvm::createStringError(
"unknown error");
3618 return llvm::createStringError(
"unknown error");
3622 return llvm::Error::success();
3626 assert(bp_site !=
nullptr);
3637 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3638 ") address = 0x%" PRIx64,
3639 site_id, (uint64_t)addr);
3644 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3645 ") address = 0x%" PRIx64
" -- SUCCESS (already enabled)",
3646 site_id, (uint64_t)addr);
3654 assert(bp_site !=
nullptr);
3659 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3660 ") addr = 0x%8.8" PRIx64,
3661 site_id, (uint64_t)addr);
3665 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3666 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3667 site_id, (uint64_t)addr);
3678 bool read = wp_res_sp->WatchpointResourceRead();
3679 bool write = wp_res_sp->WatchpointResourceWrite();
3681 assert((read || write) &&
3682 "WatchpointResource type is neither read nor write");
3698 addr_t addr = wp_sp->GetLoadAddress();
3700 LLDB_LOGF(log,
"ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
")",
3702 if (wp_sp->IsEnabled()) {
3704 "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
3705 ") addr = 0x%8.8" PRIx64
": watchpoint already enabled.",
3706 watchID, (uint64_t)addr);
3710 bool read = wp_sp->WatchpointRead();
3711 bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
3712 size_t size = wp_sp->GetByteSize();
3715 WatchpointHardwareFeature supported_features =
3718 std::vector<WatchpointResourceSP> resources =
3720 addr, size, read, write, supported_features, target_arch);
3745 bool set_all_resources =
true;
3746 std::vector<WatchpointResourceSP> succesfully_set_resources;
3747 for (
const auto &wp_res_sp : resources) {
3748 addr_t addr = wp_res_sp->GetLoadAddress();
3749 size_t size = wp_res_sp->GetByteSize();
3751 if (!
m_gdb_comm.SupportsGDBStoppointPacket(type) ||
3752 m_gdb_comm.SendGDBStoppointTypePacket(type,
true, addr, size,
3754 set_all_resources =
false;
3757 succesfully_set_resources.push_back(wp_res_sp);
3760 if (set_all_resources) {
3761 wp_sp->SetEnabled(
true, notify);
3762 for (
const auto &wp_res_sp : resources) {
3765 wp_res_sp->AddConstituent(wp_sp);
3773 for (
const auto &wp_res_sp : succesfully_set_resources) {
3774 addr_t addr = wp_res_sp->GetLoadAddress();
3775 size_t size = wp_res_sp->GetByteSize();
3777 m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3781 "Setting one of the watchpoint resources failed");
3797 addr_t addr = wp_sp->GetLoadAddress();
3800 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3801 ") addr = 0x%8.8" PRIx64,
3802 watchID, (uint64_t)addr);
3804 if (!wp_sp->IsEnabled()) {
3806 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3807 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3808 watchID, (uint64_t)addr);
3812 wp_sp->SetEnabled(
false, notify);
3816 if (wp_sp->IsHardware()) {
3817 bool disabled_all =
true;
3819 std::vector<WatchpointResourceSP> unused_resources;
3821 if (wp_res_sp->ConstituentsContains(wp_sp)) {
3823 addr_t addr = wp_res_sp->GetLoadAddress();
3824 size_t size = wp_res_sp->GetByteSize();
3825 if (
m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3827 disabled_all =
false;
3829 wp_res_sp->RemoveConstituent(wp_sp);
3830 if (wp_res_sp->GetNumberOfConstituents() == 0)
3831 unused_resources.push_back(wp_res_sp);
3835 for (
auto &wp_res_sp : unused_resources)
3838 wp_sp->SetEnabled(
false, notify);
3841 "Failure disabling one of the watchpoint locations");
3854 LLDB_LOGF(log,
"ProcessGDBRemote::DoSignal (signal = %d)", signo);
3869 if (platform_sp && !platform_sp->IsHost())
3874 const char *error_string =
error.AsCString();
3875 if (error_string ==
nullptr)
3884 static FileSpec g_debugserver_file_spec;
3891 std::string env_debugserver_path = host_env.lookup(
"LLDB_DEBUGSERVER_PATH");
3892 if (!env_debugserver_path.empty()) {
3893 debugserver_file_spec.
SetFile(env_debugserver_path,
3894 FileSpec::Style::native);
3895 LLDB_LOG(log,
"gdb-remote stub exe path set from environment variable: {0}",
3896 env_debugserver_path);
3898 debugserver_file_spec = g_debugserver_file_spec;
3900 return debugserver_file_spec;
3903 debugserver_file_spec = HostInfo::GetSupportExeDir();
3904 if (debugserver_file_spec) {
3907 LLDB_LOG(log,
"found gdb-remote stub exe '{0}'", debugserver_file_spec);
3909 g_debugserver_file_spec = debugserver_file_spec;
3912 if (!debugserver_file_spec) {
3915 LLDB_LOG(log,
"could not find gdb-remote stub exe '{0}'",
3916 debugserver_file_spec);
3920 g_debugserver_file_spec.
Clear();
3923 return debugserver_file_spec;
3928 using namespace std::placeholders;
3938 const std::weak_ptr<ProcessGDBRemote> this_wp =
3939 std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3946#if defined(__APPLE__)
3950 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
3952 struct kinfo_proc processInfo;
3953 size_t bufsize =
sizeof(processInfo);
3954 if (sysctl(mib, (
unsigned)(
sizeof(mib) /
sizeof(
int)), &processInfo, &bufsize,
3957 if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
3958 debugserver_path =
FileSpec(
"/Library/Apple/usr/libexec/oah/debugserver");
3965 "'. Please ensure it is properly installed "
3966 "and available in your PATH");
3981 debugserver_launch_info,
nullptr);
3986 LLDB_LOGF(log,
"failed to start debugserver process: %s",
3996 m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>(
3997 std::move(socket_pair->second)));
4011 std::weak_ptr<ProcessGDBRemote> process_wp,
lldb::pid_t debugserver_pid,
4020 "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
4021 ", signo=%i (0x%x), exit_status=%i)",
4022 __FUNCTION__, debugserver_pid, signo, signo, exit_status);
4024 std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
4025 LLDB_LOGF(log,
"ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
4026 static_cast<void *
>(process_sp.get()));
4027 if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
4033 std::this_thread::sleep_for(std::chrono::milliseconds(500));
4037 const StateType state = process_sp->GetState();
4046 llvm::StringRef signal_name =
4047 process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);
4049 if (!signal_name.empty())
4050 stream.
Format(format_str, signal_name);
4052 stream.
Format(format_str, signo);
4054 process_sp->SetExitStatus(-1, stream.
GetString());
4077 debugger, PluginProperties::GetSettingName())) {
4078 const bool is_global_setting =
true;
4081 "Properties for the gdb-remote process plug-in.", is_global_setting);
4088 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
4095 llvm::Expected<HostThread> async_thread =
4099 if (!async_thread) {
4101 "failed to launch host thread: {0}");
4107 "ProcessGDBRemote::%s () - Called when Async thread was "
4117 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
4132 "ProcessGDBRemote::%s () - Called when Async thread was not running.",
4138 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread starting...",
4139 __FUNCTION__,
GetID());
4157 "ProcessGDBRemote::%s(pid = %" PRIu64
4158 ") listener.WaitForEvent (NULL, event_sp)...",
4159 __FUNCTION__,
GetID());
4162 const uint32_t event_type = event_sp->GetType();
4165 "ProcessGDBRemote::%s(pid = %" PRIu64
4166 ") Got an event of type: %d...",
4167 __FUNCTION__,
GetID(), event_type);
4169 switch (event_type) {
4174 if (continue_packet) {
4175 const char *continue_cstr =
4176 (
const char *)continue_packet->
GetBytes();
4177 const size_t continue_cstr_len = continue_packet->
GetByteSize();
4179 "ProcessGDBRemote::%s(pid = %" PRIu64
4180 ") got eBroadcastBitAsyncContinue: %s",
4181 __FUNCTION__,
GetID(), continue_cstr);
4183 if (::strstr(continue_cstr,
"vAttach") ==
nullptr)
4190 llvm::StringRef(continue_cstr, continue_cstr_len),
4201 switch (stop_state) {
4214 int exit_status = response.
GetHexU8();
4215 std::string desc_string;
4217 llvm::StringRef desc_str;
4218 llvm::StringRef desc_token;
4220 if (desc_token !=
"description")
4235 if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4238 "System Integrity Protection");
4239 }
else if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4259 "ProcessGDBRemote::%s(pid = %" PRIu64
4260 ") got eBroadcastBitAsyncThreadShouldExit...",
4261 __FUNCTION__,
GetID());
4267 "ProcessGDBRemote::%s(pid = %" PRIu64
4268 ") got unknown event 0x%8.8x",
4269 __FUNCTION__,
GetID(), event_type);
4276 "ProcessGDBRemote::%s(pid = %" PRIu64
4277 ") listener.WaitForEvent (NULL, event_sp) => false",
4278 __FUNCTION__,
GetID());
4283 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread exiting...",
4284 __FUNCTION__,
GetID());
4316 LLDB_LOGF(log,
"Hit New Thread Notification breakpoint.");
4323class AcceleratorBreakpointCallbackBaton
4324 :
public TypedBaton<AcceleratorBreakpointHitArgs> {
4326 explicit AcceleratorBreakpointCallbackBaton(
4327 std::unique_ptr<AcceleratorBreakpointHitArgs> data)
4346 "ProcessGDBRemote::HandleAcceleratorActions skipping already "
4347 "processed actions for plugin '{0}' with identifier {1}",
4349 return llvm::Error::success();
4366 return llvm::Error::success();
4376 std::string exe_path = connect_info.
exe_path.value_or(
"");
4380 &platform_options, accelerator_target_sp);
4382 return error.takeError();
4383 if (!accelerator_target_sp)
4384 return llvm::createStringError(
"failed to create accelerator target");
4386 PlatformSP platform_sp = accelerator_target_sp->GetPlatform();
4388 return llvm::createStringErrorV(
4389 "no platform '{0}' compatible with triple '{1}' for the accelerator "
4394 ? platform_sp->ConnectProcessSynchronous(
4398 : platform_sp->ConnectProcess(connect_info.
connect_url,
4400 accelerator_target_sp.get(),
error);
4402 return error.takeError();
4404 return llvm::createStringError(
"failed to connect to the accelerator");
4406 accelerator_target_sp->SetTargetSessionName(actions.
session_name);
4409 auto event_sp = std::make_shared<Event>(
4412 accelerator_target_sp));
4414 return llvm::Error::success();
4420 llvm::Error
error = llvm::Error::success();
4424 auto args_up = std::make_unique<AcceleratorBreakpointHitArgs>();
4426 args_up->breakpoint = bp;
4433 error = llvm::joinErrors(
4435 llvm::createStringErrorV(
4436 "accelerator breakpoint {0} specifies both a by_name and a "
4437 "by_address specification",
4445 bp_modules.
GetSize() ? &bp_modules :
nullptr,
4447 bp.
by_name->function_name.c_str(),
4448 eFunctionNameTypeFull,
4460 error = llvm::joinErrors(
4462 llvm::createStringErrorV(
4463 "accelerator breakpoint {0} has neither a by_name nor a "
4464 "by_address specification",
4470 error = llvm::joinErrors(
4472 llvm::createStringErrorV(
"failed to set accelerator breakpoint {0}",
4480 llvm::formatv(
"accelerator-plugin ({0})", actions.
plugin_name);
4481 bp_sp->SetBreakpointKind(kind.c_str());
4482 auto baton_sp = std::make_shared<AcceleratorBreakpointCallbackBaton>(
4483 std::move(args_up));
4511 for (
size_t i = 0; i < symbol_names.size(); ++i) {
4519 addr_t load_addr = sc.symbol->GetAddress().GetLoadAddress(&target);
4528 llvm::Expected<AcceleratorBreakpointHitResponse> response =
4532 "accelerator breakpoint hit notification failed: {0}");
4540 if (response->disable_bp) {
4542 bp_sp->SetEnabled(
false);
4547 if (response->actions) {
4551 std::string message = llvm::toString(std::move(
error));
4552 LLDB_LOG(log,
"failed to handle accelerator actions: {0}", message);
4554 "error: accelerator plugin '%s': %s\n",
4555 response->actions->plugin_name.c_str(), message.c_str());
4560 return !response->auto_resume_native;
4565 LLDB_LOG(log,
"Check if need to update ignored signals");
4579 LLDB_LOG(log,
"Signals' version hasn't changed. version={0}",
4584 auto signals_to_ignore =
4589 "Signals' version changed. old version={0}, new version={1}, "
4590 "signals ignored={2}, update result={3}",
4592 signals_to_ignore.size(),
error);
4594 if (
error.Success())
4609 platform_sp->SetThreadCreationBreakpoint(
GetTarget());
4612 log,
"Successfully created new thread notification breakpoint %i",
4617 LLDB_LOGF(log,
"Failed to create new thread notification breakpoint.");
4646 return_value =
m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
4647 if (return_value != 0) {
4650 "Sending events is not supported for this process.");
4660 if (
m_gdb_comm.GetQXferAuxvReadSupported()) {
4661 llvm::Expected<std::string> response =
m_gdb_comm.ReadExtFeature(
"auxv",
"");
4663 buf = std::make_shared<DataBufferHeap>(response->c_str(),
4664 response->length());
4675 if (
m_gdb_comm.GetThreadExtendedInfoSupported()) {
4681 args_dict->GetAsDictionary()->AddIntegerItem(
"thread", tid);
4684 packet <<
"jThreadExtendedInfo:";
4685 args_dict->Dump(packet,
false);
4692 packet << (char)(0x7d ^ 0x20);
4701 if (!response.
Empty()) {
4714 args_dict->GetAsDictionary()->AddIntegerItem(
"image_list_address",
4715 image_list_address);
4716 args_dict->GetAsDictionary()->AddIntegerItem(
"image_count", image_count);
4723 std::string info_level_str;
4725 info_level_str =
"address-only";
4727 info_level_str =
"address-name";
4729 info_level_str =
"address-name-uuid";
4731 info_level_str =
"full";
4733 return info_level_str;
4740 args_dict->GetAsDictionary()->AddBooleanItem(
"fetch_all_solibs",
true);
4742 args_dict->GetAsDictionary()->AddBooleanItem(
"report_load_commands",
false);
4744 if (!info_level_str.empty())
4745 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4746 info_level_str.c_str());
4753 const std::vector<lldb::addr_t> &load_addresses) {
4757 for (
auto addr : load_addresses)
4758 addresses->AddIntegerItem(addr);
4760 args_dict->GetAsDictionary()->AddItem(
"solib_addresses", addresses);
4763 if (!info_level_str.empty())
4764 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4765 info_level_str.c_str());
4775 if (
m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
4778 std::chrono::seconds(10));
4781 packet <<
"jGetLoadedDynamicLibrariesInfos:";
4782 args_dict->Dump(packet,
false);
4789 packet << (char)(0x7d ^ 0x20);
4798 if (!response.
Empty()) {
4811 if (
m_gdb_comm.GetDynamicLoaderProcessStateSupported()) {
4814 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"jGetDyldProcessState",
4820 if (!response.
Empty()) {
4835 if (*shared_cache_info || !
m_gdb_comm.GetSharedCacheInfoSupported())
4836 return *shared_cache_info;
4839 packet <<
"jGetSharedCacheInfo:";
4840 args_dict->Dump(packet,
false);
4849 if (response.
Empty())
4858 if (!dict->
HasKey(
"shared_cache_uuid"))
4860 llvm::StringRef uuid_str;
4862 uuid_str ==
"00000000-0000-0000-0000-000000000000")
4864 if (dict->
HasKey(
"shared_cache_path")) {
4878 HostInfo::SharedCacheIndexFiles(sc_path, uuid, sc_mode);
4881 *shared_cache_info = response_sp;
4884 return *shared_cache_info;
4889 return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
4902 const uint64_t reasonable_largeish_default = 128 * 1024;
4903 const uint64_t conservative_default = 512;
4906 uint64_t stub_max_size =
m_gdb_comm.GetRemoteMaxPacketSize();
4907 if (stub_max_size !=
UINT64_MAX && stub_max_size != 0) {
4913 if (stub_max_size > reasonable_largeish_default) {
4914 stub_max_size = reasonable_largeish_default;
4920 if (stub_max_size > 70)
4921 stub_max_size -= 32 + 32 + 6;
4926 LLDB_LOG(log,
"warning: Packet size is too small. "
4927 "LLDB may face problems while writing memory");
4938 uint64_t user_specified_max) {
4939 if (user_specified_max != 0) {
4967 module_spec = cached->second;
4968 return bool(module_spec);
4971 if (!
m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
4972 LLDB_LOGF(log,
"ProcessGDBRemote::%s - failed to get module info for %s:%s",
4973 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4980 module_spec.
Dump(stream);
4981 LLDB_LOGF(log,
"ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
4982 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4991 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4992 auto module_specs =
m_gdb_comm.GetModulesInfo(module_file_specs, triple);
4994 for (
const FileSpec &spec : module_file_specs)
4999 triple.getTriple())] = spec;
5013typedef std::vector<std::string> stringVec;
5015typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
5016struct RegisterSetInfo {
5020typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
5022struct GdbServerTargetInfo {
5026 RegisterSetMap reg_set_map;
5029using RegisterTypeMap = llvm::StringMap<const RegisterType *>;
5032ParseEnumEvalues(
const XMLNode &enum_node) {
5046 std::map<uint64_t, RegisterTypeEnum::Enumerator> enumerators;
5049 "evalue", [&enumerators, &log](
const XMLNode &enumerator_node) {
5050 std::optional<llvm::StringRef> name;
5051 std::optional<uint64_t> value;
5054 [&name, &value, &log](
const llvm::StringRef &attr_name,
5055 const llvm::StringRef &attr_value) {
5056 if (attr_name ==
"name") {
5057 if (attr_value.size())
5060 LLDB_LOG(log,
"ProcessGDBRemote::ParseEnumEvalues "
5061 "Ignoring empty name in evalue");
5062 }
else if (attr_name ==
"value") {
5063 uint64_t parsed_value = 0;
5064 if (llvm::to_integer(attr_value, parsed_value))
5065 value = parsed_value;
5068 "ProcessGDBRemote::ParseEnumEvalues "
5069 "Invalid value \"{0}\" in "
5074 "ProcessGDBRemote::ParseEnumEvalues Ignoring "
5075 "unknown attribute "
5076 "\"{0}\" in evalue",
5084 enumerators.insert_or_assign(
5085 *value, RegisterTypeEnum::Enumerator(*value, name->str()));
5092 for (
auto [_, enumerator] : enumerators)
5093 final_enumerators.push_back(enumerator);
5095 return final_enumerators;
5099ParseEnums(XMLNode feature_node, RegisterTypeMap &feature_register_types,
5100 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5105 "enum", [log, &feature_register_types,
5106 &owned_register_types](
const XMLNode &enum_node) {
5110 const llvm::StringRef &attr_value) {
5111 if (attr_name ==
"id")
5129 ParseEnumEvalues(enum_node);
5130 if (!enumerators.empty()) {
5132 "ProcessGDBRemote::ParseEnums Found enum type \"{0}\"",
5135 std::make_unique<RegisterTypeEnum>(
id, enumerators);
5136 const RegisterTypeEnum *enum_type_ptr = enum_type.get();
5137 auto [it, inserted] =
5138 feature_register_types.try_emplace(
id, enum_type_ptr);
5140 owned_register_types.push_back(std::move(enum_type));
5141 }
else if (llvm::isa<RegisterTypeEnum>(it->second)) {
5146 owned_register_types.push_back(std::move(enum_type));
5147 it->second = enum_type_ptr;
5151 "ProcessGDBRemote::ParseEnums Ignoring enum type \"{0}\" "
5152 "because another type with that id already exists",
5163static std::vector<RegisterTypeFlags::Field>
5164ParseFlagsFields(XMLNode flags_node,
unsigned size,
5165 const RegisterTypeMap &feature_register_types) {
5167 const unsigned max_start_bit = size * 8 - 1;
5170 std::vector<RegisterTypeFlags::Field> fields;
5172 &feature_register_types](
5175 std::optional<llvm::StringRef> name;
5176 std::optional<unsigned> start;
5177 std::optional<unsigned> end;
5178 std::optional<llvm::StringRef> type;
5181 &log](
const llvm::StringRef &attr_name,
5182 const llvm::StringRef &attr_value) {
5185 if (attr_name ==
"name") {
5188 "ProcessGDBRemote::ParseFlagsFields Found field node name \"{0}\"",
5191 }
else if (attr_name ==
"start") {
5192 unsigned parsed_start = 0;
5193 if (llvm::to_integer(attr_value, parsed_start)) {
5194 if (parsed_start > max_start_bit) {
5196 "ProcessGDBRemote::ParseFlagsFields Invalid start {0} in "
5199 parsed_start, max_start_bit);
5201 start = parsed_start;
5205 "ProcessGDBRemote::ParseFlagsFields Invalid start \"{0}\" in "
5209 }
else if (attr_name ==
"end") {
5210 unsigned parsed_end = 0;
5211 if (llvm::to_integer(attr_value, parsed_end))
5212 if (parsed_end > max_start_bit) {
5214 "ProcessGDBRemote::ParseFlagsFields Invalid end {0} in "
5217 parsed_end, max_start_bit);
5222 "ProcessGDBRemote::ParseFlagsFields Invalid end \"{0}\" in "
5226 }
else if (attr_name ==
"type") {
5231 "ProcessGDBRemote::ParseFlagsFields Ignoring unknown attribute "
5232 "\"{0}\" in field node",
5239 if (name && start && end) {
5243 "ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
5244 "\"{2}\", ignoring",
5245 *start, *end, name->data());
5249 "ProcessGDBRemote::ParseFlagsFields Ignoring field \"{}\" "
5250 "that has size > 64 bits, this is not supported",
5254 const RegisterTypeEnum *enum_type =
nullptr;
5255 if (type && !type->empty()) {
5256 auto found = feature_register_types.find(*type);
5257 if (found != feature_register_types.end()) {
5258 enum_type = llvm::dyn_cast<RegisterTypeEnum>(found->second);
5262 "ProcessGDBRemote::ParseFlagsFields Type \"{0}\" for "
5263 "field \"{1}\" is not an enum, ignoring",
5264 type->data(), name->data());
5269 uint64_t max_value =
5272 if (enumerator.m_value > max_value) {
5273 enum_type =
nullptr;
5276 "ProcessGDBRemote::ParseFlagsFields In enum \"{0}\" "
5277 "evalue \"{1}\" with value {2} exceeds the maximum "
5278 "value of field \"{3}\" ({4}), ignoring enum",
5279 type->data(), enumerator.m_name, enumerator.m_value,
5280 name->data(), max_value);
5287 "ProcessGDBRemote::ParseFlagsFields Could not find type "
5289 "for field \"{1}\", ignoring",
5290 type->data(), name->data());
5295 RegisterTypeFlags::Field(name->str(), *start, *end, enum_type));
5306 XMLNode feature_node, RegisterTypeMap &feature_register_types,
5307 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5312 [&log, &feature_register_types,
5313 &owned_register_types](
const XMLNode &flags_node) ->
bool {
5314 LLDB_LOG(log,
"ProcessGDBRemote::ParseFlags Found flags node \"{0}\"",
5317 std::optional<llvm::StringRef>
id;
5318 std::optional<unsigned> size;
5320 [&
id, &size, &log](
const llvm::StringRef &name,
5321 const llvm::StringRef &value) {
5324 }
else if (name ==
"size") {
5325 unsigned parsed_size = 0;
5326 if (llvm::to_integer(value, parsed_size))
5330 "ProcessGDBRemote::ParseFlags Invalid size \"{0}\" "
5336 "ProcessGDBRemote::ParseFlags Ignoring unknown "
5337 "attribute \"{0}\" in flags node",
5345 std::vector<RegisterTypeFlags::Field> fields =
5346 ParseFlagsFields(flags_node, *size, feature_register_types);
5347 if (fields.size()) {
5349 std::sort(fields.rbegin(), fields.rend());
5350 std::vector<RegisterTypeFlags::Field>::const_iterator overlap =
5351 std::adjacent_find(fields.begin(), fields.end(),
5352 [](
const RegisterTypeFlags::Field &lhs,
5353 const RegisterTypeFlags::Field &rhs) {
5354 return lhs.Overlaps(rhs);
5358 if (overlap == fields.end()) {
5359 if (feature_register_types.contains(*
id)) {
5364 "ProcessGDBRemote::ParseFlags Definition of flags \"{0}\" "
5365 "conflicts with an existing type, ignoring this "
5369 auto flags_type = std::make_unique<RegisterTypeFlags>(
5370 id->str(), *size, std::move(fields));
5371 feature_register_types.try_emplace(*
id, flags_type.get());
5372 owned_register_types.push_back(std::move(flags_type));
5376 std::vector<RegisterTypeFlags::Field>::const_iterator next =
5380 "ProcessGDBRemote::ParseFlags Ignoring flags because fields "
5381 "{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) "
5383 overlap->GetName().c_str(), overlap->GetStart(),
5384 overlap->GetEnd(), next->GetName().c_str(), next->GetStart(),
5390 "ProcessGDBRemote::ParseFlags Ignoring definition of flags "
5391 "\"{0}\" because it contains no fields.",
5400static const RegisterTypeBuiltin *
5401ResolveGDBBuiltinType(llvm::StringRef type_name) {
5405 static const RegisterTypeBuiltin bool_type(
"bool",
eEncodingUint,
5407 static const RegisterTypeBuiltin int8_type(
"int8",
eEncodingSint,
5409 static const RegisterTypeBuiltin int16_type(
"int16",
eEncodingSint,
5411 static const RegisterTypeBuiltin int32_type(
"int32",
eEncodingSint,
5413 static const RegisterTypeBuiltin int64_type(
"int64",
eEncodingSint,
5415 static const RegisterTypeBuiltin int128_type(
"int128",
eEncodingSint,
5417 static const RegisterTypeBuiltin uint8_type(
"uint8",
eEncodingUint,
5419 static const RegisterTypeBuiltin uint16_type(
"uint16",
eEncodingUint,
5421 static const RegisterTypeBuiltin uint32_type(
"uint32",
eEncodingUint,
5423 static const RegisterTypeBuiltin uint64_type(
"uint64",
eEncodingUint,
5425 static const RegisterTypeBuiltin uint128_type(
"uint128",
eEncodingUint,
5427 static const RegisterTypeBuiltin code_ptr_type(
5429 static const RegisterTypeBuiltin data_ptr_type(
5431 static const RegisterTypeBuiltin ieee_half_type(
"ieee_half",
eEncodingIEEE754,
5433 static const RegisterTypeBuiltin ieee_single_type(
5435 static const RegisterTypeBuiltin ieee_double_type(
5437 static const RegisterTypeBuiltin i387_ext_type(
"i387_ext",
eEncodingIEEE754,
5439 static const RegisterTypeBuiltin bfloat16_type(
"bfloat16",
eEncodingIEEE754,
5442 return llvm::StringSwitch<const RegisterTypeBuiltin *>(type_name)
5443 .Case(
"bool", &bool_type)
5444 .Case(
"int8", &int8_type)
5445 .Case(
"int16", &int16_type)
5446 .Case(
"int32", &int32_type)
5447 .Case(
"int64", &int64_type)
5448 .Case(
"int128", &int128_type)
5449 .Case(
"uint8", &uint8_type)
5450 .Case(
"uint16", &uint16_type)
5451 .Case(
"uint32", &uint32_type)
5452 .Case(
"uint64", &uint64_type)
5453 .Case(
"uint128", &uint128_type)
5454 .Case(
"code_ptr", &code_ptr_type)
5455 .Case(
"data_ptr", &data_ptr_type)
5456 .Case(
"ieee_half", &ieee_half_type)
5457 .Case(
"ieee_single", &ieee_single_type)
5458 .Case(
"ieee_double", &ieee_double_type)
5459 .Case(
"i387_ext", &i387_ext_type)
5460 .Case(
"bfloat16", &bfloat16_type)
5464static const RegisterType *
5465ResolveGDBType(llvm::StringRef type_name,
5466 const RegisterTypeMap &feature_register_types) {
5467 auto type_it = feature_register_types.find(type_name);
5468 if (type_it != feature_register_types.end())
5469 return type_it->second;
5470 return ResolveGDBBuiltinType(type_name);
5474ParseVector(
const XMLNode &vector_node, RegisterTypeMap &feature_register_types,
5475 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5477 std::optional<llvm::StringRef>
id;
5478 std::optional<llvm::StringRef> element_type_name;
5479 std::optional<uint32_t> count;
5482 [&
id, &element_type_name, &count, log](llvm::StringRef name,
5483 llvm::StringRef value) {
5486 }
else if (name ==
"type") {
5487 element_type_name = value;
5488 }
else if (name ==
"count") {
5489 uint32_t parsed_count = 0;
5490 if (llvm::to_integer(value, parsed_count))
5491 count = parsed_count;
5493 LLDB_LOG(log,
"ProcessGDBRemote::ParseVector Invalid count \"{0}\"",
5497 "ProcessGDBRemote::ParseVector Ignoring unknown attribute "
5507 if (!
id ||
id->empty() || !element_type_name || element_type_name->empty() ||
5508 !count || *count == 0 || *count > max_vector_count) {
5509 LLDB_LOG(log,
"ProcessGDBRemote::ParseVector Ignoring vector with invalid "
5510 "id, type, or count");
5514 if (feature_register_types.contains(*
id)) {
5516 "ProcessGDBRemote::ParseVector Ignoring duplicate type \"{0}\"",
5521 const RegisterType *element_type =
5522 ResolveGDBType(*element_type_name, feature_register_types);
5523 if (!element_type) {
5525 "ProcessGDBRemote::ParseVector Could not resolve element type "
5526 "\"{0}\" for vector \"{1}\"",
5527 *element_type_name, *
id);
5531 if (!llvm::isa<RegisterTypeBuiltin, RegisterTypeVector, RegisterTypeUnion>(
5534 "ProcessGDBRemote::ParseVector Found element type \"{0}\" for "
5535 "vector \"{1}\", but it is not a builtin, vector, or union "
5537 *element_type_name, *
id);
5541 std::optional<uint64_t> element_size = element_type->
GetByteSize();
5545 "ProcessGDBRemote::ParseVector Size of vector \"{0}\" is too "
5552 std::make_unique<RegisterTypeVector>(
id->str(), element_type, *count);
5553 feature_register_types.try_emplace(*
id, vector_type.get());
5554 owned_register_types.push_back(std::move(vector_type));
5557static std::vector<RegisterTypeUnion::Field>
5558ParseUnionFields(
const XMLNode &union_node, llvm::StringRef union_id,
5559 const RegisterTypeMap &feature_register_types) {
5561 std::vector<RegisterTypeUnion::Field> fields;
5562 bool invalid_field =
false;
5565 "field", [&fields, &invalid_field, log, &feature_register_types,
5566 union_id](
const XMLNode &field_node) {
5567 std::optional<llvm::StringRef> name;
5568 std::optional<llvm::StringRef> type_name;
5571 [&name, &type_name, log, union_id](llvm::StringRef attribute,
5572 llvm::StringRef value) {
5573 if (attribute ==
"name")
5575 else if (attribute ==
"type")
5579 "ProcessGDBRemote::ParseUnionFields Ignoring unknown "
5580 "attribute \"{0}\" in a field of union \"{1}\"",
5581 attribute, union_id);
5585 if (!name || name->empty() || !type_name || type_name->empty()) {
5587 "ProcessGDBRemote::ParseUnionFields Union \"{0}\" has a "
5588 "field missing a non-empty name or type",
5590 invalid_field =
true;
5594 const RegisterType *field_type =
5595 ResolveGDBType(*type_name, feature_register_types);
5598 "ProcessGDBRemote::ParseUnionFields Could not resolve type "
5599 "\"{0}\" for field \"{1}\" of union \"{2}\"",
5600 *type_name, *name, union_id);
5601 invalid_field =
true;
5605 if (!llvm::isa<RegisterTypeBuiltin, RegisterTypeVector,
5606 RegisterTypeUnion>(field_type)) {
5608 "ProcessGDBRemote::ParseUnionFields Found type \"{0}\" "
5609 "for field \"{1}\", but it is not a builtin, vector, or "
5610 "union type. Union \"{2}\" will be ignored.",
5611 *type_name, *name, union_id);
5612 invalid_field =
true;
5616 fields.emplace_back(name->str(), field_type);
5622 if (invalid_field) {
5624 "ProcessGDBRemote::ParseUnionFields Ignoring union \"{0}\" "
5625 "because it contains an invalid field",
5628 }
else if (fields.empty()) {
5630 "ProcessGDBRemote::ParseUnionFields Ignoring union \"{0}\" "
5631 "because it has no fields",
5638ParseUnion(
const XMLNode &union_node, RegisterTypeMap &feature_register_types,
5639 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5641 std::optional<llvm::StringRef>
id;
5644 [&
id, log](llvm::StringRef name, llvm::StringRef value) {
5649 "ProcessGDBRemote::ParseUnion Ignoring unknown attribute "
5655 if (!
id ||
id->empty()) {
5656 LLDB_LOG(log,
"ProcessGDBRemote::ParseUnion Ignoring union without an id");
5660 if (feature_register_types.contains(*
id)) {
5662 "ProcessGDBRemote::ParseUnion Ignoring duplicate type \"{0}\"",
5667 std::vector<RegisterTypeUnion::Field> fields =
5668 ParseUnionFields(union_node, *
id, feature_register_types);
5673 std::make_unique<RegisterTypeUnion>(
id->str(), std::move(fields));
5674 feature_register_types.try_emplace(*
id, union_type.get());
5675 owned_register_types.push_back(std::move(union_type));
5678static void ParseCompositeTypes(
5679 XMLNode feature_node, RegisterTypeMap &feature_register_types,
5680 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5682 [&feature_register_types,
5683 &owned_register_types](
const XMLNode &type_node) {
5684 if (type_node.
NameIs(
"vector"))
5685 ParseVector(type_node, feature_register_types, owned_register_types);
5686 else if (type_node.
NameIs(
"union"))
5687 ParseUnion(type_node, feature_register_types, owned_register_types);
5693 XMLNode feature_node, GdbServerTargetInfo &target_info,
5694 std::vector<DynamicRegisterInfo::Register> ®isters,
5695 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5700 RegisterTypeMap feature_register_types;
5703 ParseEnums(feature_node, feature_register_types, owned_register_types);
5704 for (
const auto ®ister_type : feature_register_types)
5705 if (
const auto *enum_type =
5706 llvm::dyn_cast<RegisterTypeEnum>(register_type.second))
5709 ParseFlags(feature_node, feature_register_types, owned_register_types);
5710 for (
const auto ®ister_type : feature_register_types)
5711 if (
const auto *flags_type =
5712 llvm::dyn_cast<RegisterTypeFlags>(register_type.second))
5713 flags_type->DumpToLog(log);
5718 ParseCompositeTypes(feature_node, feature_register_types,
5719 owned_register_types);
5720 for (
const auto ®ister_type : feature_register_types)
5721 if (
const auto *vector_type =
5722 llvm::dyn_cast<RegisterTypeVector>(register_type.second))
5723 vector_type->DumpToLog(log);
5724 for (
const auto ®ister_type : feature_register_types)
5725 if (
const auto *union_type =
5726 llvm::dyn_cast<RegisterTypeUnion>(register_type.second))
5727 union_type->DumpToLog(log);
5731 [&target_info, ®isters, &feature_register_types,
5732 log](
const XMLNode ®_node) ->
bool {
5733 std::string gdb_group;
5734 std::string gdb_type;
5735 DynamicRegisterInfo::Register reg_info;
5736 bool encoding_set =
false;
5737 bool format_set =
false;
5741 &encoding_set, &format_set, ®_info,
5742 log](
const llvm::StringRef &name,
5743 const llvm::StringRef &value) ->
bool {
5744 if (name ==
"name") {
5746 }
else if (name ==
"bitsize") {
5747 if (llvm::to_integer(value, reg_info.
byte_size))
5749 llvm::divideCeil(reg_info.
byte_size, CHAR_BIT);
5750 }
else if (name ==
"type") {
5751 gdb_type = value.str();
5752 }
else if (name ==
"group") {
5753 gdb_group = value.str();
5754 }
else if (name ==
"regnum") {
5756 }
else if (name ==
"offset") {
5758 }
else if (name ==
"altname") {
5760 }
else if (name ==
"encoding") {
5761 encoding_set =
true;
5763 }
else if (name ==
"format") {
5769 llvm::StringSwitch<lldb::Format>(value)
5780 }
else if (name ==
"group_id") {
5782 llvm::to_integer(value, set_id);
5783 RegisterSetMap::const_iterator pos =
5784 target_info.reg_set_map.find(set_id);
5785 if (pos != target_info.reg_set_map.end())
5786 reg_info.
set_name = pos->second.name;
5787 }
else if (name ==
"gcc_regnum" || name ==
"ehframe_regnum") {
5789 }
else if (name ==
"dwarf_regnum") {
5791 }
else if (name ==
"generic") {
5793 }
else if (name ==
"value_regnums") {
5796 }
else if (name ==
"invalidate_regnums") {
5801 "ProcessGDBRemote::ParseRegisters unhandled reg "
5802 "attribute %s = %s",
5803 name.data(), value.data());
5808 if (!gdb_type.empty()) {
5810 auto it = feature_register_types.find(gdb_type);
5811 if (it != feature_register_types.end()) {
5812 if (
const auto *vector_type =
5813 llvm::dyn_cast<RegisterTypeVector>(it->second)) {
5814 std::optional<uint64_t> type_size = vector_type->GetByteSize();
5817 "ProcessGDBRemote::ParseRegisters Register {0} is "
5818 "too large for vector type {1}",
5819 reg_info.
name, vector_type->GetID());
5820 }
else if (!vector_type->IsByteSizeCompatible(
5824 "ProcessGDBRemote::ParseRegisters Size of register "
5825 "{0} is incompatible with vector type {1}",
5826 reg_info.
name, vector_type->GetID());
5830 "ProcessGDBRemote::ParseRegisters Size of register type "
5831 "{0} ({1} bytes) for register {2} does not match the "
5832 "register size ({3} bytes). Ignoring this type.",
5833 vector_type->GetID(), *type_size, reg_info.
name,
5838 if (!encoding_set) {
5840 encoding_set =
true;
5847 }
else if (
const auto *union_type =
5848 llvm::dyn_cast<RegisterTypeUnion>(it->second)) {
5851 "ProcessGDBRemote::ParseRegisters Register {0} is "
5852 "too large for union type {1}",
5853 reg_info.
name, union_type->GetID());
5854 }
else if (!union_type->IsByteSizeCompatible(
5857 "ProcessGDBRemote::ParseRegisters Size of register "
5858 "{0} is incompatible with union type {1}",
5859 reg_info.
name, union_type->GetID());
5862 if (!encoding_set) {
5864 encoding_set =
true;
5871 }
else if (
const auto *flags_type =
5872 llvm::dyn_cast<RegisterTypeFlags>(it->second)) {
5873 if (reg_info.
byte_size == flags_type->GetSize())
5878 "ProcessGDBRemote::ParseRegisters Size of register flags "
5879 "{0} ({1} bytes) for register {2} does not match the "
5880 "register size ({3} bytes). Ignoring this set of flags.",
5881 flags_type->GetID().c_str(), flags_type->GetSize(),
5889 if (!gdb_type.empty() && !(encoding_set || format_set)) {
5890 if (llvm::StringRef(gdb_type).starts_with(
"int")) {
5893 }
else if (gdb_type ==
"data_ptr" || gdb_type ==
"code_ptr") {
5896 }
else if (gdb_type ==
"float" || gdb_type ==
"ieee_single" ||
5897 gdb_type ==
"ieee_double") {
5900 }
else if (gdb_type ==
"aarch64v" ||
5901 llvm::StringRef(gdb_type).starts_with(
"vec") ||
5902 gdb_type ==
"i387_ext" || gdb_type ==
"uint128" ||
5915 "ProcessGDBRemote::ParseRegisters Could not determine lldb"
5916 "format and encoding for gdb type %s",
5926 if (!gdb_group.empty()) {
5937 "ProcessGDBRemote::{0} Skipping zero bitsize register {1}",
5938 __FUNCTION__, reg_info.
name);
5940 registers.push_back(reg_info);
5955 ArchSpec &arch_to_use, std::string xml_filename,
5956 std::vector<DynamicRegisterInfo::Register> ®isters) {
5958 llvm::Expected<std::string> raw =
m_gdb_comm.ReadExtFeature(
"features", xml_filename);
5959 if (errorToBool(raw.takeError()))
5964 if (xml_document.
ParseMemory(raw->c_str(), raw->size(),
5965 xml_filename.c_str())) {
5966 GdbServerTargetInfo target_info;
5967 std::vector<XMLNode> feature_nodes;
5973 const XMLNode &node) ->
bool {
5974 llvm::StringRef name = node.
GetName();
5975 if (name ==
"architecture") {
5977 }
else if (name ==
"osabi") {
5979 }
else if (name ==
"xi:include" || name ==
"include") {
5982 target_info.includes.push_back(href);
5983 }
else if (name ==
"feature") {
5984 feature_nodes.push_back(node);
5985 }
else if (name ==
"groups") {
5987 "group", [&target_info](
const XMLNode &node) ->
bool {
5989 RegisterSetInfo set_info;
5992 [&set_id, &set_info](
const llvm::StringRef &name,
5993 const llvm::StringRef &value) ->
bool {
5996 llvm::to_integer(value, set_id);
6003 target_info.reg_set_map[set_id] = set_info;
6016 feature_nodes.push_back(feature_node);
6018 const XMLNode &node) ->
bool {
6019 llvm::StringRef name = node.
GetName();
6020 if (name ==
"xi:include" || name ==
"include") {
6023 target_info.includes.push_back(href);
6037 if (!arch_to_use.
IsValid() && !target_info.arch.empty()) {
6039 arch_to_use.
SetTriple(llvm::StringSwitch<std::string>(target_info.arch)
6040 .Case(
"i386:x86-64",
"x86_64")
6041 .Case(
"riscv:rv64",
"riscv64")
6042 .Case(
"riscv:rv32",
"riscv32")
6043 .Default(target_info.arch) +
6051 for (
auto &feature_node : feature_nodes) {
6055 for (
const auto &include : target_info.includes) {
6067 std::vector<DynamicRegisterInfo::Register> ®isters,
6069 std::map<uint32_t, uint32_t> remote_to_local_map;
6070 uint32_t remote_regnum = 0;
6071 for (
auto it : llvm::enumerate(registers)) {
6079 remote_to_local_map[remote_reg_info.
regnum_remote] = it.index();
6085 auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) {
6086 auto lldb_regit = remote_to_local_map.find(process_regnum);
6087 return lldb_regit != remote_to_local_map.end() ? lldb_regit->second
6091 llvm::transform(remote_reg_info.value_regs,
6092 remote_reg_info.value_regs.begin(), proc_to_lldb);
6093 llvm::transform(remote_reg_info.invalidate_regs,
6094 remote_reg_info.invalidate_regs.begin(), proc_to_lldb);
6101 abi_sp->AugmentRegisterInfo(registers);
6111 if (!
m_gdb_comm.GetQXferFeaturesReadSupported())
6112 return llvm::createStringError(
6113 llvm::inconvertibleErrorCode(),
6114 "the debug server does not support \"qXfer:features:read\"");
6117 return llvm::createStringError(
6118 llvm::inconvertibleErrorCode(),
6119 "the debug server supports \"qXfer:features:read\", but LLDB does not "
6120 "have XML parsing enabled (check LLLDB_ENABLE_LIBXML2)");
6122 std::vector<DynamicRegisterInfo::Register> registers;
6130 ? llvm::ErrorSuccess()
6131 : llvm::createStringError(
6132 llvm::inconvertibleErrorCode(),
6133 "the debug server did not describe any registers");
6139 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6140 "XML parsing not available");
6143 LLDB_LOGF(log,
"ProcessGDBRemote::%s", __FUNCTION__);
6152 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries-svr4",
"");
6154 return raw.takeError();
6157 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
6160 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
6161 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6162 "Error reading noname.xml");
6166 return llvm::createStringError(
6167 llvm::inconvertibleErrorCode(),
6168 "Error finding library-list-svr4 xml element");
6173 if (!main_lm.empty())
6177 "library", [log, &list](
const XMLNode &library) ->
bool {
6182 [&module](
const llvm::StringRef &name,
6183 const llvm::StringRef &value) ->
bool {
6186 module.set_name(value.str());
6187 else if (name ==
"lm") {
6189 llvm::to_integer(value, uint_value);
6190 module.set_link_map(uint_value);
6191 }
else if (name ==
"l_addr") {
6194 llvm::to_integer(value, uint_value);
6195 module.set_base(uint_value);
6198 module.set_base_is_offset(true);
6199 }
else if (name ==
"l_ld") {
6201 llvm::to_integer(value, uint_value);
6202 module.set_dynamic(uint_value);
6211 bool base_is_offset;
6213 module.get_name(name);
6214 module.get_link_map(lm);
6215 module.get_base(base);
6216 module.get_base_is_offset(base_is_offset);
6217 module.get_dynamic(ld);
6220 "found (link_map:0x%08" PRIx64
", base:0x%08" PRIx64
6221 "[%s], ld:0x%08" PRIx64
", name:'%s')",
6222 lm, base, (base_is_offset ?
"offset" :
"absolute"), ld,
6231 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
6232 (
int)list.
m_list.size());
6236 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries",
"");
6239 return raw.takeError();
6241 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
6244 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
6245 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6246 "Error reading noname.xml");
6250 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6251 "Error finding library-list xml element");
6255 "library", [log, &list](
const XMLNode &library) ->
bool {
6259 module.set_name(name);
6268 llvm::to_integer(address, address_value);
6269 module.set_base(address_value);
6271 module.set_base_is_offset(false);
6276 bool base_is_offset;
6277 module.get_name(name);
6278 module.get_base(base);
6279 module.get_base_is_offset(base_is_offset);
6281 LLDB_LOGF(log,
"found (base:0x%08" PRIx64
"[%s], name:'%s')", base,
6282 (base_is_offset ?
"offset" :
"absolute"), name.c_str());
6290 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
6291 (
int)list.
m_list.size());
6294 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6295 "Remote libraries not supported");
6302 bool value_is_offset) {
6317 return module_list.takeError();
6323 std::string mod_name;
6326 bool mod_base_is_offset;
6329 valid &= modInfo.
get_name(mod_name);
6330 valid &= modInfo.
get_base(mod_base);
6343 if (module_sp.get())
6344 new_modules.
Append(module_sp);
6347 if (new_modules.
GetSize() > 0) {
6352 for (
size_t i = 0; i < loaded_modules.
GetSize(); ++i) {
6356 for (
size_t j = 0; j < new_modules.
GetSize(); ++j) {
6365 removed_modules.
Append(loaded_module);
6369 loaded_modules.
Remove(removed_modules);
6370 m_process->GetTarget().ModulesDidUnload(removed_modules,
false);
6389 m_process->GetTarget().ModulesDidLoad(new_modules);
6392 return llvm::ErrorSuccess();
6401 std::string file_path = file.
GetPath(
false);
6402 if (file_path.empty())
6423 "Fetching file load address from remote server returned an error");
6433 "Unknown error happened during sending the load address packet");
6454 std::string input = data.str();
6461 size_t found, pos = 0, len = input.length();
6462 while ((found = input.find(
end_delimiter, pos)) != std::string::npos) {
6464 input.substr(pos, found).c_str());
6465 std::string profile_data =
6480 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
6482 llvm::raw_string_ostream output_stream(output);
6483 llvm::StringRef name, value;
6487 if (name.compare(
"thread_used_id") == 0) {
6489 uint64_t thread_id = threadIDHexExtractor.
GetHexMaxU64(
false, 0);
6491 bool has_used_usec =
false;
6492 uint32_t curr_used_usec = 0;
6493 llvm::StringRef usec_name, usec_value;
6494 uint32_t input_file_pos = profileDataExtractor.
GetFilePos();
6496 if (usec_name ==
"thread_used_usec") {
6497 has_used_usec =
true;
6498 usec_value.getAsInteger(
BASE_10, curr_used_usec);
6502 profileDataExtractor.
SetFilePos(input_file_pos);
6506 if (has_used_usec) {
6507 uint32_t prev_used_usec = 0;
6508 std::map<uint64_t, uint32_t>::iterator iterator =
6511 prev_used_usec = iterator->second;
6513 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
6515 bool good_first_time =
6516 (prev_used_usec == 0) && (real_used_usec > 250000);
6517 bool good_subsequent_time =
6518 (prev_used_usec > 0) &&
6521 if (good_first_time || good_subsequent_time) {
6525 output_stream << name <<
":";
6527 output_stream << index_id <<
";";
6529 output_stream << usec_name <<
":" << usec_value <<
";";
6532 llvm::StringRef local_name, local_value;
6538 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
6541 output_stream << name <<
":" << value <<
";";
6544 output_stream << name <<
":" << value <<
";";
6579 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6580 "qSaveCore returned an error");
6585 for (
auto x : llvm::split(response.
GetStringRef(),
';')) {
6586 if (x.consume_front(
"core-path:"))
6592 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6593 "qSaveCore returned no core path");
6596 FileSpec remote_core{llvm::StringRef(path)};
6602 platform.
Unlink(remote_core);
6604 return error.ToError();
6610 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6611 "Unable to send qSaveCore");
6623 "GDBRemoteCommunicationClientBase::%s() received $J packet "
6624 "but was not a StructuredData packet: packet starts with "
6636 json_sp->Dump(json_str,
true);
6639 "ProcessGDBRemote::%s() "
6640 "received Async StructuredData packet: %s",
6641 __FUNCTION__, json_str.
GetData());
6644 "ProcessGDBRemote::%s"
6645 "() received StructuredData packet:"
6655 if (structured_data_sp)
6663 "Tests packet speeds of various sizes to determine "
6664 "the performance characteristics of the GDB remote "
6669 "The number of packets to send of each varying size "
6670 "(default is 1000).",
6673 "The maximum number of bytes to send in a packet. Sizes "
6674 "increase in powers of 2 while the size is less than or "
6675 "equal to this option value. (default 1024).",
6678 "The maximum number of bytes to receive in a packet. Sizes "
6679 "increase in powers of 2 while the size is less than or "
6680 "equal to this option value. (default 1024).",
6683 "Print the output as JSON data for easy parsing.", false, true) {
6703 if (!output_stream_sp)
6704 output_stream_sp =
m_interpreter.GetDebugger().GetAsyncOutputStream();
6707 const uint32_t num_packets =
6709 const uint64_t max_send =
m_max_send.GetOptionValue().GetCurrentValue();
6710 const uint64_t max_recv =
m_max_recv.GetOptionValue().GetCurrentValue();
6711 const bool json =
m_json.GetOptionValue().GetCurrentValue();
6712 const uint64_t k_recv_amount =
6715 num_packets, max_send, max_recv, k_recv_amount, json,
6740 "Dumps the packet history buffer. ", nullptr) {}
6761 interpreter,
"process plugin packet xfer-size",
6762 "Maximum size that lldb will try to read/write one one chunk.",
6773 "amount to be transferred when "
6784 uint64_t user_specified_max = strtoul(packet_size,
nullptr, 10);
6785 if (errno == 0 && user_specified_max != 0) {
6800 "Send a custom packet through the GDB remote "
6801 "protocol and print the answer. "
6802 "The packet header and footer will automatically "
6803 "be added to the packet prior to sending and "
6804 "stripped from the result.",
6815 "'%s' takes a one or more packet content arguments",
6823 for (
size_t i = 0; i < argc; ++i) {
6830 output_strm.
Printf(
" packet: %s\n", packet_cstr);
6831 std::string response_str = std::string(response.
GetStringRef());
6833 if (strstr(packet_cstr,
"qGetProfileData") !=
nullptr) {
6837 if (response_str.empty())
6838 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6851 "Send a qRcmd packet through the GDB remote protocol "
6852 "and print the response. "
6853 "The argument passed to this command will be hex "
6854 "encoded into a valid 'qRcmd' packet, sent and the "
6855 "response will be printed.") {}
6861 if (command.empty()) {
6878 [&output_strm](llvm::StringRef output) { output_strm << output; });
6881 const std::string &response_str = std::string(response.
GetStringRef());
6883 if (response_str.empty())
6884 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6896 "Commands that deal with GDB remote packets.",
6925 interpreter,
"process plugin",
6926 "Commands for operating on a ProcessGDBRemote process.",
6927 "process plugin <subcommand> [<subcommand-options>]") {
6938 m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(
6939 GetTarget().GetDebugger().GetCommandInterpreter());
6944 bool enable,
bool is_expression_fork) {
6950 if (!enable && is_expression_fork) {
6951 if (
auto entry =
GetTarget().GetEntryPointAddress())
6952 entry_addr = entry->GetOpcodeLoadAddress(&
GetTarget());
6966 "DidForkSwitchSoftwareBreakpoints: retaining expression-"
6967 "return trap at {0:x} in forked child",
6991 addr_t addr = wp_res_sp->GetLoadAddress();
6992 size_t size = wp_res_sp->GetByteSize();
6994 m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,
7000 bool is_expression_fork) {
7009 bool overrode_follow_mode =
false;
7012 if (is_expression_fork) {
7013 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
7014 "to parent during expression evaluation");
7016 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
7017 "to parent during expression evaluation. Child process "
7018 "{0} is available for manual attachment.",
7022 overrode_follow_mode =
true;
7033 switch (follow_fork_mode) {
7035 follow_pid = parent_pid;
7036 follow_tid = parent_tid;
7037 detach_pid = child_pid;
7038 detach_tid = child_tid;
7041 follow_pid = child_pid;
7042 follow_tid = child_tid;
7043 detach_pid = parent_pid;
7044 detach_tid = parent_tid;
7049 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
7050 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to set pid/tid");
7064 if (!
m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) ||
7065 !
m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) {
7066 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to reset pid/tid");
7070 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
7073 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
7075 if (
error.Fail() && keep_stopped) {
7076 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach-and-stay-stopped not "
7077 "supported, falling back to normal detach");
7078 keep_stopped =
false;
7082 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach packet send failed: {0}",
7083 error.AsCString() ?
error.AsCString() :
"<unknown error>");
7089 if (overrode_follow_mode && !is_expression_fork) {
7093 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
7094 "'parent' because an expression is being evaluated.\n"
7095 "Child process %" PRIu64
7096 " has been detached%s.\n"
7097 "You can attach to it with: process attach -p %" PRIu64
7100 keep_stopped ?
" and stopped" :
" (running)",
7116 bool is_expression_fork) {
7121 "ProcessGDBRemote::DidVFork() called for child_pid: {0}, child_tid {1}",
7122 child_pid, child_tid);
7128 bool overrode_follow_mode =
false;
7131 if (is_expression_fork) {
7132 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
7133 "to parent during expression evaluation");
7135 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
7136 "to parent during expression evaluation. Child process "
7137 "{0} is available for manual attachment.",
7141 overrode_follow_mode =
true;
7151 switch (follow_fork_mode) {
7153 detach_pid = child_pid;
7154 detach_tid = child_tid;
7157 detach_pid =
m_gdb_comm.GetCurrentProcessID();
7163 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
7164 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to set pid/tid");
7172 if (!
m_gdb_comm.SetCurrentThread(child_tid, child_pid) ||
7173 !
m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) {
7174 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to reset pid/tid");
7180 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
7181 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
7183 if (
error.Fail() && keep_stopped) {
7184 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() detach-and-stay-stopped not "
7185 "supported, falling back to normal detach");
7186 keep_stopped =
false;
7191 "ProcessGDBRemote::DidVFork() detach packet send failed: {0}",
7192 error.AsCString() ?
error.AsCString() :
"<unknown error>");
7196 if (overrode_follow_mode && !is_expression_fork) {
7200 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
7201 "'parent' because an expression is being evaluated.\n"
7202 "Child process %" PRIu64
7203 " has been detached%s.\n"
7204 "You can attach to it with: process attach -p %" PRIu64
7207 keep_stopped ?
" and stopped" :
" (running)",
7240 llvm::Error joined = llvm::Error::success();
7241 for (
auto &[site, action] : site_to_action) {
7245 joined = llvm::joinErrors(std::move(joined), std::move(
error));
7253static llvm::SmallVector<std::optional<uint8_t>>
7255 llvm::SmallVector<std::optional<uint8_t>> results;
7259 parsed ? parsed->GetAsDictionary() :
nullptr;
7267 llvm::StringRef token;
7268 if (
auto *
string = object->GetAsString())
7269 token =
string->GetValue();
7270 if (token ==
"OK") {
7271 results.push_back(std::nullopt);
7274 if (token.size() != 3 || !token.starts_with(
"E")) {
7275 results.push_back(uint8_t(0xff));
7278 uint8_t error_code = 0;
7279 if (token.drop_front(1).getAsInteger(
BASE_16, error_code))
7280 results.push_back(0xff);
7282 results.push_back(error_code);
7291static std::optional<GDBStoppointType>
7300 return std::nullopt;
7309 return std::nullopt;
7311 llvm_unreachable(
"unhandled BreakpointSite type");
7315struct BreakpointPacketInfo {
7316 BreakpointSite &site;
7317 size_t trap_opcode_size;
7322std::string to_string(
const BreakpointPacketInfo &info) {
7323 char packet = info.is_enable ?
'Z' :
'z';
7324 return llvm::formatv(
"{0}{1},{2:x-},{3:x-}", packet,
7326 info.trap_opcode_size)
7333 if (site_to_action.empty())
7334 return llvm::Error::success();
7335 if (!
m_gdb_comm.GetMultiBreakpointSupported())
7340 std::vector<BreakpointPacketInfo> breakpoint_infos;
7341 for (
auto [site, action] : site_to_action) {
7343 std::optional<GDBStoppointType> type =
7347 LLDB_LOG(log,
"MultiBreakpoint: site {0} at {1:x} can't be batched",
7348 site->GetID(), site->GetLoadAddress());
7352 breakpoint_infos.push_back(
7357 stream <<
"jMultiBreakpoint:";
7359 auto args_array = std::make_shared<StructuredData::Array>();
7360 for (
auto &bp_info : breakpoint_infos)
7361 args_array->AddStringItem(to_string(bp_info));
7364 packet_dict.
AddItem(
"breakpoint_requests", args_array);
7365 packet_dict.
Dump(stream,
false);
7369 llvm::Expected<StringExtractorGDBRemote> response =
7374 LLDB_LOG_ERROR(log, response.takeError(),
"jMultiBreakpoint failed: {0}");
7378 llvm::SmallVector<std::optional<uint8_t>> results =
7382 if (results.size() != breakpoint_infos.size())
7383 return llvm::createStringErrorV(
7384 "MultiBreakpoint response count mismatch (expected {0}, got {1})",
7385 site_to_action.size(), results.size());
7387 llvm::Error joined = llvm::Error::success();
7388 for (
auto [error_code, bp_info] :
7389 llvm::zip_equal(results, breakpoint_infos)) {
7392 auto error = llvm::createStringErrorV(
7393 "MultiBreakpoint: site {0} at {1:x} failed with E{2}",
7394 bp_info.site.GetID(), bp_info.site.GetLoadAddress(), error_code);
7395 joined = llvm::joinErrors(std::move(joined), std::move(
error));
7399 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.
void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
static ModuleListProperties & GetGlobalModuleListProperties()
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
size_t GetSize() const
Gets the size of the module list.
void ForEach(std::function< IterationAction(const lldb::ModuleSP &module_sp)> const &callback) const
Applies 'callback' to each module in this ModuleList.
void Dump(Stream &strm) const
A class that describes an executable image and its associated object and symbol files.
virtual ObjectFile * GetObjectFile()
Get the object file representation for the current architecture.
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
A plug-in interface definition class for object file parsers.
@ eTypeExecutable
A normal executable.
@ eTypeDebugInfo
An object file that contains only debug information.
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
@ eTypeObjectFile
An intermediate object file.
@ eTypeDynamicLinker
The platform's dynamic linker executable.
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
@ eTypeSharedLibrary
A shared library that can be used during execution.
@ eTypeJIT
JIT code that has symbols, sections and possibly debug info.
A command line option parsing protocol class.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool CreateSettingForProcessPlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, llvm::StringRef description, bool is_global_property)
static lldb::OptionValuePropertiesSP GetSettingForProcessPlugin(Debugger &debugger, llvm::StringRef setting_name)
static bool UnregisterPlugin(ABICreateInstance create_callback)
An address in a process, qualified by an address space.
lldb::addr_t GetValue() const
std::optional< lldb::tid_t > GetThreadID() const
lldb::addr_space_t GetAddressSpace() const
bool GetIgnoreExisting() const
bool GetDetachOnError() const
bool GetWaitForLaunch() const
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
lldb::pid_t GetProcessID() const
FileSpec & GetExecutableFile()
uint32_t GetUserID() const
Environment & GetEnvironment()
void SetUserID(uint32_t uid)
const char * GetLaunchEventData() const
const FileAction * GetFileActionForFD(int fd) const
void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback)
void SetLaunchInSeparateProcessGroup(bool separate)
const FileSpec & GetWorkingDirectory() const
Args GetExtraStartupCommands() const
FollowForkMode GetFollowForkMode() const
std::chrono::seconds GetInterruptTimeout() const
A plug-in interface definition class for debugging a process.
lldb::IOHandlerSP m_process_input_reader
std::mutex m_process_input_reader_mutex
StopPointSiteList< lldb_private::BreakpointSite > & GetBreakpointSiteList()
virtual Status DisableSoftwareBreakpoint(BreakpointSite *bp_site)
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
ThreadList & GetThreadList()
void SetAddressableBitMasks(AddressableBits bit_masks)
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
void SetUnixSignals(lldb::UnixSignalsSP &&signals_sp)
void SetSTDIOFileDescriptor(int file_descriptor, std::optional< int > secondary_fd=std::nullopt)
Associates a file descriptor with the process' STDIO handling and configures an asynchronous reading ...
virtual void ModulesDidLoad(ModuleList &module_list)
virtual llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buffer)
Reads each range individually via ReadMemoryFromInferior, bypassing the memory cache.
void ResumePrivateStateThread()
void MapSupportedStructuredDataPlugins(const StructuredData::Array &supported_type_names)
Loads any plugins associated with asynchronous structured data and maps the relevant supported type n...
std::map< lldb::BreakpointSiteSP, BreakpointAction, SiteIDCmp > BreakpointSiteToActionMap
virtual SystemRuntime * GetSystemRuntime()
Get the system runtime plug-in for this process.
std::map< uint64_t, uint32_t > m_thread_id_to_index_id_map
lldb::StateType GetPrivateState() const
void SetBreakpointSiteEnabled(BreakpointSite &site, bool is_enabled=true)
lldb::DynamicLoaderUP m_dyld_up
virtual Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries)
StopPointSiteList< lldb_private::WatchpointResource > m_watchpoint_resource_list
Watchpoint resources currently in use.
bool IsBreakpointSitePhysicallyEnabled(const BreakpointSite &site)
std::vector< AddressSpaceInfo > m_address_spaces
A list of address spaces for this process.
void AppendSTDOUT(const char *s, size_t len)
bool HasAssignedIndexIDToThread(uint64_t sb_thread_id)
lldb::ByteOrder GetByteOrder() const
void UpdateThreadListIfNeeded()
bool IsValid() const
Return whether this object is valid (i.e.
virtual void DidExec()
Called after a process re-execs itself.
void BroadcastAsyncProfileData(const std::string &one_profile_data)
lldb::UnixSignalsSP m_unix_signals_sp
lldb::tid_t m_interrupt_tid
void AddCacheData(lldb::addr_t addr, const lldb::WritableDataBufferSP &data_buffer_sp)
Cache memory, restoring the original bytes under any breakpoint.
virtual Status EnableSoftwareBreakpoint(BreakpointSite *bp_site)
bool RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp)
Route the incoming structured data dictionary to the right plugin.
virtual bool IsAlive()
Check if a process is still alive.
ThreadList m_thread_list_real
The threads for this process as are known to the protocol we are debugging with.
lldb::StateType m_last_broadcast_state
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
uint32_t AssignIndexIDToThread(uint64_t thread_id)
virtual bool SetExitStatus(int exit_status, llvm::StringRef exit_string)
Set accessor for the process exit status (return code).
uint32_t GetAddressByteSize() const
uint32_t GetStopID() const
void SetPrivateState(lldb::StateType state)
llvm::Expected< AddressSpaceInfo > GetAddressSpaceInfo(llvm::StringRef address_space_name)
lldb::StateType GetPublicState() const
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
void SetSTDIOPseudoTerminal(PseudoTerminal &pty)
Associates the primary side of pty with the process' STDIO handling.
ThreadList m_thread_list
The threads for this process as the user will see them.
const lldb::UnixSignalsSP & GetUnixSignals()
std::weak_ptr< Target > m_target_wp
The target that owns this process.
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
friend class DynamicLoader
size_t GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site)
const ProcessModID & GetModIDRef() const
ThreadedCommunication m_stdio_communication
Target & GetTarget()
Get the target object pointer for this module.
lldb::OptionValuePropertiesSP GetValueProperties() const
A pseudo terminal helper class.
llvm::Error OpenFirstAvailablePrimary(int oflag)
Open the first available pseudo terminal.
@ invalid_fd
Invalid file descriptor value.
int GetPrimaryFileDescriptor() const
The primary file descriptor accessor.
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
std::string GetSecondaryName() const
Get the name of the secondary pseudo terminal.
std::vector< Enumerator > Enumerators
const Enumerators & GetEnumerators() const
void DumpToLog(Log *log) const
unsigned GetSizeInBits() const
Get size of the field in bits. Will always be at least 1.
uint64_t GetMaxValue() const
The maximum unsigned value that could be contained in this field.
virtual std::optional< uint64_t > GetByteSize() const
Return this type's fixed size in bytes, if it has one.
virtual StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Status &error)
virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error)
Status CompleteSending(lldb::pid_t child_pid)
shared_fd_t GetSendableFD()
static llvm::Expected< Pair > CreatePair(std::optional< SocketProtocol > protocol=std::nullopt)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
static lldb::StopInfoSP CreateStopReasonWithMachException(Thread &thread, uint32_t exc_type, uint32_t exc_data_count, uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, bool pc_already_adjusted=true, bool adjust_pc_if_needed=false)
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread)
static lldb::StopInfoSP CreateStopReasonVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonWithInterrupt(Thread &thread, int signo, const char *description)
static lldb::StopInfoSP CreateStopReasonWithSignal(Thread &thread, int signo, const char *description=nullptr, std::optional< int > code=std::nullopt)
static lldb::StopInfoSP CreateStopReasonFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonVForkDone(Thread &thread)
static lldb::StopInfoSP CreateStopReasonWithWatchpointID(Thread &thread, lldb::break_id_t watch_id, bool silently_continue=false)
static lldb::StopInfoSP CreateStopReasonWithException(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(Thread &thread, lldb::break_id_t break_id)
static lldb::StopInfoSP CreateStopReasonHistoryBoundary(Thread &thread, const char *description)
static lldb::StopInfoSP 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 RebuildModuleListWithExecutable(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Clear the module list and rebuild it around a new main executable.
bool MergeArchitecture(const ArchSpec &arch_spec)
void AddThreadSortedByIndexID(const lldb::ThreadSP &thread_sp)
static llvm::Expected< HostThread > LaunchThread(llvm::StringRef name, std::function< lldb::thread_result_t()> thread_function, size_t min_stack_byte_size=0)
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid, bool can_update=true)
Represents UUID's of various sizes.
bool SetFromStringRef(llvm::StringRef str)
static lldb::UnixSignalsSP Create(const ArchSpec &arch)
static std::vector< lldb::WatchpointResourceSP > AtomizeWatchpointRequest(lldb::addr_t addr, size_t size, bool read, bool write, WatchpointHardwareFeature supported_features, ArchSpec &arch)
Convert a user's watchpoint request into an array of memory regions, each region watched by one hardw...
XMLNode GetRootElement(const char *required_name=nullptr)
bool ParseMemory(const char *xml, size_t xml_length, const char *url="untitled.xml")
void ForEachChildElement(NodeCallback const &callback) const
llvm::StringRef GetName() const
bool GetElementText(std::string &text) const
std::string GetAttributeValue(const char *name, const char *fail_value=nullptr) const
bool NameIs(const char *name) const
void ForEachChildElementWithName(const char *name, NodeCallback const &callback) const
XMLNode FindFirstChildElementWithName(const char *name) const
void ForEachAttribute(AttributeCallback const &callback) const
@ eBroadcastBitRunPacketSent
PacketResult SendPacketAndReceiveResponseWithOutputSupport(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout, llvm::function_ref< void(llvm::StringRef)> output_callback)
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0), bool sync_on_timeout=true)
lldb::StateType SendContinuePacketAndWaitForResponse(ContinueDelegate &delegate, const UnixSignals &signals, llvm::StringRef payload, std::chrono::seconds interrupt_timeout, StringExtractorGDBRemote &response)
bool SupportsGDBStoppointPacket(GDBStoppointType type)
llvm::Expected< std::string > ReadExtFeature(llvm::StringRef object, llvm::StringRef annex)
void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm)
bool GetQXferLibrariesSVR4ReadSupported()
bool GetQXferLibrariesReadSupported()
void DumpHistory(Stream &strm)
Status FlashErase(lldb::addr_t addr, size_t size)
Status DisableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buf) override
Override of DoReadMemoryRanges that uses MultiMemRead to perform this operation in a single packet.
friend class ThreadGDBRemote
DataExtractor GetAuxvData() override
GDBRemoteCommunicationClient & GetGDBRemote()
static bool AcceleratorBreakpointHitCallback(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
Breakpoint callback invoked when an accelerator-plugin-requested breakpoint is hit.
Status DoConnectRemote(llvm::StringRef remote_url) override
Attach to a remote system via a URL.
void HandleAsyncStructuredDataPacket(llvm::StringRef data) override
Process asynchronously-received structured data.
void KillDebugserverProcess()
Status DoDestroy() override
llvm::Error DoDisableBreakpointSite(BreakpointSite &bp_site)
Disable a single breakpoint site directly by sending the appropriate z packet or restoring the origin...
std::vector< std::unique_ptr< RegisterType > > m_register_types
Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info)
virtual std::shared_ptr< ThreadGDBRemote > CreateThread(lldb::tid_t tid)
StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(lldb::addr_t image_list_address, lldb::addr_t image_count) override
Retrieve the list of shared libraries that are loaded for this process This method is used on pre-mac...
llvm::Error HandleAcceleratorActions(const AcceleratorActions &actions)
Handle a set of actions requested by an accelerator plugin.
lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet)
static void MonitorDebugserverProcess(std::weak_ptr< ProcessGDBRemote > process_wp, lldb::pid_t pid, int signo, int exit_status)
StructuredData::ObjectSP GetSharedCacheInfo() override
Status DisableBreakpointSite(BreakpointSite *bp_site) override
Status EnableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
Status DoSignal(int signal) override
Sends a process a UNIX signal signal.
Status DoDeallocateMemory(lldb::addr_t ptr) override
Actually deallocate memory in the process.
Broadcaster m_async_broadcaster
bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec)
llvm::Error UpdateBreakpointSitesNotBatched(const BreakpointSiteToActionMap &site_to_action)
bool StopNoticingNewThreads() override
Call this to turn off the stop & notice new threads mode.
static bool NewThreadNotifyBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid, bool is_expression_fork=false) override
Called after a reported fork.
void DumpPluginHistory(Stream &s) override
The underlying plugin might store the low-level communication history for this session.
FlashRangeVector m_erased_flash_ranges
Guarded< StructuredData::ObjectSP, std::mutex > m_shared_cache_info
Shared cache image list from the "jGetSharedCacheInfo" packet.
Status DoDetach(bool keep_stopped) override
Detaches from a running or stopped process.
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) override
Actually allocate memory in the process.
tid_sig_collection m_continue_C_tids
bool HasErased(FlashRange range)
std::optional< bool > DoGetWatchpointReportedAfter() override
Provide an override value in the subclass for lldb's CPU-based logic for whether watchpoint exception...
void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid, bool is_expression_fork=false) override
Called after a reported vfork.
Status WillLaunchOrAttach()
std::optional< uint32_t > GetWatchpointSlotCount() override
Get the number of watchpoints supported by this target.
GDBRemoteCommunicationClient m_gdb_comm
llvm::Expected< std::vector< uint8_t > > DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) override
Does the final operation to read memory tags.
llvm::DenseMap< ModuleCacheKey, ModuleSpec, ModuleCacheInfo > m_cached_module_specs
Status DoWillAttachToProcessWithID(lldb::pid_t pid) override
Called before attaching to a process.
friend class GDBRemoteCommunicationClient
void DidForkSwitchSoftwareBreakpoints(bool enable, bool is_expression_fork=false)
Status DoResume(lldb::RunDirection direction) override
Resumes all of a process's threads as configured using the Thread run control functions.
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.
Guarded< StructuredData::ObjectSP, std::mutex > m_jthreadsinfo
Full stop info, expedited registers and memory for all threads, from the "jThreadsInfo" packet.
static void DebuggerInitialize(Debugger &debugger)
tid_collection m_thread_ids
Status DoAttachToProcessWithName(const char *process_name, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a partial process name.
std::string m_partial_profile_data
StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos_sender(StructuredData::ObjectSP args)
void MaybeLoadExecutableModule()
std::vector< lldb::addr_t > m_thread_pcs
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
void SetThreadPc(const lldb::ThreadSP &thread_sp, uint64_t index)
std::recursive_mutex m_async_thread_state_mutex
bool DoCanAllocateMemory() override
Determines whether DoAllocateMemory is expected to succeed, without running code in the process.
Status ConnectToDebugserver(llvm::StringRef host_port)
void SetUnixSignals(const lldb::UnixSignalsSP &signals_sp)
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
uint64_t m_remote_stub_max_memory_size
std::optional< StringExtractorGDBRemote > m_last_stop_packet
CommandObject * GetPluginCommandObject() override
Return a multi-word command object that can be used to expose plug-in specific commands.
int64_t m_breakpoint_pc_offset
size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, Status &error) override
Actually do the writing of memory to a process.
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override
Launch a new process.
lldb::CommandObjectSP m_command_sp
void DidVForkDone() override
Called after reported vfork completion.
std::string HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &inputStringExtractor)
bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, std::string xml_filename, std::vector< DynamicRegisterInfo::Register > ®isters)
lldb::tid_t m_last_stop_primary_tid
bool m_use_g_packet_for_reading
Status DoWillAttachToProcessWithName(const char *process_name, bool wait_for_launch) override
Called before attaching to a process.
static std::chrono::seconds GetPacketTimeout()
lldb::ListenerSP m_async_listener_sp
std::pair< std::string, std::string > ModuleCacheKey
bool CalculateThreadStopInfo(ThreadGDBRemote *thread)
Guarded< StructuredData::ObjectSP, std::mutex > m_jstopinfo
Stop info caches filled at a stop and reset by WillResume, which runs on another thread.
lldb::DynamicRegisterInfoSP m_register_info_sp
tid_collection m_continue_c_tids
bool SupportsMemoryTagging() override
Check whether the process supports memory tagging.
void BuildDynamicRegisterInfo(bool force)
tid_collection m_continue_s_tids
size_t UpdateThreadPCsFromStopReplyThreadsValue(llvm::StringRef value)
~ProcessGDBRemote() override
llvm::VersionTuple GetHostOSVersion() override
Sometimes the connection to a process can detect the host OS version that the process is running on.
lldb::tid_t m_initial_tid
llvm::Expected< StringExtractorGDBRemote > SendMultiMemReadPacket(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges)
std::map< uint64_t, uint32_t > m_thread_id_to_used_usec_map
Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, const std::vector< uint8_t > &tags) override
Does the final operation to write memory tags.
llvm::Error ParseMultiMemReadPacket(llvm::StringRef response_str, llvm::MutableArrayRef< uint8_t > buffer, unsigned expected_num_ranges, llvm::SmallVectorImpl< llvm::MutableArrayRef< uint8_t > > &memory_regions)
llvm::Expected< std::vector< uint8_t > > TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override
Get binary data given a trace technology and a data identifier.
llvm::Error HandleAcceleratorBreakpoints(const AcceleratorActions &actions)
Set the breakpoints requested by an accelerator plugin as internal breakpoints with a callback that n...
Status EnableBreakpointSite(BreakpointSite *bp_site) override
void ModulesDidLoad(ModuleList &module_list) override
ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
uint32_t m_vfork_in_progress_count
@ eBroadcastBitAsyncContinue
@ eBroadcastBitAsyncThreadShouldExit
@ eBroadcastBitAsyncThreadDidExit
Status WillResume() override
Called before resuming to a process.
lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr, bool value_is_offset)
void SetLastStopPacket(const StringExtractorGDBRemote &response)
lldb::thread_result_t AsyncThread()
Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries) override
static std::chrono::milliseconds GetPacketTestDelay()
llvm::Error LoadModules() override
Sometimes processes know how to retrieve and load shared libraries.
uint64_t m_max_memory_size
void HandleAsyncMisc(llvm::StringRef data) override
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path, bool can_connect)
void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple) override
llvm::VersionTuple GetHostMacCatalystVersion() override
void DidForkSwitchHardwareTraps(bool enable)
HostThread m_async_thread
StructuredData::ObjectSP GetDynamicLoaderProcessState() override
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override
Try to fetch the module specification for a module with the given file name and architecture.
Status DoWillLaunch(Module *module) override
Called before launching to a process.
void DidAttach(ArchSpec &process_arch) override
Called after attaching a process.
llvm::Expected< bool > SaveCore(llvm::StringRef outfile) override
Save core dump into the specified file.
std::atomic< lldb::pid_t > m_debugserver_pid
std::optional< Diagnostics::ArtifactProviderID > m_diagnostics_artifact_id
Registration for the packet-history diagnostics provider, if enabled.
llvm::Expected< std::string > TraceGetState(llvm::StringRef type) override
Get the current tracing state of the process and its threads.
bool IsAlive() override
Check if a process is still alive.
void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override
void SetQueueInfo(std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue)
void SetNewlyAddedBinaries(const std::vector< lldb::addr_t > &added_binaries)
void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr)
void PrivateSetRegisterUnavailable(uint32_t reg)
lldb::RegisterContextSP GetRegisterContext() override
void SetDetailedBinariesInfo(StructuredData::ObjectSP &detailed_info)
void SetAssociatedWithLibdispatchQueue(lldb_private::LazyBool associated_with_libdispatch_queue) override
bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef< uint8_t > data)
#define LLDB_INVALID_SITE_ID
#define LLDB_INVALID_WATCH_ID
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_THREAD_ID
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_INVALID_PROCESS_ID
#define LLDB_DEFAULT_ADDRESS_SPACE_ID
#define LLDB_REGNUM_GENERIC_PC
lldb::ByteOrder InlHostByteOrder()
std::vector< DynamicRegisterInfo::Register > GetFallbackRegisters(const ArchSpec &arch_to_use)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length)
bool StateIsRunningState(lldb::StateType state)
Check if a state represents a state where the process or thread is running.
bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr, lldb::addr_t addr, lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset)
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
const char * GetPermissionsAsCString(uint32_t permissions)
void DumpProcessGDBRemotePacketHistory(void *p, const char *path)
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::BreakpointSite > BreakpointSiteSP
RunDirection
Execution directions.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
ConnectionStatus
Connection Status Types.
@ eConnectionStatusSuccess
Success.
std::shared_ptr< lldb_private::UnixSignals > UnixSignalsSP
@ eFormatCString
Null-terminated C strings.
@ eFormatCharArray
Print characters with no single quotes, used for character arrays that can contain non printable char...
@ eFormatInstruction
Disassemble an opcode.
@ eFormatVoid
Do not print this.
@ eFormatComplex
Floating point complex type.
@ eFormatHexFloat
ISO C99 hex float string.
@ eFormatOSType
OS character codes encoded into an integer 'PICT' 'text' etc...
@ eFormatAddressInfo
Describe what an address points to (func + offset with file/line, symbol + offset,...
@ eFormatCharPrintable
Only printable characters, '.' if not printable.
@ eFormatComplexInteger
Integer complex type.
@ eFormatFloat128
Disambiguate between 128-bit long double (which uses eFormatFloat) and __float128 (which uses eFormat...
std::shared_ptr< lldb_private::Platform > PlatformSP
StateType
Process and Thread States.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ eStateConnected
Process is connected to remote debug services, but not launched or attached to anything yet.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateAttaching
Process is currently trying to attach.
@ eStateExited
Process has exited and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eSymbolSharedCacheUseInferiorSharedCacheOnly
@ eSymbolSharedCacheUseHostAndInferiorSharedCache
std::shared_ptr< lldb_private::Stream > StreamSP
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::Process > ProcessSP
Encoding
Register encoding definitions.
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
@ eEncodingSint
signed integer
std::shared_ptr< lldb_private::Event > EventSP
@ eReturnStatusSuccessFinishResult
@ eArgTypeUnsignedInteger
std::shared_ptr< lldb_private::Watchpoint > WatchpointSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::WatchpointResource > WatchpointResourceSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
BinaryInformationLevel
When the Process plugin can retrieve information about all binaries loaded in the target process,...
@ eBinaryInformationLevelAddrName
@ eBinaryInformationLevelAddrNameUUID
@ eBinaryInformationLevelFull
@ eBinaryInformationLevelAddrOnly
std::shared_ptr< lldb_private::Target > TargetSP
std::unique_ptr< lldb_private::Stream > StreamUP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindProcessPlugin
num used by the process plugin - e.g.
Actions to be performed in the native process on behalf of an accelerator plugin.
std::vector< AcceleratorBreakpointInfo > breakpoints
New breakpoints to set. Nothing to set if this is empty.
int64_t identifier
Unique identifier for this action within the plugin.
std::string plugin_name
Unique name identifying the accelerator plugin.
std::optional< AcceleratorConnectionInfo > connect_info
If set, the client should create a new target and connect to the accelerator GDB server described her...
std::string session_name
Human-readable label for the accelerator target.
Sent by the client when a plugin-requested breakpoint is hit.
AcceleratorBreakpointInfo breakpoint
std::vector< SymbolValue > symbol_values
int64_t identifier
Unique breakpoint ID used to identify this breakpoint in the BreakpointWasHit callback.
std::vector< std::string > symbol_names
Symbol names whose values should be supplied when the breakpoint is hit.
std::optional< AcceleratorBreakpointByAddress > by_address
Breakpoint by load address.
std::optional< AcceleratorBreakpointByName > by_name
Breakpoint by function name.
Information the client needs to connect to an accelerator GDB server.
std::string triple
Target triple for the accelerator target.
bool synchronous
If true, connect synchronously: the client blocks until the accelerator process is connected and stop...
std::optional< std::string > exe_path
Path to the executable to use when creating the accelerator target.
std::string connect_url
Connection URL the client should connect to (as in "process connect<url>").
std::string platform_name
Name of the platform to select when creating the accelerator target.
A binary to find and load into a Target.
lldb::addr_t value
Address where the binary should be loaded, or read out of memory.
UUID uuid
UUID of the binary to be loaded.
bool is_main_executable
Whether this is the process' main executable.
bool force_symbol_search
Allow the search to do a possibly expensive external search for the ObjectFile and/or SymbolFile.
bool set_address_in_target
Whether the address of the binary should be set in the Target if it is added.
bool notify
Whether ModulesDidLoad should be called once the binary has been added to the Target.
bool value_is_offset
A flag indicating that value is an address, or an offset to be applied to the file addresses.
const RegisterType * register_type
std::vector< uint32_t > value_regs
std::vector< uint32_t > invalidate_regs
Options used by Module::FindFunctions.
bool include_inlines
Include inlined functions.
bool include_symbols
Include the symbol table.
static Status ToFormat(const char *s, lldb::Format &format, size_t *byte_size_ptr)
BaseType GetRangeBase() const
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
BaseType GetRangeEnd() const
void SetByteSize(SizeType s)
jLLDBTraceGetBinaryData gdb-remote packet
jLLDBTraceStop gdb-remote packet