9#include "lldb/Host/Config.h"
14#include <netinet/in.h>
17#include <sys/socket.h>
22#include <sys/sysctl.h>
102#include "llvm/ADT/STLExtras.h"
103#include "llvm/ADT/ScopeExit.h"
104#include "llvm/ADT/StringMap.h"
105#include "llvm/ADT/StringSwitch.h"
106#include "llvm/Support/Chrono.h"
107#include "llvm/Support/ErrorExtras.h"
108#include "llvm/Support/FormatAdapters.h"
109#include "llvm/Support/Threading.h"
110#include "llvm/Support/raw_ostream.h"
112#if defined(__APPLE__)
113#define DEBUGSERVER_BASENAME "debugserver"
115#define DEBUGSERVER_BASENAME "lldb-server.exe"
117#define DEBUGSERVER_BASENAME "lldb-server"
137 llvm::consumeError(file.takeError());
141 ((
Process *)p)->DumpPluginHistory(stream);
147#define LLDB_PROPERTIES_processgdbremote
148#include "ProcessGDBRemoteProperties.inc"
151#define LLDB_PROPERTIES_processgdbremote
152#include "ProcessGDBRemotePropertiesEnum.inc"
157 static llvm::StringRef GetSettingName() {
161 PluginProperties() : Properties() {
162 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
163 m_collection_sp->Initialize(g_processgdbremote_properties_def);
166 ~PluginProperties()
override =
default;
168 uint64_t GetPacketTimeout() {
169 const uint32_t idx = ePropertyPacketTimeout;
170 return GetPropertyAtIndexAs<uint64_t>(
171 idx, g_processgdbremote_properties[idx].default_uint_value);
174 bool SetPacketTimeout(uint64_t timeout) {
175 const uint32_t idx = ePropertyPacketTimeout;
176 return SetPropertyAtIndex(idx, timeout);
179 FileSpec GetTargetDefinitionFile()
const {
180 const uint32_t idx = ePropertyTargetDefinitionFile;
181 return GetPropertyAtIndexAs<FileSpec>(idx, {});
184 bool GetUseSVR4()
const {
185 const uint32_t idx = ePropertyUseSVR4;
186 return GetPropertyAtIndexAs<bool>(
187 idx, g_processgdbremote_properties[idx].default_uint_value != 0);
190 bool GetUseGPacketForReading()
const {
191 const uint32_t idx = ePropertyUseGPacketForReading;
192 return GetPropertyAtIndexAs<bool>(idx,
true);
195 uint64_t GetPacketTestDelay()
const {
196 const uint32_t idx = ePropertyPacketTestDelay;
197 return GetPropertyAtIndexAs<uint64_t>(
198 idx, g_processgdbremote_properties[idx].default_uint_value);
202std::chrono::seconds ResumeTimeout() {
return std::chrono::seconds(5); }
204static std::pair<uint16_t, uint16_t> GetClientTerminalSize() {
206 CONSOLE_SCREEN_BUFFER_INFO csbi{};
207 HANDLE h = ::GetStdHandle(STD_OUTPUT_HANDLE);
208 if (h != INVALID_HANDLE_VALUE && ::GetConsoleScreenBufferInfo(h, &csbi)) {
209 int cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
210 int rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
211 if (cols > 0 && rows > 0)
212 return {
static_cast<uint16_t
>(cols),
static_cast<uint16_t
>(rows)};
214#elif LLDB_ENABLE_POSIX
216 if (::ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0 &&
218 return {ws.ws_col, ws.ws_row};
226 static PluginProperties g_settings;
234#if defined(__APPLE__)
235#define LOW_PORT (IPPORT_RESERVED)
236#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
238#define LOW_PORT (1024u)
239#define HIGH_PORT (49151u)
243 return "GDB Remote protocol based debugging plug-in.";
252 const FileSpec *crash_file_path,
bool can_connect) {
268 return std::chrono::milliseconds(
277 bool plugin_specified_by_name) {
278 if (plugin_specified_by_name)
282 Module *exe_module = target_sp->GetExecutableModulePointer();
286 switch (exe_objfile->
GetType()) {
310 :
Process(target_sp, listener_sp),
314 Listener::MakeListener(
"lldb.process.gdb-remote.async-listener")),
325 "async thread should exit");
327 "async thread continue");
329 "async thread did exit");
333 const uint32_t async_event_mask =
339 "ProcessGDBRemote::%s failed to listen for "
340 "m_async_broadcaster events",
344 const uint64_t timeout_seconds =
346 if (timeout_seconds > 0)
347 m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
355 llvm::sys::TimePoint<> now = std::chrono::system_clock::now();
356 std::string name = llvm::formatv(
357 "gdb-remote-packet-history-{0:%Y-%m-%dT%H-%M-%S}.txt", now);
359 std::move(name), [
this]() -> std::string {
390std::shared_ptr<ThreadGDBRemote>
392 return std::make_shared<ThreadGDBRemote>(*
this, tid);
396 const FileSpec &target_definition_fspec) {
402 if (module_object_sp) {
405 "gdb-server-target-definition",
error));
407 if (target_definition_sp) {
409 target_definition_sp->GetValueForKey(
"host-info"));
411 if (
auto host_info_dict = target_object->GetAsDictionary()) {
413 host_info_dict->GetValueForKey(
"triple");
414 if (
auto triple_string_value = triple_value->GetAsString()) {
415 std::string triple_string =
416 std::string(triple_string_value->GetValue());
417 ArchSpec host_arch(triple_string.c_str());
426 target_definition_sp->GetValueForKey(
"breakpoint-pc-offset");
427 if (breakpoint_pc_offset_value) {
428 if (
auto breakpoint_pc_int_value =
429 breakpoint_pc_offset_value->GetAsSignedInteger())
434 *target_definition_sp,
GetTarget().GetArchitecture()) > 0) {
443 const llvm::StringRef &comma_separated_register_numbers,
444 std::vector<uint32_t> ®nums,
int base) {
446 for (llvm::StringRef x : llvm::split(comma_separated_register_numbers,
',')) {
448 if (llvm::to_integer(x, reg, base))
449 regnums.push_back(reg);
451 return regnums.size();
463 const auto host_packet_timeout =
m_gdb_comm.GetHostDefaultPacketTimeout();
464 if (host_packet_timeout > std::chrono::seconds(0)) {
482 if (target_definition_fspec) {
488 target_definition_fspec.
GetPath() +
499 if (remote_process_arch.
IsValid())
500 arch_to_use = remote_process_arch;
502 arch_to_use = remote_host_arch;
505 arch_to_use = target_arch;
508 if (!register_info_err) {
515 "Failed to read register information from target XML: {0}");
516 LLDB_LOG(log,
"Now trying to use qRegisterInfo instead.");
519 std::vector<DynamicRegisterInfo::Register> registers;
520 uint32_t reg_num = 0;
524 const int packet_len =
525 ::snprintf(packet,
sizeof(packet),
"qRegisterInfo%x", reg_num);
526 assert(packet_len < (
int)
sizeof(packet));
529 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
533 llvm::StringRef name;
534 llvm::StringRef value;
538 if (name ==
"name") {
540 }
else if (name ==
"alt-name") {
542 }
else if (name ==
"bitsize") {
545 }
else if (name ==
"offset") {
547 }
else if (name ==
"encoding") {
551 }
else if (name ==
"format") {
555 llvm::StringSwitch<Format>(value)
597 }
else if (name ==
"set") {
599 }
else if (name ==
"gcc" || name ==
"ehframe") {
601 }
else if (name ==
"dwarf") {
603 }
else if (name ==
"generic") {
605 }
else if (name ==
"container-regs") {
607 }
else if (name ==
"invalidate-regs") {
613 registers.push_back(reg_info);
626 "the debug server supports Target Description XML but LLDB does "
627 "not have XML parsing enabled. Using \"qRegisterInfo\" was also "
628 "not possible. Register information may be incorrect or missing",
638 if (registers.empty()) {
640 if (!registers.empty())
643 "All other methods failed, using fallback register information.");
658 bool wait_for_launch) {
690 if (
m_gdb_comm.GetProcessArchitecture().IsValid()) {
693 if (
m_gdb_comm.GetHostArchitecture().IsValid()) {
704 "Process %" PRIu64
" was reported after connecting to "
705 "'%s', but state was not stopped: %s",
709 "Process %" PRIu64
" was reported after connecting to '%s', "
710 "but no stop reply packet was received",
711 pid, remote_url.str().c_str());
715 "ProcessGDBRemote::%s pid %" PRIu64
716 ": normalizing target architecture initial triple: %s "
717 "(GetTarget().GetArchitecture().IsValid() %s, "
718 "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
719 __FUNCTION__,
GetID(),
720 GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
722 m_gdb_comm.GetHostArchitecture().IsValid() ?
"true" :
"false");
728 if (
m_gdb_comm.GetProcessArchitecture().IsValid())
735 "ProcessGDBRemote::%s pid %" PRIu64
736 ": normalized target architecture triple: %s",
737 __FUNCTION__,
GetID(),
738 GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
755 LLDB_LOGF(log,
"ProcessGDBRemote::%s() entered", __FUNCTION__);
757 uint32_t launch_flags = launch_info.
GetFlags().
Get();
780 if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
782 "ProcessGDBRemote::%s provided with STDIO paths via "
783 "launch_info: stdin=%s, stdout=%s, stderr=%s",
785 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
786 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
787 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
789 LLDB_LOGF(log,
"ProcessGDBRemote::%s no STDIO paths given via launch_info",
792 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
793 if (stdin_file_spec || disable_stdio) {
808 if (
error.Success()) {
810 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
815 if (!stdin_file_spec)
817 FileSpec::Style::native);
818 if (!stdout_file_spec)
820 FileSpec::Style::native);
821 if (!stderr_file_spec)
823 FileSpec::Style::native);
824 }
else if (platform_sp && platform_sp->IsHost()) {
829 if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
833 if (!stdin_file_spec)
834 stdin_file_spec = secondary_name;
836 if (!stdout_file_spec)
837 stdout_file_spec = secondary_name;
839 if (!stderr_file_spec)
840 stderr_file_spec = secondary_name;
844 "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
845 "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
848 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
849 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
850 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
854 "ProcessGDBRemote::%s final STDIO paths after all "
855 "adjustments: stdin=%s, stdout=%s, stderr=%s",
857 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
858 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
859 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
863 if (stdout_file_spec)
865 if (stderr_file_spec)
868 if (launch_flags & eLaunchFlagUsePipes) {
871 auto [terminal_cols, terminal_rows] = GetClientTerminalSize();
872 m_gdb_comm.SetSTDIOWindowSize(terminal_cols, terminal_rows);
875 m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
876 m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
879 GetTarget().GetArchitecture().GetArchitectureName());
882 if (launch_event_data !=
nullptr && *launch_event_data !=
'\0')
883 m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
895 std::chrono::seconds(10));
901 const llvm::Triple &remote_triple =
903 if (remote_triple.getOS() != llvm::Triple::UnknownOS) {
904 FileSpec remote_exe_file(exe_file.GetPath(
false),
907 0, remote_exe_file.
GetPath(
true));
910 exe_file.GetPath(
true));
913 if (llvm::Error err =
m_gdb_comm.LaunchProcess(args)) {
916 llvm::fmt_consume(std::move(err)));
923 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
945 if (!disable_stdio) {
955 std::make_shared<IOHandlerProcessSTDIOWindows>(
this);
961 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
error.AsCString());
971 if (!connect_url.empty()) {
972 LLDB_LOGF(log,
"ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
973 connect_url.str().c_str());
974 std::unique_ptr<ConnectionFileDescriptor> conn_up(
977 const uint32_t max_retry_count = 50;
978 uint32_t retry_count = 0;
987 if (retry_count >= max_retry_count)
990 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1007 if (
error.Success())
1014 m_gdb_comm.GetListThreadsInStopReplySupported();
1021 auto handle_cmds = [&] (
const Args &args) ->
void {
1025 entry.c_str(), response);
1031 handle_cmds(platform_sp->GetExtraStartupCommands());
1048 if (remote_process_arch.
IsValid()) {
1049 process_arch = remote_process_arch;
1050 LLDB_LOG(log,
"gdb-remote had process architecture, using {0} {1}",
1054 process_arch =
m_gdb_comm.GetHostArchitecture();
1056 "gdb-remote did not have process architecture, using gdb-remote "
1057 "host architecture {0} {1}",
1068 LLDB_LOG(log,
"analyzing target arch, currently {0} {1}",
1080 if ((process_arch.
GetMachine() == llvm::Triple::arm ||
1081 process_arch.
GetMachine() == llvm::Triple::thumb) &&
1082 process_arch.
GetTriple().getVendor() == llvm::Triple::Apple) {
1085 "remote process is ARM/Apple, "
1086 "setting target arch to {0} {1}",
1091 const llvm::Triple &remote_triple = process_arch.
GetTriple();
1092 llvm::Triple new_target_triple = target_arch.
GetTriple();
1093 if (new_target_triple.getVendorName().size() == 0) {
1094 new_target_triple.setVendor(remote_triple.getVendor());
1096 if (new_target_triple.getOSName().size() == 0) {
1097 new_target_triple.setOS(remote_triple.getOS());
1099 if (new_target_triple.getEnvironmentName().size() == 0)
1100 new_target_triple.setEnvironment(remote_triple.getEnvironment());
1103 ArchSpec new_target_arch = target_arch;
1104 new_target_arch.
SetTriple(new_target_triple);
1110 "final target arch after adjustments for remote architecture: "
1129 m_gdb_comm.GetSupportedStructuredDataPlugins())
1138 if (platform_sp && platform_sp->IsConnected())
1146 llvm::Expected<std::vector<AcceleratorActions>> init_actions =
1147 m_gdb_comm.GetAcceleratorInitializeActions();
1148 if (!init_actions) {
1150 "failed to get accelerator initialize actions: {0}");
1155 "failed to handle accelerator actions: {0}");
1165 UUID standalone_uuid;
1167 bool standalone_value_is_offset;
1168 if (
m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value,
1169 standalone_value_is_offset)) {
1170 if (standalone_uuid.
IsValid()) {
1172 bin_spec.
uuid = standalone_uuid;
1173 bin_spec.
value = standalone_value;
1178 llvm::Expected<ModuleSP> module =
1182 << llvm::toString(module.takeError()) <<
"\n";
1194 std::vector<addr_t> bin_addrs =
m_gdb_comm.GetProcessStandaloneBinaries();
1195 if (bin_addrs.size()) {
1196 for (
addr_t addr : bin_addrs) {
1197 const bool notify =
true;
1204 .LoadPlatformBinaryAndSetup(
this, addr, notify))
1209 bin_spec.
value = addr;
1211 bin_spec.
notify = notify;
1213 llvm::Expected<ModuleSP> module =
1217 << llvm::toString(module.takeError()) <<
"\n";
1227 std::optional<QOffsets> offsets =
m_gdb_comm.GetQOffsets();
1232 size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==
1233 offsets->offsets.size();
1237 bool changed =
false;
1238 module_sp->SetLoadAddress(
GetTarget(), offsets->offsets[0],
1243 m_process->GetTarget().ModulesDidLoad(list);
1257 LLDB_LOGF(log,
"ProcessGDBRemote::%s()", __FUNCTION__);
1263 if (
error.Success()) {
1267 const int packet_len =
1268 ::snprintf(packet,
sizeof(packet),
"vAttach;%" PRIx64, attach_pid);
1271 std::make_shared<EventDataBytes>(llvm::StringRef(packet, packet_len));
1286 if (process_name && process_name[0]) {
1288 if (
error.Success()) {
1294 if (!
m_gdb_comm.GetVAttachOrWaitSupported()) {
1309 auto data_sp = std::make_shared<EventDataBytes>(packet.
GetString());
1330llvm::Expected<std::string>
1335llvm::Expected<std::vector<uint8_t>>
1347 process_arch.
Clear();
1363 return m_gdb_comm.GetReverseStepSupported() ||
1370 LLDB_LOGF(log,
"ProcessGDBRemote::Resume(%s)",
1375 if (listener_sp->StartListeningForEvents(
1377 listener_sp->StartListeningForEvents(
1384 bool continue_packet_error =
false;
1398 std::string pid_prefix;
1400 pid_prefix = llvm::formatv(
"p{0:x-}.",
GetID());
1402 if (num_continue_c_tids == num_threads ||
1407 continue_packet.
Format(
"vCont;c:{0}-1", pid_prefix);
1415 for (tid_collection::const_iterator
1418 t_pos != t_end; ++t_pos)
1419 continue_packet.
Format(
";c:{0}{1:x-}", pid_prefix, *t_pos);
1421 continue_packet_error =
true;
1426 for (tid_sig_collection::const_iterator
1429 s_pos != s_end; ++s_pos)
1430 continue_packet.
Format(
";C{0:x-2}:{1}{2:x-}", s_pos->second,
1431 pid_prefix, s_pos->first);
1433 continue_packet_error =
true;
1438 for (tid_collection::const_iterator
1441 t_pos != t_end; ++t_pos)
1442 continue_packet.
Format(
";s:{0}{1:x-}", pid_prefix, *t_pos);
1444 continue_packet_error =
true;
1449 for (tid_sig_collection::const_iterator
1452 s_pos != s_end; ++s_pos)
1453 continue_packet.
Format(
";S{0:x-2}:{1}{2:x-}", s_pos->second,
1454 pid_prefix, s_pos->first);
1456 continue_packet_error =
true;
1459 if (continue_packet_error)
1460 continue_packet.
Clear();
1463 continue_packet_error =
true;
1469 if (num_continue_c_tids > 0) {
1470 if (num_continue_c_tids == num_threads) {
1474 continue_packet_error =
false;
1475 }
else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
1476 num_continue_s_tids == 0 && num_continue_S_tids == 0) {
1480 continue_packet_error =
false;
1484 if (continue_packet_error && num_continue_C_tids > 0) {
1485 if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
1486 num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
1487 num_continue_S_tids == 0) {
1490 if (num_continue_C_tids > 1) {
1495 if (num_continue_C_tids > 1) {
1496 continue_packet_error =
false;
1499 continue_packet_error =
true;
1502 if (!continue_packet_error)
1506 continue_packet_error =
false;
1509 if (!continue_packet_error) {
1511 continue_packet.
Printf(
"C%2.2x", continue_signo);
1516 if (continue_packet_error && num_continue_s_tids > 0) {
1517 if (num_continue_s_tids == num_threads) {
1523 continue_packet_error =
false;
1524 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1525 num_continue_s_tids == 1 && num_continue_S_tids == 0) {
1529 continue_packet_error =
false;
1533 if (!continue_packet_error && num_continue_S_tids > 0) {
1534 if (num_continue_S_tids == num_threads) {
1537 continue_packet_error =
false;
1538 if (num_continue_S_tids > 1) {
1539 for (
size_t i = 1; i < num_threads; ++i) {
1541 continue_packet_error =
true;
1544 if (!continue_packet_error) {
1547 continue_packet.
Printf(
"S%2.2x", step_signo);
1549 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1550 num_continue_s_tids == 0 && num_continue_S_tids == 1) {
1554 continue_packet_error =
false;
1560 if (num_continue_s_tids > 0 || num_continue_S_tids > 0) {
1562 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1563 "support reverse-stepping");
1565 "target does not support reverse-stepping");
1568 if (num_continue_S_tids > 0) {
1571 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1573 "can't deliver signals while running in reverse");
1576 if (num_continue_s_tids > 1) {
1577 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: can't step multiple "
1578 "threads in reverse");
1580 "can't step multiple threads while reverse-stepping");
1586 if (!
m_gdb_comm.GetReverseContinueSupported()) {
1587 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1588 "support reverse-continue");
1590 "target does not support reverse execution of processes");
1593 if (num_continue_C_tids > 0) {
1596 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1598 "can't deliver signals while running in reverse");
1606 continue_packet_error =
false;
1609 if (continue_packet_error) {
1611 "can't make continue packet for this resume");
1616 "Trying to resume but the async thread is dead.");
1617 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Trying to resume but the "
1618 "async thread is dead.");
1623 std::make_shared<EventDataBytes>(continue_packet.
GetString());
1626 if (!listener_sp->GetEvent(event_sp, ResumeTimeout())) {
1628 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Resume timed out.");
1631 "Broadcast continue, but the async thread was "
1632 "killed before we got an ack back.");
1634 "ProcessGDBRemote::DoResume: Broadcast continue, but the "
1635 "async thread was killed before we got an ack back.");
1651 llvm::StringRef value) {
1657 auto pid_tid = thread_ids.
GetPidTid(pid);
1658 if (pid_tid && pid_tid->first == pid) {
1664 }
while (thread_ids.
GetChar() ==
',');
1670 llvm::StringRef value) {
1672 for (llvm::StringRef x : llvm::split(value,
',')) {
1674 if (llvm::to_integer(x,
pc, 16))
1686 if (thread_infos && thread_infos->
GetSize() > 0) {
1710 const llvm::StringRef stop_info_str = stop_info.
GetStringRef();
1713 const size_t thread_pcs_pos = stop_info_str.find(
";thread-pcs:");
1714 if (thread_pcs_pos != llvm::StringRef::npos) {
1715 const size_t start = thread_pcs_pos + strlen(
";thread-pcs:");
1716 const size_t end = stop_info_str.find(
';', start);
1717 if (end != llvm::StringRef::npos) {
1718 llvm::StringRef value = stop_info_str.substr(start, end - start);
1723 const size_t threads_pos = stop_info_str.find(
";threads:");
1724 if (threads_pos != llvm::StringRef::npos) {
1725 const size_t start = threads_pos + strlen(
";threads:");
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);
1736 bool sequence_mutex_unavailable =
false;
1738 if (sequence_mutex_unavailable) {
1753 if (num_thread_ids == 0) {
1759 ThreadList old_thread_list_copy(old_thread_list);
1760 if (num_thread_ids > 0) {
1761 for (
size_t i = 0; i < num_thread_ids; ++i) {
1768 thread_sp.get(), thread_sp->GetID());
1771 thread_sp.get(), thread_sp->GetID());
1781 size_t old_num_thread_ids = old_thread_list_copy.
GetSize(
false);
1782 for (
size_t i = 0; i < old_num_thread_ids; i++) {
1784 if (old_thread_sp) {
1785 lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
1800 uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1813 if (thread_infos_sp) {
1817 const size_t n = thread_infos->
GetSize();
1818 for (
size_t i = 0; i < n; ++i) {
1824 if (tid == thread->GetID())
1853 if (
GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
1863 for (
const auto &pair : expedited_register_map) {
1864 uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1874 reg_value_extractor.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
1882 uint8_t signo,
const std::string &thread_name,
const std::string &reason,
1883 const std::string &description, uint32_t exc_type,
1884 const std::vector<addr_t> &exc_data,
addr_t thread_dispatch_qaddr,
1885 bool queue_vars_valid,
1887 LazyBool associated_with_dispatch_queue,
addr_t dispatch_queue_t,
1888 std::string &queue_name,
QueueKind queue_kind, uint64_t queue_serial,
1889 std::vector<lldb::addr_t> &added_binaries,
1914 reg_ctx_sp->InvalidateIfNeeded(
true);
1922 if (reg_ctx_sp->ReconfigureRegisterInfo()) {
1925 reg_ctx_sp->InvalidateAllRegisters();
1932 thread_sp->SetName(thread_name.empty() ?
nullptr : thread_name.c_str());
1937 if (queue_vars_valid)
1938 gdb_thread->
SetQueueInfo(std::move(queue_name), queue_kind, queue_serial,
1939 dispatch_queue_t, associated_with_dispatch_queue);
1953 StopInfoSP current_stop_info_sp = thread_sp->GetPrivateStopInfo(
false);
1955 current_stop_info_sp) {
1956 thread_sp->SetStopInfo(current_stop_info_sp);
1960 if (!thread_sp->StopInfoIsUpToDate()) {
1963 addr_t pc = thread_sp->GetRegisterContext()->GetPC();
1965 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1967 thread_sp->SetThreadStoppedAtUnexecutedBP(
pc);
1969 if (exc_type != 0) {
1977 if (interrupt_thread)
1978 thread_sp = interrupt_thread;
1980 const size_t exc_data_size = exc_data.size();
1981 thread_sp->SetStopInfo(
1983 *thread_sp, exc_type, exc_data_size,
1984 exc_data_size >= 1 ? exc_data[0] : 0,
1985 exc_data_size >= 2 ? exc_data[1] : 0,
1986 exc_data_size >= 3 ? exc_data[2] : 0));
1989 bool handled =
false;
1990 bool did_exec =
false;
1993 if (!reason.empty() && reason !=
"none") {
1994 if (reason ==
"trace") {
1997 }
else if (reason ==
"breakpoint") {
1998 thread_sp->SetThreadHitBreakpointSite();
2006 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2007 thread_sp->SetStopInfo(
2009 *thread_sp, bp_site_sp->GetID()));
2012 thread_sp->SetStopInfo(invalid_stop_info_sp);
2015 }
else if (reason ==
"trap") {
2017 }
else if (reason ==
"watchpoint") {
2053 bool silently_continue =
false;
2063 silently_continue =
true;
2067 if (!wp_resource_sp) {
2069 LLDB_LOGF(log,
"failed to find watchpoint");
2076 watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
2079 *thread_sp, watch_id, silently_continue));
2081 }
else if (reason ==
"exception") {
2083 *thread_sp, description.c_str()));
2085 }
else if (reason ==
"history boundary") {
2087 *thread_sp, description.c_str()));
2089 }
else if (reason ==
"exec") {
2091 thread_sp->SetStopInfo(
2094 }
else if (reason ==
"processor trace") {
2096 *thread_sp, description.c_str()));
2097 }
else if (reason ==
"fork") {
2102 thread_sp->SetStopInfo(
2105 }
else if (reason ==
"vfork") {
2111 *thread_sp, child_pid, child_tid));
2113 }
else if (reason ==
"vforkdone") {
2114 thread_sp->SetStopInfo(
2120 if (!handled && signo && !did_exec) {
2141 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
2151 thread_sp->SetThreadHitBreakpointSite();
2153 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2155 thread_sp->GetRegisterContext()->SetPC(
pc);
2156 thread_sp->SetStopInfo(
2158 *thread_sp, bp_site_sp->GetID()));
2161 thread_sp->SetStopInfo(invalid_stop_info_sp);
2167 thread_sp->SetStopInfo(
2171 *thread_sp, signo, description.c_str()));
2182 if (interrupt_thread)
2183 thread_sp = interrupt_thread;
2186 *thread_sp, signo, description.c_str()));
2190 if (!description.empty()) {
2193 const char *stop_info_desc = stop_info_sp->GetDescription();
2194 if (!stop_info_desc || !stop_info_desc[0])
2195 stop_info_sp->SetDescription(description.c_str());
2198 *thread_sp, description.c_str()));
2208 const std::string &description) {
2217 *thread_sp, signo, description.c_str()));
2226 static constexpr llvm::StringLiteral g_key_tid(
"tid");
2227 static constexpr llvm::StringLiteral g_key_name(
"name");
2228 static constexpr llvm::StringLiteral g_key_reason(
"reason");
2229 static constexpr llvm::StringLiteral g_key_metype(
"metype");
2230 static constexpr llvm::StringLiteral g_key_medata(
"medata");
2231 static constexpr llvm::StringLiteral g_key_qaddr(
"qaddr");
2232 static constexpr llvm::StringLiteral g_key_dispatch_queue_t(
2233 "dispatch_queue_t");
2234 static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(
2235 "associated_with_dispatch_queue");
2236 static constexpr llvm::StringLiteral g_key_queue_name(
"qname");
2237 static constexpr llvm::StringLiteral g_key_queue_kind(
"qkind");
2238 static constexpr llvm::StringLiteral g_key_queue_serial_number(
"qserialnum");
2239 static constexpr llvm::StringLiteral g_key_registers(
"registers");
2240 static constexpr llvm::StringLiteral g_key_memory(
"memory");
2241 static constexpr llvm::StringLiteral g_key_description(
"description");
2242 static constexpr llvm::StringLiteral g_key_signal(
"signal");
2243 static constexpr llvm::StringLiteral g_key_added_binaries(
"added-binaries");
2244 static constexpr llvm::StringLiteral g_key_detailed_binaries_info(
2245 "detailed-binaries-info");
2250 std::string thread_name;
2252 std::string description;
2253 uint32_t exc_type = 0;
2254 std::vector<addr_t> exc_data;
2257 bool queue_vars_valid =
false;
2260 std::string queue_name;
2262 uint64_t queue_serial_number = 0;
2263 std::vector<addr_t> added_binaries;
2269 thread_dict->
ForEach([
this, &tid, &expedited_register_map, &thread_name,
2270 &signo, &reason, &description, &exc_type, &exc_data,
2271 &thread_dispatch_qaddr, &queue_vars_valid,
2272 &associated_with_dispatch_queue, &dispatch_queue_t,
2273 &queue_name, &queue_kind, &queue_serial_number,
2274 &added_binaries, &detailed_binaries_info](
2275 llvm::StringRef key,
2277 if (key == g_key_tid) {
2280 }
else if (key == g_key_metype) {
2282 exc_type =
object->GetUnsignedIntegerValue(0);
2283 }
else if (key == g_key_medata) {
2288 exc_data.push_back(object->GetUnsignedIntegerValue());
2292 }
else if (key == g_key_name) {
2293 thread_name = std::string(object->GetStringValue());
2294 }
else if (key == g_key_qaddr) {
2295 thread_dispatch_qaddr =
2297 }
else if (key == g_key_queue_name) {
2298 queue_vars_valid =
true;
2299 queue_name = std::string(object->GetStringValue());
2300 }
else if (key == g_key_queue_kind) {
2301 std::string queue_kind_str = std::string(object->GetStringValue());
2302 if (queue_kind_str ==
"serial") {
2303 queue_vars_valid =
true;
2305 }
else if (queue_kind_str ==
"concurrent") {
2306 queue_vars_valid =
true;
2309 }
else if (key == g_key_queue_serial_number) {
2310 queue_serial_number =
object->GetUnsignedIntegerValue(0);
2311 if (queue_serial_number != 0)
2312 queue_vars_valid =
true;
2313 }
else if (key == g_key_dispatch_queue_t) {
2314 dispatch_queue_t =
object->GetUnsignedIntegerValue(0);
2316 queue_vars_valid =
true;
2317 }
else if (key == g_key_associated_with_dispatch_queue) {
2318 queue_vars_valid =
true;
2319 bool associated =
object->GetBooleanValue();
2324 }
else if (key == g_key_reason) {
2325 reason = std::string(object->GetStringValue());
2326 }
else if (key == g_key_description) {
2327 description = std::string(object->GetStringValue());
2328 }
else if (key == g_key_registers) {
2331 if (registers_dict) {
2333 [&expedited_register_map](llvm::StringRef key,
2336 if (llvm::to_integer(key, reg))
2337 expedited_register_map[reg] =
2338 std::string(object->GetStringValue());
2342 }
else if (key == g_key_memory) {
2348 if (mem_cache_dict) {
2351 "address", mem_cache_addr)) {
2353 llvm::StringRef str;
2358 const size_t byte_size = bytes.
GetStringRef().size() / 2;
2361 const size_t bytes_copied =
2363 if (bytes_copied == byte_size)
2373 }
else if (key == g_key_signal)
2375 else if (key == g_key_added_binaries) {
2378 array->
ForEach([&added_binaries](
2381 object->GetAsUnsignedInteger();
2385 added_binaries.push_back(value);
2390 }
else if (key == g_key_detailed_binaries_info) {
2395 if (object->GetAsDictionary()) {
2397 object->Dump(json_str);
2398 detailed_binaries_info =
2406 tid, expedited_register_map, signo, thread_name, reason, description,
2407 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2408 associated_with_dispatch_queue, dispatch_queue_t, queue_name, queue_kind,
2409 queue_serial_number, added_binaries, detailed_binaries_info);
2415 const char stop_type = stop_packet.
GetChar();
2416 switch (stop_type) {
2435 const uint8_t signo = stop_packet.
GetHexU8();
2436 llvm::StringRef key;
2437 llvm::StringRef value;
2438 std::string thread_name;
2440 std::string description;
2441 std::vector<addr_t> added_binaries;
2443 uint32_t exc_type = 0;
2444 std::vector<addr_t> exc_data;
2446 bool queue_vars_valid =
2450 std::string queue_name;
2452 uint64_t queue_serial_number = 0;
2456 if (key.compare(
"metype") == 0) {
2458 value.getAsInteger(
BASE_16, exc_type);
2459 }
else if (key.compare(
"medata") == 0) {
2462 value.getAsInteger(
BASE_16, x);
2463 exc_data.push_back(x);
2464 }
else if (key.compare(
"thread") == 0) {
2467 auto pid_tid = thread_id.
GetPidTid(pid);
2469 stop_pid = pid_tid->first;
2470 tid = pid_tid->second;
2473 }
else if (key.compare(
"threads") == 0) {
2474 std::lock_guard<std::recursive_mutex> guard(
2477 }
else if (key.compare(
"thread-pcs") == 0) {
2482 while (!value.empty()) {
2483 llvm::StringRef pc_str;
2484 std::tie(pc_str, value) = value.split(
',');
2489 }
else if (key.compare(
"jstopinfo") == 0) {
2498 }
else if (key.compare(
"hexname") == 0) {
2502 }
else if (key.compare(
"name") == 0) {
2503 thread_name = std::string(value);
2504 }
else if (key.compare(
"qaddr") == 0) {
2505 value.getAsInteger(
BASE_16, thread_dispatch_qaddr);
2506 }
else if (key.compare(
"dispatch_queue_t") == 0) {
2507 queue_vars_valid =
true;
2508 value.getAsInteger(
BASE_16, dispatch_queue_t);
2509 }
else if (key.compare(
"qname") == 0) {
2510 queue_vars_valid =
true;
2514 }
else if (key.compare(
"qkind") == 0) {
2515 queue_kind = llvm::StringSwitch<QueueKind>(value)
2520 }
else if (key.compare(
"qserialnum") == 0) {
2521 if (!value.getAsInteger(
BASE_10, queue_serial_number))
2522 queue_vars_valid =
true;
2523 }
else if (key.compare(
"reason") == 0) {
2524 reason = std::string(value);
2525 }
else if (key.compare(
"description") == 0) {
2529 }
else if (key.compare(
"memory") == 0) {
2543 llvm::StringRef addr_str, bytes_str;
2544 std::tie(addr_str, bytes_str) = value.split(
'=');
2545 if (!addr_str.empty() && !bytes_str.empty()) {
2552 const size_t bytes_copied =
2554 if (bytes_copied == byte_size)
2558 }
else if (key.compare(
"watch") == 0 || key.compare(
"rwatch") == 0 ||
2559 key.compare(
"awatch") == 0) {
2562 value.getAsInteger(
BASE_16, wp_addr);
2570 reason =
"watchpoint";
2572 ostr.
Printf(
"%" PRIu64, wp_addr);
2573 description = std::string(ostr.
GetString());
2574 }
else if (key.compare(
"swbreak") == 0 || key.compare(
"hwbreak") == 0) {
2575 reason =
"breakpoint";
2576 }
else if (key.compare(
"replaylog") == 0) {
2577 reason =
"history boundary";
2578 }
else if (key.compare(
"library") == 0) {
2584 }
else if (key.compare(
"fork") == 0 || key.compare(
"vfork") == 0) {
2590 LLDB_LOG(log,
"Invalid PID/TID to fork: {0}", value);
2596 ostr.
Printf(
"%" PRIu64
" %" PRIu64, pid_tid->first, pid_tid->second);
2597 description = std::string(ostr.
GetString());
2598 }
else if (key.compare(
"addressing_bits") == 0) {
2599 uint64_t addressing_bits;
2600 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2603 }
else if (key.compare(
"low_mem_addressing_bits") == 0) {
2604 uint64_t addressing_bits;
2605 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2608 }
else if (key.compare(
"high_mem_addressing_bits") == 0) {
2609 uint64_t addressing_bits;
2610 if (!value.getAsInteger(
BASE_10, addressing_bits)) {
2613 }
else if (key ==
"added-binaries") {
2617 while (!value.empty()) {
2618 llvm::StringRef pc_str;
2619 std::tie(pc_str, value) = value.split(
',');
2622 added_binaries.push_back(
pc);
2624 }
else if (key ==
"detailed-binaries-info") {
2632 }
else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
2634 if (!key.getAsInteger(
BASE_16, reg))
2635 expedited_register_map[reg] = std::string(std::move(value));
2645 "Received stop for incorrect PID = {0} (inferior PID = {1})",
2667 tid, expedited_register_map, signo, thread_name, reason, description,
2668 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2669 associated_with_dispatch_queue, dispatch_queue_t, queue_name,
2670 queue_kind, queue_serial_number, added_binaries,
2671 detailed_binaries_info);
2719 if (!selected_thread_sp ||
2720 selected_thread_sp->GetID() != primary_thread_sp->GetID())
2721 m_thread_list.SetSelectedThreadByID(primary_thread_sp->GetID());
2748 LLDB_LOGF(log,
"ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
2752 if (
error.Success())
2754 "ProcessGDBRemote::DoDetach() detach packet sent successfully");
2757 "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
2758 error.AsCString() ?
error.AsCString() :
"<unknown error>");
2761 if (!
error.Success())
2776 LLDB_LOGF(log,
"ProcessGDBRemote::DoDestroy()");
2779 int exit_status = SIGABRT;
2780 std::string exit_string;
2787 exit_status = kill_res.get();
2788#if defined(__APPLE__)
2800 if (platform_sp && platform_sp->IsHost()) {
2803 reap_pid = waitpid(
GetID(), &status, WNOHANG);
2804 LLDB_LOGF(log,
"Reaped pid: %d, status: %d.\n", reap_pid, status);
2808 exit_string.assign(
"killed");
2810 exit_string.assign(llvm::toString(kill_res.takeError()));
2813 exit_string.assign(
"killed or interrupted while attaching.");
2819 exit_string.assign(
"destroying when not connected to debugserver");
2840 const bool did_exec =
2841 response.
GetStringRef().find(
";reason:exec;") != std::string::npos;
2844 LLDB_LOGF(log,
"ProcessGDBRemote::SetLastStopPacket () - detected exec");
2849 m_gdb_comm.ResetDiscoverableSettings(did_exec);
2874 LLDB_LOG_ERROR(log, list.takeError(),
"Failed to read module list: {0}.");
2876 addr = list->m_link_map;
2896 const size_t n = thread_infos->
GetSize();
2897 for (
size_t i = 0; i < n; ++i) {
2914 xPacketState x_state =
m_gdb_comm.GetxPacketState();
2917 size_t max_memory_size = x_state != xPacketState::Unimplemented
2920 if (size > max_memory_size) {
2924 size = max_memory_size;
2929 packet_len = ::snprintf(packet,
sizeof(packet),
"%c%" PRIx64
",%" PRIx64,
2930 x_state != xPacketState::Unimplemented ?
'x' :
'm',
2931 (uint64_t)addr, (uint64_t)size);
2932 assert(packet_len + 1 < (
int)
sizeof(packet));
2935 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
2940 if (x_state != xPacketState::Unimplemented) {
2945 llvm::StringRef data_received = response.
GetStringRef();
2946 if (x_state == xPacketState::Prefixed &&
2947 !data_received.consume_front(
"b")) {
2949 "unexpected response to GDB server memory read packet '{0}': "
2951 packet, data_received);
2956 size_t memcpy_size = std::min(size, data_received.size());
2957 memcpy(buf, data_received.data(), memcpy_size);
2961 llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size),
'\xdd');
2965 "memory read failed for 0x%" PRIx64, addr);
2968 "GDB server does not support reading memory");
2971 "unexpected response to GDB server memory read packet '%s': '%s'",
2983 uint64_t max_packet_size,
2987 constexpr uint64_t range_overhead = 33;
2988 uint64_t current_size = 0;
2989 for (
auto [idx, range] : llvm::enumerate(ranges)) {
2990 uint64_t potential_size = current_size + range.size + range_overhead;
2991 if (potential_size > max_packet_size) {
2994 "MultiMemRead input has a range (base = {0:x}, size = {1}) "
2995 "bigger than the maximum allowed by remote",
2996 range.base, range.size);
3000 return ranges.size();
3003llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>
3006 llvm::MutableArrayRef<uint8_t> buffer) {
3010 const llvm::ArrayRef<Range<lldb::addr_t, size_t>> original_ranges = ranges;
3011 llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> memory_regions;
3013 while (!ranges.empty()) {
3014 uint64_t num_ranges =
3016 if (num_ranges == 0)
3019 auto ranges_for_request = ranges.take_front(num_ranges);
3020 ranges = ranges.drop_front(num_ranges);
3022 llvm::Expected<StringExtractorGDBRemote> response =
3026 "MultiMemRead error response: {0}");
3030 llvm::StringRef response_str = response->GetStringRef();
3031 const unsigned expected_num_ranges = ranges_for_request.size();
3033 response_str, buffer, expected_num_ranges, memory_regions)) {
3035 "MultiMemRead error parsing response: {0}");
3039 return memory_regions;
3042llvm::Expected<StringExtractorGDBRemote>
3045 std::string packet_str;
3046 llvm::raw_string_ostream stream(packet_str);
3047 stream <<
"MultiMemRead:ranges:";
3049 auto range_to_stream = [&](
auto range) {
3051 stream << llvm::formatv(
"{0:x-},{1:x-}", range.base, range.size);
3053 llvm::interleave(ranges, stream, range_to_stream,
",");
3058 m_gdb_comm.SendPacketAndWaitForResponse(packet_str.data(), response,
3061 return llvm::createStringErrorV(
"MultiMemRead failed to send packet: '{0}'",
3065 return llvm::createStringErrorV(
"MultiMemRead failed: '{0}'",
3069 return llvm::createStringErrorV(
"MultiMemRead unexpected response: '{0}'",
3076 llvm::StringRef response_str, llvm::MutableArrayRef<uint8_t> buffer,
3077 unsigned expected_num_ranges,
3080 auto [sizes_str, memory_data] = response_str.split(
';');
3081 if (sizes_str.size() == response_str.size())
3082 return llvm::createStringErrorV(
3083 "MultiMemRead response missing field separator ';' in: '{0}'",
3087 for (llvm::StringRef size_str : llvm::split(sizes_str,
',')) {
3089 if (size_str.getAsInteger(
BASE_16, read_size))
3090 return llvm::createStringErrorV(
3091 "MultiMemRead response has invalid size string: {0}", size_str);
3093 if (memory_data.size() < read_size)
3094 return llvm::createStringErrorV(
"MultiMemRead response did not have "
3095 "enough data, requested sizes: {0}",
3098 llvm::StringRef region_to_read = memory_data.take_front(read_size);
3099 memory_data = memory_data.drop_front(read_size);
3101 assert(buffer.size() >= read_size);
3102 llvm::MutableArrayRef<uint8_t> region_to_write =
3103 buffer.take_front(read_size);
3104 buffer = buffer.drop_front(read_size);
3106 memcpy(region_to_write.data(), region_to_read.data(), read_size);
3107 memory_regions.push_back(region_to_write);
3110 return llvm::Error::success();
3114 return m_gdb_comm.GetMemoryTaggingSupported();
3117llvm::Expected<std::vector<uint8_t>>
3124 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3125 "Error reading memory tags from remote");
3129 llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
3130 std::vector<uint8_t> got;
3131 got.reserve(tag_data.size());
3132 std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
3138 const std::vector<uint8_t> &tags) {
3141 return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
3145 std::vector<ObjectFile::LoadableData> entries) {
3155 if (
error.Success())
3169 for (
size_t i = 0; i < size; ++i)
3194 if (blocksize == 0) {
3202 lldb::addr_t block_start_addr = addr - (addr % blocksize);
3203 size += (addr - block_start_addr);
3204 if ((size % blocksize) != 0)
3205 size += (blocksize - size % blocksize);
3221 auto overlap = last_range.GetRangeEnd() - range.
GetRangeBase();
3242 "flash erase failed for 0x%" PRIx64, addr);
3245 "GDB server does not support flashing");
3248 "unexpected response to GDB server flash erase packet '%s': '%s'",
3265 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"vFlashDone", response,
3275 "GDB server does not support flashing");
3278 "unexpected response to GDB server flash done packet: '%s'",
3293 if (size > max_memory_size) {
3297 size = max_memory_size;
3317 if (!
error.Success())
3319 packet.
Printf(
"vFlashWrite:%" PRIx64
":", addr);
3322 packet.
Printf(
"M%" PRIx64
",%" PRIx64
":", addr, (uint64_t)size);
3335 "memory write failed for 0x%" PRIx64, addr);
3338 "GDB server does not support writing memory");
3341 "unexpected response to GDB server memory write packet '%s': '%s'",
3351 uint32_t permissions,
3357 allocated_addr =
m_gdb_comm.AllocateMemory(size, permissions);
3360 return allocated_addr;
3366 if (permissions & lldb::ePermissionsReadable)
3368 if (permissions & lldb::ePermissionsWritable)
3370 if (permissions & lldb::ePermissionsExecutable)
3379 "ProcessGDBRemote::%s no direct stub support for memory "
3380 "allocation, and InferiorCallMmap also failed - is stub "
3381 "missing register context save/restore capability?",
3388 "unable to allocate %" PRIu64
" bytes of memory with permissions %s",
3392 return allocated_addr;
3407 return m_gdb_comm.GetWatchpointReportedAfter();
3414 switch (supported) {
3419 "tried to deallocate memory without ever allocating memory");
3425 "unable to deallocate memory at 0x%" PRIx64, addr);
3437 "unable to deallocate memory at 0x%" PRIx64, addr);
3470 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3472 if (error_no == 0) {
3475 return llvm::Error::success();
3478 if (error_no != UINT8_MAX)
3479 return llvm::createStringErrorV(
3480 "error sending the breakpoint request: {0}", error_no);
3481 return llvm::createStringError(
"error sending the breakpoint request");
3483 LLDB_LOG(log,
"Software breakpoints are unsupported");
3488 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3490 if (error_no == 0) {
3493 return llvm::Error::success();
3496 if (error_no != UINT8_MAX)
3497 return llvm::createStringErrorV(
3498 "error sending the hardware breakpoint request: {0} "
3499 "(hardware breakpoint resources might be exhausted or unavailable)",
3501 return llvm::createStringError(
3502 "error sending the hardware breakpoint request "
3503 "(hardware breakpoint resources might be exhausted or unavailable)");
3505 LLDB_LOG(log,
"Hardware breakpoints are unsupported");
3509 return llvm::createStringError(
"hardware breakpoints are not supported");
3525 return error.takeError();
3531 return llvm::createStringError(
"unknown error");
3536 return llvm::createStringError(
"unknown error");
3540 return llvm::Error::success();
3544 assert(bp_site !=
nullptr);
3555 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3556 ") address = 0x%" PRIx64,
3557 site_id, (uint64_t)addr);
3562 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3563 ") address = 0x%" PRIx64
" -- SUCCESS (already enabled)",
3564 site_id, (uint64_t)addr);
3572 assert(bp_site !=
nullptr);
3577 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3578 ") addr = 0x%8.8" PRIx64,
3579 site_id, (uint64_t)addr);
3583 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3584 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3585 site_id, (uint64_t)addr);
3596 bool read = wp_res_sp->WatchpointResourceRead();
3597 bool write = wp_res_sp->WatchpointResourceWrite();
3599 assert((read || write) &&
3600 "WatchpointResource type is neither read nor write");
3616 addr_t addr = wp_sp->GetLoadAddress();
3618 LLDB_LOGF(log,
"ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
")",
3620 if (wp_sp->IsEnabled()) {
3622 "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
3623 ") addr = 0x%8.8" PRIx64
": watchpoint already enabled.",
3624 watchID, (uint64_t)addr);
3628 bool read = wp_sp->WatchpointRead();
3629 bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
3630 size_t size = wp_sp->GetByteSize();
3633 WatchpointHardwareFeature supported_features =
3636 std::vector<WatchpointResourceSP> resources =
3638 addr, size, read, write, supported_features, target_arch);
3663 bool set_all_resources =
true;
3664 std::vector<WatchpointResourceSP> succesfully_set_resources;
3665 for (
const auto &wp_res_sp : resources) {
3666 addr_t addr = wp_res_sp->GetLoadAddress();
3667 size_t size = wp_res_sp->GetByteSize();
3669 if (!
m_gdb_comm.SupportsGDBStoppointPacket(type) ||
3670 m_gdb_comm.SendGDBStoppointTypePacket(type,
true, addr, size,
3672 set_all_resources =
false;
3675 succesfully_set_resources.push_back(wp_res_sp);
3678 if (set_all_resources) {
3679 wp_sp->SetEnabled(
true, notify);
3680 for (
const auto &wp_res_sp : resources) {
3683 wp_res_sp->AddConstituent(wp_sp);
3691 for (
const auto &wp_res_sp : succesfully_set_resources) {
3692 addr_t addr = wp_res_sp->GetLoadAddress();
3693 size_t size = wp_res_sp->GetByteSize();
3695 m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3699 "Setting one of the watchpoint resources failed");
3715 addr_t addr = wp_sp->GetLoadAddress();
3718 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3719 ") addr = 0x%8.8" PRIx64,
3720 watchID, (uint64_t)addr);
3722 if (!wp_sp->IsEnabled()) {
3724 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3725 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3726 watchID, (uint64_t)addr);
3730 wp_sp->SetEnabled(
false, notify);
3734 if (wp_sp->IsHardware()) {
3735 bool disabled_all =
true;
3737 std::vector<WatchpointResourceSP> unused_resources;
3739 if (wp_res_sp->ConstituentsContains(wp_sp)) {
3741 addr_t addr = wp_res_sp->GetLoadAddress();
3742 size_t size = wp_res_sp->GetByteSize();
3743 if (
m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3745 disabled_all =
false;
3747 wp_res_sp->RemoveConstituent(wp_sp);
3748 if (wp_res_sp->GetNumberOfConstituents() == 0)
3749 unused_resources.push_back(wp_res_sp);
3753 for (
auto &wp_res_sp : unused_resources)
3756 wp_sp->SetEnabled(
false, notify);
3759 "Failure disabling one of the watchpoint locations");
3772 LLDB_LOGF(log,
"ProcessGDBRemote::DoSignal (signal = %d)", signo);
3787 if (platform_sp && !platform_sp->IsHost())
3792 const char *error_string =
error.AsCString();
3793 if (error_string ==
nullptr)
3802 static FileSpec g_debugserver_file_spec;
3809 std::string env_debugserver_path = host_env.lookup(
"LLDB_DEBUGSERVER_PATH");
3810 if (!env_debugserver_path.empty()) {
3811 debugserver_file_spec.
SetFile(env_debugserver_path,
3812 FileSpec::Style::native);
3813 LLDB_LOG(log,
"gdb-remote stub exe path set from environment variable: {0}",
3814 env_debugserver_path);
3816 debugserver_file_spec = g_debugserver_file_spec;
3818 return debugserver_file_spec;
3821 debugserver_file_spec = HostInfo::GetSupportExeDir();
3822 if (debugserver_file_spec) {
3825 LLDB_LOG(log,
"found gdb-remote stub exe '{0}'", debugserver_file_spec);
3827 g_debugserver_file_spec = debugserver_file_spec;
3830 if (!debugserver_file_spec) {
3833 LLDB_LOG(log,
"could not find gdb-remote stub exe '{0}'",
3834 debugserver_file_spec);
3838 g_debugserver_file_spec.
Clear();
3841 return debugserver_file_spec;
3846 using namespace std::placeholders;
3856 const std::weak_ptr<ProcessGDBRemote> this_wp =
3857 std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3864#if defined(__APPLE__)
3868 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
3870 struct kinfo_proc processInfo;
3871 size_t bufsize =
sizeof(processInfo);
3872 if (sysctl(mib, (
unsigned)(
sizeof(mib) /
sizeof(
int)), &processInfo, &bufsize,
3875 if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
3876 debugserver_path =
FileSpec(
"/Library/Apple/usr/libexec/oah/debugserver");
3883 "'. Please ensure it is properly installed "
3884 "and available in your PATH");
3899 debugserver_launch_info,
nullptr);
3904 LLDB_LOGF(log,
"failed to start debugserver process: %s",
3914 m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>(
3915 std::move(socket_pair->second)));
3929 std::weak_ptr<ProcessGDBRemote> process_wp,
lldb::pid_t debugserver_pid,
3938 "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
3939 ", signo=%i (0x%x), exit_status=%i)",
3940 __FUNCTION__, debugserver_pid, signo, signo, exit_status);
3942 std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
3943 LLDB_LOGF(log,
"ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
3944 static_cast<void *
>(process_sp.get()));
3945 if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
3951 std::this_thread::sleep_for(std::chrono::milliseconds(500));
3955 const StateType state = process_sp->GetState();
3964 llvm::StringRef signal_name =
3965 process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);
3967 if (!signal_name.empty())
3968 stream.
Format(format_str, signal_name);
3970 stream.
Format(format_str, signo);
3972 process_sp->SetExitStatus(-1, stream.
GetString());
3995 debugger, PluginProperties::GetSettingName())) {
3996 const bool is_global_setting =
true;
3999 "Properties for the gdb-remote process plug-in.", is_global_setting);
4006 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
4013 llvm::Expected<HostThread> async_thread =
4017 if (!async_thread) {
4019 "failed to launch host thread: {0}");
4025 "ProcessGDBRemote::%s () - Called when Async thread was "
4035 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
4050 "ProcessGDBRemote::%s () - Called when Async thread was not running.",
4056 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread starting...",
4057 __FUNCTION__,
GetID());
4075 "ProcessGDBRemote::%s(pid = %" PRIu64
4076 ") listener.WaitForEvent (NULL, event_sp)...",
4077 __FUNCTION__,
GetID());
4080 const uint32_t event_type = event_sp->GetType();
4083 "ProcessGDBRemote::%s(pid = %" PRIu64
4084 ") Got an event of type: %d...",
4085 __FUNCTION__,
GetID(), event_type);
4087 switch (event_type) {
4092 if (continue_packet) {
4093 const char *continue_cstr =
4094 (
const char *)continue_packet->
GetBytes();
4095 const size_t continue_cstr_len = continue_packet->
GetByteSize();
4097 "ProcessGDBRemote::%s(pid = %" PRIu64
4098 ") got eBroadcastBitAsyncContinue: %s",
4099 __FUNCTION__,
GetID(), continue_cstr);
4101 if (::strstr(continue_cstr,
"vAttach") ==
nullptr)
4108 llvm::StringRef(continue_cstr, continue_cstr_len),
4119 switch (stop_state) {
4132 int exit_status = response.
GetHexU8();
4133 std::string desc_string;
4135 llvm::StringRef desc_str;
4136 llvm::StringRef desc_token;
4138 if (desc_token !=
"description")
4153 if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4156 "System Integrity Protection");
4157 }
else if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4177 "ProcessGDBRemote::%s(pid = %" PRIu64
4178 ") got eBroadcastBitAsyncThreadShouldExit...",
4179 __FUNCTION__,
GetID());
4185 "ProcessGDBRemote::%s(pid = %" PRIu64
4186 ") got unknown event 0x%8.8x",
4187 __FUNCTION__,
GetID(), event_type);
4194 "ProcessGDBRemote::%s(pid = %" PRIu64
4195 ") listener.WaitForEvent (NULL, event_sp) => false",
4196 __FUNCTION__,
GetID());
4201 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread exiting...",
4202 __FUNCTION__,
GetID());
4234 LLDB_LOGF(log,
"Hit New Thread Notification breakpoint.");
4241class AcceleratorBreakpointCallbackBaton
4242 :
public TypedBaton<AcceleratorBreakpointHitArgs> {
4244 explicit AcceleratorBreakpointCallbackBaton(
4245 std::unique_ptr<AcceleratorBreakpointHitArgs> data)
4264 "ProcessGDBRemote::HandleAcceleratorActions skipping already "
4265 "processed actions for plugin '{0}' with identifier {1}",
4267 return llvm::Error::success();
4284 return llvm::Error::success();
4294 std::string exe_path = connect_info.
exe_path.value_or(
"");
4298 &platform_options, accelerator_target_sp);
4300 return error.takeError();
4301 if (!accelerator_target_sp)
4302 return llvm::createStringError(
"failed to create accelerator target");
4304 PlatformSP platform_sp = accelerator_target_sp->GetPlatform();
4306 return llvm::createStringErrorV(
4307 "no platform '{0}' compatible with triple '{1}' for the accelerator "
4312 ? platform_sp->ConnectProcessSynchronous(
4316 : platform_sp->ConnectProcess(connect_info.
connect_url,
4318 accelerator_target_sp.get(),
error);
4320 return error.takeError();
4322 return llvm::createStringError(
"failed to connect to the accelerator");
4324 accelerator_target_sp->SetTargetSessionName(actions.
session_name);
4327 auto event_sp = std::make_shared<Event>(
4330 accelerator_target_sp));
4332 return llvm::Error::success();
4338 llvm::Error
error = llvm::Error::success();
4342 auto args_up = std::make_unique<AcceleratorBreakpointHitArgs>();
4344 args_up->breakpoint = bp;
4351 error = llvm::joinErrors(
4353 llvm::createStringErrorV(
4354 "accelerator breakpoint {0} specifies both a by_name and a "
4355 "by_address specification",
4363 bp_modules.
GetSize() ? &bp_modules :
nullptr,
4365 bp.
by_name->function_name.c_str(),
4366 eFunctionNameTypeFull,
4378 error = llvm::joinErrors(
4380 llvm::createStringErrorV(
4381 "accelerator breakpoint {0} has neither a by_name nor a "
4382 "by_address specification",
4388 error = llvm::joinErrors(
4390 llvm::createStringErrorV(
"failed to set accelerator breakpoint {0}",
4398 llvm::formatv(
"accelerator-plugin ({0})", actions.
plugin_name);
4399 bp_sp->SetBreakpointKind(kind.c_str());
4400 auto baton_sp = std::make_shared<AcceleratorBreakpointCallbackBaton>(
4401 std::move(args_up));
4429 for (
size_t i = 0; i < symbol_names.size(); ++i) {
4437 addr_t load_addr = sc.symbol->GetAddress().GetLoadAddress(&target);
4446 llvm::Expected<AcceleratorBreakpointHitResponse> response =
4450 "accelerator breakpoint hit notification failed: {0}");
4458 if (response->disable_bp) {
4460 bp_sp->SetEnabled(
false);
4465 if (response->actions) {
4469 std::string message = llvm::toString(std::move(
error));
4470 LLDB_LOG(log,
"failed to handle accelerator actions: {0}", message);
4472 "error: accelerator plugin '%s': %s\n",
4473 response->actions->plugin_name.c_str(), message.c_str());
4478 return !response->auto_resume_native;
4483 LLDB_LOG(log,
"Check if need to update ignored signals");
4497 LLDB_LOG(log,
"Signals' version hasn't changed. version={0}",
4502 auto signals_to_ignore =
4507 "Signals' version changed. old version={0}, new version={1}, "
4508 "signals ignored={2}, update result={3}",
4510 signals_to_ignore.size(),
error);
4512 if (
error.Success())
4527 platform_sp->SetThreadCreationBreakpoint(
GetTarget());
4530 log,
"Successfully created new thread notification breakpoint %i",
4535 LLDB_LOGF(log,
"Failed to create new thread notification breakpoint.");
4564 return_value =
m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
4565 if (return_value != 0) {
4568 "Sending events is not supported for this process.");
4578 if (
m_gdb_comm.GetQXferAuxvReadSupported()) {
4579 llvm::Expected<std::string> response =
m_gdb_comm.ReadExtFeature(
"auxv",
"");
4581 buf = std::make_shared<DataBufferHeap>(response->c_str(),
4582 response->length());
4593 if (
m_gdb_comm.GetThreadExtendedInfoSupported()) {
4599 args_dict->GetAsDictionary()->AddIntegerItem(
"thread", tid);
4602 packet <<
"jThreadExtendedInfo:";
4603 args_dict->Dump(packet,
false);
4610 packet << (char)(0x7d ^ 0x20);
4619 if (!response.
Empty()) {
4632 args_dict->GetAsDictionary()->AddIntegerItem(
"image_list_address",
4633 image_list_address);
4634 args_dict->GetAsDictionary()->AddIntegerItem(
"image_count", image_count);
4641 std::string info_level_str;
4643 info_level_str =
"address-only";
4645 info_level_str =
"address-name";
4647 info_level_str =
"address-name-uuid";
4649 info_level_str =
"full";
4651 return info_level_str;
4658 args_dict->GetAsDictionary()->AddBooleanItem(
"fetch_all_solibs",
true);
4660 args_dict->GetAsDictionary()->AddBooleanItem(
"report_load_commands",
false);
4662 if (!info_level_str.empty())
4663 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4664 info_level_str.c_str());
4671 const std::vector<lldb::addr_t> &load_addresses) {
4675 for (
auto addr : load_addresses)
4676 addresses->AddIntegerItem(addr);
4678 args_dict->GetAsDictionary()->AddItem(
"solib_addresses", addresses);
4681 if (!info_level_str.empty())
4682 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4683 info_level_str.c_str());
4693 if (
m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
4696 std::chrono::seconds(10));
4699 packet <<
"jGetLoadedDynamicLibrariesInfos:";
4700 args_dict->Dump(packet,
false);
4707 packet << (char)(0x7d ^ 0x20);
4716 if (!response.
Empty()) {
4729 if (
m_gdb_comm.GetDynamicLoaderProcessStateSupported()) {
4732 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"jGetDyldProcessState",
4738 if (!response.
Empty()) {
4755 packet <<
"jGetSharedCacheInfo:";
4756 args_dict->Dump(packet,
false);
4765 if (response.
Empty())
4774 if (!dict->
HasKey(
"shared_cache_uuid"))
4776 llvm::StringRef uuid_str;
4778 uuid_str ==
"00000000-0000-0000-0000-000000000000")
4780 if (dict->
HasKey(
"shared_cache_path")) {
4794 HostInfo::SharedCacheIndexFiles(sc_path, uuid, sc_mode);
4805 return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
4818 const uint64_t reasonable_largeish_default = 128 * 1024;
4819 const uint64_t conservative_default = 512;
4822 uint64_t stub_max_size =
m_gdb_comm.GetRemoteMaxPacketSize();
4823 if (stub_max_size !=
UINT64_MAX && stub_max_size != 0) {
4829 if (stub_max_size > reasonable_largeish_default) {
4830 stub_max_size = reasonable_largeish_default;
4836 if (stub_max_size > 70)
4837 stub_max_size -= 32 + 32 + 6;
4842 LLDB_LOG(log,
"warning: Packet size is too small. "
4843 "LLDB may face problems while writing memory");
4854 uint64_t user_specified_max) {
4855 if (user_specified_max != 0) {
4883 module_spec = cached->second;
4884 return bool(module_spec);
4887 if (!
m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
4888 LLDB_LOGF(log,
"ProcessGDBRemote::%s - failed to get module info for %s:%s",
4889 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4896 module_spec.
Dump(stream);
4897 LLDB_LOGF(log,
"ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
4898 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4907 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4908 auto module_specs =
m_gdb_comm.GetModulesInfo(module_file_specs, triple);
4910 for (
const FileSpec &spec : module_file_specs)
4915 triple.getTriple())] = spec;
4929typedef std::vector<std::string> stringVec;
4931typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
4932struct RegisterSetInfo {
4936typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
4938struct GdbServerTargetInfo {
4942 RegisterSetMap reg_set_map;
4945using RegisterTypeMap = llvm::StringMap<const RegisterType *>;
4948ParseEnumEvalues(
const XMLNode &enum_node) {
4962 std::map<uint64_t, RegisterTypeEnum::Enumerator> enumerators;
4965 "evalue", [&enumerators, &log](
const XMLNode &enumerator_node) {
4966 std::optional<llvm::StringRef> name;
4967 std::optional<uint64_t> value;
4970 [&name, &value, &log](
const llvm::StringRef &attr_name,
4971 const llvm::StringRef &attr_value) {
4972 if (attr_name ==
"name") {
4973 if (attr_value.size())
4976 LLDB_LOG(log,
"ProcessGDBRemote::ParseEnumEvalues "
4977 "Ignoring empty name in evalue");
4978 }
else if (attr_name ==
"value") {
4979 uint64_t parsed_value = 0;
4980 if (llvm::to_integer(attr_value, parsed_value))
4981 value = parsed_value;
4984 "ProcessGDBRemote::ParseEnumEvalues "
4985 "Invalid value \"{0}\" in "
4990 "ProcessGDBRemote::ParseEnumEvalues Ignoring "
4991 "unknown attribute "
4992 "\"{0}\" in evalue",
5000 enumerators.insert_or_assign(
5001 *value, RegisterTypeEnum::Enumerator(*value, name->str()));
5008 for (
auto [_, enumerator] : enumerators)
5009 final_enumerators.push_back(enumerator);
5011 return final_enumerators;
5015ParseEnums(XMLNode feature_node, RegisterTypeMap &feature_register_types,
5016 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5021 "enum", [log, &feature_register_types,
5022 &owned_register_types](
const XMLNode &enum_node) {
5026 const llvm::StringRef &attr_value) {
5027 if (attr_name ==
"id")
5045 ParseEnumEvalues(enum_node);
5046 if (!enumerators.empty()) {
5048 "ProcessGDBRemote::ParseEnums Found enum type \"{0}\"",
5051 std::make_unique<RegisterTypeEnum>(
id, enumerators);
5052 const RegisterTypeEnum *enum_type_ptr = enum_type.get();
5053 auto [it, inserted] =
5054 feature_register_types.try_emplace(
id, enum_type_ptr);
5056 owned_register_types.push_back(std::move(enum_type));
5057 }
else if (llvm::isa<RegisterTypeEnum>(it->second)) {
5062 owned_register_types.push_back(std::move(enum_type));
5063 it->second = enum_type_ptr;
5067 "ProcessGDBRemote::ParseEnums Ignoring enum type \"{0}\" "
5068 "because another type with that id already exists",
5079static std::vector<RegisterTypeFlags::Field>
5080ParseFlagsFields(XMLNode flags_node,
unsigned size,
5081 const RegisterTypeMap &feature_register_types) {
5083 const unsigned max_start_bit = size * 8 - 1;
5086 std::vector<RegisterTypeFlags::Field> fields;
5088 &feature_register_types](
5091 std::optional<llvm::StringRef> name;
5092 std::optional<unsigned> start;
5093 std::optional<unsigned> end;
5094 std::optional<llvm::StringRef> type;
5097 &log](
const llvm::StringRef &attr_name,
5098 const llvm::StringRef &attr_value) {
5101 if (attr_name ==
"name") {
5104 "ProcessGDBRemote::ParseFlagsFields Found field node name \"{0}\"",
5107 }
else if (attr_name ==
"start") {
5108 unsigned parsed_start = 0;
5109 if (llvm::to_integer(attr_value, parsed_start)) {
5110 if (parsed_start > max_start_bit) {
5112 "ProcessGDBRemote::ParseFlagsFields Invalid start {0} in "
5115 parsed_start, max_start_bit);
5117 start = parsed_start;
5121 "ProcessGDBRemote::ParseFlagsFields Invalid start \"{0}\" in "
5125 }
else if (attr_name ==
"end") {
5126 unsigned parsed_end = 0;
5127 if (llvm::to_integer(attr_value, parsed_end))
5128 if (parsed_end > max_start_bit) {
5130 "ProcessGDBRemote::ParseFlagsFields Invalid end {0} in "
5133 parsed_end, max_start_bit);
5138 "ProcessGDBRemote::ParseFlagsFields Invalid end \"{0}\" in "
5142 }
else if (attr_name ==
"type") {
5147 "ProcessGDBRemote::ParseFlagsFields Ignoring unknown attribute "
5148 "\"{0}\" in field node",
5155 if (name && start && end) {
5159 "ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
5160 "\"{2}\", ignoring",
5161 *start, *end, name->data());
5165 "ProcessGDBRemote::ParseFlagsFields Ignoring field \"{}\" "
5166 "that has size > 64 bits, this is not supported",
5170 const RegisterTypeEnum *enum_type =
nullptr;
5171 if (type && !type->empty()) {
5172 auto found = feature_register_types.find(*type);
5173 if (found != feature_register_types.end()) {
5174 enum_type = llvm::dyn_cast<RegisterTypeEnum>(found->second);
5178 "ProcessGDBRemote::ParseFlagsFields Type \"{0}\" for "
5179 "field \"{1}\" is not an enum, ignoring",
5180 type->data(), name->data());
5185 uint64_t max_value =
5188 if (enumerator.m_value > max_value) {
5189 enum_type =
nullptr;
5192 "ProcessGDBRemote::ParseFlagsFields In enum \"{0}\" "
5193 "evalue \"{1}\" with value {2} exceeds the maximum "
5194 "value of field \"{3}\" ({4}), ignoring enum",
5195 type->data(), enumerator.m_name, enumerator.m_value,
5196 name->data(), max_value);
5203 "ProcessGDBRemote::ParseFlagsFields Could not find type "
5205 "for field \"{1}\", ignoring",
5206 type->data(), name->data());
5211 RegisterTypeFlags::Field(name->str(), *start, *end, enum_type));
5222 XMLNode feature_node, RegisterTypeMap &feature_register_types,
5223 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5228 [&log, &feature_register_types,
5229 &owned_register_types](
const XMLNode &flags_node) ->
bool {
5230 LLDB_LOG(log,
"ProcessGDBRemote::ParseFlags Found flags node \"{0}\"",
5233 std::optional<llvm::StringRef>
id;
5234 std::optional<unsigned> size;
5236 [&
id, &size, &log](
const llvm::StringRef &name,
5237 const llvm::StringRef &value) {
5240 }
else if (name ==
"size") {
5241 unsigned parsed_size = 0;
5242 if (llvm::to_integer(value, parsed_size))
5246 "ProcessGDBRemote::ParseFlags Invalid size \"{0}\" "
5252 "ProcessGDBRemote::ParseFlags Ignoring unknown "
5253 "attribute \"{0}\" in flags node",
5261 std::vector<RegisterTypeFlags::Field> fields =
5262 ParseFlagsFields(flags_node, *size, feature_register_types);
5263 if (fields.size()) {
5265 std::sort(fields.rbegin(), fields.rend());
5266 std::vector<RegisterTypeFlags::Field>::const_iterator overlap =
5267 std::adjacent_find(fields.begin(), fields.end(),
5268 [](
const RegisterTypeFlags::Field &lhs,
5269 const RegisterTypeFlags::Field &rhs) {
5270 return lhs.Overlaps(rhs);
5274 if (overlap == fields.end()) {
5275 if (feature_register_types.contains(*
id)) {
5280 "ProcessGDBRemote::ParseFlags Definition of flags \"{0}\" "
5281 "conflicts with an existing type, ignoring this "
5285 auto flags_type = std::make_unique<RegisterTypeFlags>(
5286 id->str(), *size, std::move(fields));
5287 feature_register_types.try_emplace(*
id, flags_type.get());
5288 owned_register_types.push_back(std::move(flags_type));
5292 std::vector<RegisterTypeFlags::Field>::const_iterator next =
5296 "ProcessGDBRemote::ParseFlags Ignoring flags because fields "
5297 "{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) "
5299 overlap->GetName().c_str(), overlap->GetStart(),
5300 overlap->GetEnd(), next->GetName().c_str(), next->GetStart(),
5306 "ProcessGDBRemote::ParseFlags Ignoring definition of flags "
5307 "\"{0}\" because it contains no fields.",
5317 XMLNode feature_node, GdbServerTargetInfo &target_info,
5318 std::vector<DynamicRegisterInfo::Register> ®isters,
5319 std::vector<std::unique_ptr<RegisterType>> &owned_register_types) {
5324 RegisterTypeMap feature_register_types;
5327 ParseEnums(feature_node, feature_register_types, owned_register_types);
5328 for (
const auto ®ister_type : feature_register_types)
5329 if (
const auto *enum_type =
5330 llvm::dyn_cast<RegisterTypeEnum>(register_type.second))
5333 ParseFlags(feature_node, feature_register_types, owned_register_types);
5334 for (
const auto ®ister_type : feature_register_types)
5335 if (
const auto *flags_type =
5336 llvm::dyn_cast<RegisterTypeFlags>(register_type.second))
5337 flags_type->DumpToLog(log);
5341 [&target_info, ®isters, &feature_register_types,
5342 log](
const XMLNode ®_node) ->
bool {
5343 std::string gdb_group;
5344 std::string gdb_type;
5345 DynamicRegisterInfo::Register reg_info;
5346 bool encoding_set =
false;
5347 bool format_set =
false;
5351 &encoding_set, &format_set, ®_info,
5352 log](
const llvm::StringRef &name,
5353 const llvm::StringRef &value) ->
bool {
5354 if (name ==
"name") {
5356 }
else if (name ==
"bitsize") {
5357 if (llvm::to_integer(value, reg_info.
byte_size))
5359 llvm::divideCeil(reg_info.
byte_size, CHAR_BIT);
5360 }
else if (name ==
"type") {
5361 gdb_type = value.str();
5362 }
else if (name ==
"group") {
5363 gdb_group = value.str();
5364 }
else if (name ==
"regnum") {
5366 }
else if (name ==
"offset") {
5368 }
else if (name ==
"altname") {
5370 }
else if (name ==
"encoding") {
5371 encoding_set =
true;
5373 }
else if (name ==
"format") {
5379 llvm::StringSwitch<lldb::Format>(value)
5390 }
else if (name ==
"group_id") {
5392 llvm::to_integer(value, set_id);
5393 RegisterSetMap::const_iterator pos =
5394 target_info.reg_set_map.find(set_id);
5395 if (pos != target_info.reg_set_map.end())
5396 reg_info.
set_name = pos->second.name;
5397 }
else if (name ==
"gcc_regnum" || name ==
"ehframe_regnum") {
5399 }
else if (name ==
"dwarf_regnum") {
5401 }
else if (name ==
"generic") {
5403 }
else if (name ==
"value_regnums") {
5406 }
else if (name ==
"invalidate_regnums") {
5411 "ProcessGDBRemote::ParseRegisters unhandled reg "
5412 "attribute %s = %s",
5413 name.data(), value.data());
5418 if (!gdb_type.empty()) {
5420 auto it = feature_register_types.find(gdb_type);
5421 if (it != feature_register_types.end()) {
5422 if (
const auto *flags_type =
5423 llvm::dyn_cast<RegisterTypeFlags>(it->second)) {
5424 if (reg_info.
byte_size == flags_type->GetSize())
5429 "ProcessGDBRemote::ParseRegisters Size of register flags "
5430 "{0} ({1} bytes) for register {2} does not match the "
5431 "register size ({3} bytes). Ignoring this set of flags.",
5432 flags_type->GetID().c_str(), flags_type->GetSize(),
5440 if (!gdb_type.empty() && !(encoding_set || format_set)) {
5441 if (llvm::StringRef(gdb_type).starts_with(
"int")) {
5444 }
else if (gdb_type ==
"data_ptr" || gdb_type ==
"code_ptr") {
5447 }
else if (gdb_type ==
"float" || gdb_type ==
"ieee_single" ||
5448 gdb_type ==
"ieee_double") {
5451 }
else if (gdb_type ==
"aarch64v" ||
5452 llvm::StringRef(gdb_type).starts_with(
"vec") ||
5453 gdb_type ==
"i387_ext" || gdb_type ==
"uint128" ||
5466 "ProcessGDBRemote::ParseRegisters Could not determine lldb"
5467 "format and encoding for gdb type %s",
5477 if (!gdb_group.empty()) {
5488 "ProcessGDBRemote::{0} Skipping zero bitsize register {1}",
5489 __FUNCTION__, reg_info.
name);
5491 registers.push_back(reg_info);
5506 ArchSpec &arch_to_use, std::string xml_filename,
5507 std::vector<DynamicRegisterInfo::Register> ®isters) {
5509 llvm::Expected<std::string> raw =
m_gdb_comm.ReadExtFeature(
"features", xml_filename);
5510 if (errorToBool(raw.takeError()))
5515 if (xml_document.
ParseMemory(raw->c_str(), raw->size(),
5516 xml_filename.c_str())) {
5517 GdbServerTargetInfo target_info;
5518 std::vector<XMLNode> feature_nodes;
5524 const XMLNode &node) ->
bool {
5525 llvm::StringRef name = node.
GetName();
5526 if (name ==
"architecture") {
5528 }
else if (name ==
"osabi") {
5530 }
else if (name ==
"xi:include" || name ==
"include") {
5533 target_info.includes.push_back(href);
5534 }
else if (name ==
"feature") {
5535 feature_nodes.push_back(node);
5536 }
else if (name ==
"groups") {
5538 "group", [&target_info](
const XMLNode &node) ->
bool {
5540 RegisterSetInfo set_info;
5543 [&set_id, &set_info](
const llvm::StringRef &name,
5544 const llvm::StringRef &value) ->
bool {
5547 llvm::to_integer(value, set_id);
5554 target_info.reg_set_map[set_id] = set_info;
5567 feature_nodes.push_back(feature_node);
5569 const XMLNode &node) ->
bool {
5570 llvm::StringRef name = node.
GetName();
5571 if (name ==
"xi:include" || name ==
"include") {
5574 target_info.includes.push_back(href);
5588 if (!arch_to_use.
IsValid() && !target_info.arch.empty()) {
5590 arch_to_use.
SetTriple(llvm::StringSwitch<std::string>(target_info.arch)
5591 .Case(
"i386:x86-64",
"x86_64")
5592 .Case(
"riscv:rv64",
"riscv64")
5593 .Case(
"riscv:rv32",
"riscv32")
5594 .Default(target_info.arch) +
5602 for (
auto &feature_node : feature_nodes) {
5606 for (
const auto &include : target_info.includes) {
5618 std::vector<DynamicRegisterInfo::Register> ®isters,
5620 std::map<uint32_t, uint32_t> remote_to_local_map;
5621 uint32_t remote_regnum = 0;
5622 for (
auto it : llvm::enumerate(registers)) {
5630 remote_to_local_map[remote_reg_info.
regnum_remote] = it.index();
5636 auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) {
5637 auto lldb_regit = remote_to_local_map.find(process_regnum);
5638 return lldb_regit != remote_to_local_map.end() ? lldb_regit->second
5642 llvm::transform(remote_reg_info.value_regs,
5643 remote_reg_info.value_regs.begin(), proc_to_lldb);
5644 llvm::transform(remote_reg_info.invalidate_regs,
5645 remote_reg_info.invalidate_regs.begin(), proc_to_lldb);
5652 abi_sp->AugmentRegisterInfo(registers);
5662 if (!
m_gdb_comm.GetQXferFeaturesReadSupported())
5663 return llvm::createStringError(
5664 llvm::inconvertibleErrorCode(),
5665 "the debug server does not support \"qXfer:features:read\"");
5668 return llvm::createStringError(
5669 llvm::inconvertibleErrorCode(),
5670 "the debug server supports \"qXfer:features:read\", but LLDB does not "
5671 "have XML parsing enabled (check LLLDB_ENABLE_LIBXML2)");
5673 std::vector<DynamicRegisterInfo::Register> registers;
5681 ? llvm::ErrorSuccess()
5682 : llvm::createStringError(
5683 llvm::inconvertibleErrorCode(),
5684 "the debug server did not describe any registers");
5690 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5691 "XML parsing not available");
5694 LLDB_LOGF(log,
"ProcessGDBRemote::%s", __FUNCTION__);
5703 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries-svr4",
"");
5705 return raw.takeError();
5708 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5711 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5712 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5713 "Error reading noname.xml");
5717 return llvm::createStringError(
5718 llvm::inconvertibleErrorCode(),
5719 "Error finding library-list-svr4 xml element");
5724 if (!main_lm.empty())
5728 "library", [log, &list](
const XMLNode &library) ->
bool {
5733 [&module](
const llvm::StringRef &name,
5734 const llvm::StringRef &value) ->
bool {
5737 module.set_name(value.str());
5738 else if (name ==
"lm") {
5740 llvm::to_integer(value, uint_value);
5741 module.set_link_map(uint_value);
5742 }
else if (name ==
"l_addr") {
5745 llvm::to_integer(value, uint_value);
5746 module.set_base(uint_value);
5749 module.set_base_is_offset(true);
5750 }
else if (name ==
"l_ld") {
5752 llvm::to_integer(value, uint_value);
5753 module.set_dynamic(uint_value);
5762 bool base_is_offset;
5764 module.get_name(name);
5765 module.get_link_map(lm);
5766 module.get_base(base);
5767 module.get_base_is_offset(base_is_offset);
5768 module.get_dynamic(ld);
5771 "found (link_map:0x%08" PRIx64
", base:0x%08" PRIx64
5772 "[%s], ld:0x%08" PRIx64
", name:'%s')",
5773 lm, base, (base_is_offset ?
"offset" :
"absolute"), ld,
5782 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5783 (
int)list.
m_list.size());
5787 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries",
"");
5790 return raw.takeError();
5792 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5795 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5796 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5797 "Error reading noname.xml");
5801 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5802 "Error finding library-list xml element");
5806 "library", [log, &list](
const XMLNode &library) ->
bool {
5810 module.set_name(name);
5819 llvm::to_integer(address, address_value);
5820 module.set_base(address_value);
5822 module.set_base_is_offset(false);
5827 bool base_is_offset;
5828 module.get_name(name);
5829 module.get_base(base);
5830 module.get_base_is_offset(base_is_offset);
5832 LLDB_LOGF(log,
"found (base:0x%08" PRIx64
"[%s], name:'%s')", base,
5833 (base_is_offset ?
"offset" :
"absolute"), name.c_str());
5841 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5842 (
int)list.
m_list.size());
5845 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5846 "Remote libraries not supported");
5853 bool value_is_offset) {
5868 return module_list.takeError();
5874 std::string mod_name;
5877 bool mod_base_is_offset;
5880 valid &= modInfo.
get_name(mod_name);
5881 valid &= modInfo.
get_base(mod_base);
5894 if (module_sp.get())
5895 new_modules.
Append(module_sp);
5898 if (new_modules.
GetSize() > 0) {
5903 for (
size_t i = 0; i < loaded_modules.
GetSize(); ++i) {
5907 for (
size_t j = 0; j < new_modules.
GetSize(); ++j) {
5916 removed_modules.
Append(loaded_module);
5920 loaded_modules.
Remove(removed_modules);
5921 m_process->GetTarget().ModulesDidUnload(removed_modules,
false);
5940 m_process->GetTarget().ModulesDidLoad(new_modules);
5943 return llvm::ErrorSuccess();
5952 std::string file_path = file.
GetPath(
false);
5953 if (file_path.empty())
5974 "Fetching file load address from remote server returned an error");
5984 "Unknown error happened during sending the load address packet");
6005 std::string input = data.str();
6012 size_t found, pos = 0, len = input.length();
6013 while ((found = input.find(
end_delimiter, pos)) != std::string::npos) {
6015 input.substr(pos, found).c_str());
6016 std::string profile_data =
6031 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
6033 llvm::raw_string_ostream output_stream(output);
6034 llvm::StringRef name, value;
6038 if (name.compare(
"thread_used_id") == 0) {
6040 uint64_t thread_id = threadIDHexExtractor.
GetHexMaxU64(
false, 0);
6042 bool has_used_usec =
false;
6043 uint32_t curr_used_usec = 0;
6044 llvm::StringRef usec_name, usec_value;
6045 uint32_t input_file_pos = profileDataExtractor.
GetFilePos();
6047 if (usec_name ==
"thread_used_usec") {
6048 has_used_usec =
true;
6049 usec_value.getAsInteger(
BASE_10, curr_used_usec);
6053 profileDataExtractor.
SetFilePos(input_file_pos);
6057 if (has_used_usec) {
6058 uint32_t prev_used_usec = 0;
6059 std::map<uint64_t, uint32_t>::iterator iterator =
6062 prev_used_usec = iterator->second;
6064 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
6066 bool good_first_time =
6067 (prev_used_usec == 0) && (real_used_usec > 250000);
6068 bool good_subsequent_time =
6069 (prev_used_usec > 0) &&
6072 if (good_first_time || good_subsequent_time) {
6076 output_stream << name <<
":";
6078 output_stream << index_id <<
";";
6080 output_stream << usec_name <<
":" << usec_value <<
";";
6083 llvm::StringRef local_name, local_value;
6089 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
6092 output_stream << name <<
":" << value <<
";";
6095 output_stream << name <<
":" << value <<
";";
6130 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6131 "qSaveCore returned an error");
6136 for (
auto x : llvm::split(response.
GetStringRef(),
';')) {
6137 if (x.consume_front(
"core-path:"))
6143 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6144 "qSaveCore returned no core path");
6147 FileSpec remote_core{llvm::StringRef(path)};
6153 platform.
Unlink(remote_core);
6155 return error.ToError();
6161 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6162 "Unable to send qSaveCore");
6174 "GDBRemoteCommunicationClientBase::%s() received $J packet "
6175 "but was not a StructuredData packet: packet starts with "
6187 json_sp->Dump(json_str,
true);
6190 "ProcessGDBRemote::%s() "
6191 "received Async StructuredData packet: %s",
6192 __FUNCTION__, json_str.
GetData());
6195 "ProcessGDBRemote::%s"
6196 "() received StructuredData packet:"
6206 if (structured_data_sp)
6214 "Tests packet speeds of various sizes to determine "
6215 "the performance characteristics of the GDB remote "
6220 "The number of packets to send of each varying size "
6221 "(default is 1000).",
6224 "The maximum number of bytes to send in a packet. Sizes "
6225 "increase in powers of 2 while the size is less than or "
6226 "equal to this option value. (default 1024).",
6229 "The maximum number of bytes to receive in a packet. Sizes "
6230 "increase in powers of 2 while the size is less than or "
6231 "equal to this option value. (default 1024).",
6234 "Print the output as JSON data for easy parsing.", false, true) {
6254 if (!output_stream_sp)
6255 output_stream_sp =
m_interpreter.GetDebugger().GetAsyncOutputStream();
6258 const uint32_t num_packets =
6260 const uint64_t max_send =
m_max_send.GetOptionValue().GetCurrentValue();
6261 const uint64_t max_recv =
m_max_recv.GetOptionValue().GetCurrentValue();
6262 const bool json =
m_json.GetOptionValue().GetCurrentValue();
6263 const uint64_t k_recv_amount =
6266 num_packets, max_send, max_recv, k_recv_amount, json,
6291 "Dumps the packet history buffer. ", nullptr) {}
6312 interpreter,
"process plugin packet xfer-size",
6313 "Maximum size that lldb will try to read/write one one chunk.",
6324 "amount to be transferred when "
6335 uint64_t user_specified_max = strtoul(packet_size,
nullptr, 10);
6336 if (errno == 0 && user_specified_max != 0) {
6351 "Send a custom packet through the GDB remote "
6352 "protocol and print the answer. "
6353 "The packet header and footer will automatically "
6354 "be added to the packet prior to sending and "
6355 "stripped from the result.",
6366 "'%s' takes a one or more packet content arguments",
6374 for (
size_t i = 0; i < argc; ++i) {
6381 output_strm.
Printf(
" packet: %s\n", packet_cstr);
6382 std::string response_str = std::string(response.
GetStringRef());
6384 if (strstr(packet_cstr,
"qGetProfileData") !=
nullptr) {
6388 if (response_str.empty())
6389 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6402 "Send a qRcmd packet through the GDB remote protocol "
6403 "and print the response. "
6404 "The argument passed to this command will be hex "
6405 "encoded into a valid 'qRcmd' packet, sent and the "
6406 "response will be printed.") {}
6412 if (command.empty()) {
6429 [&output_strm](llvm::StringRef output) { output_strm << output; });
6432 const std::string &response_str = std::string(response.
GetStringRef());
6434 if (response_str.empty())
6435 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6447 "Commands that deal with GDB remote packets.",
6476 interpreter,
"process plugin",
6477 "Commands for operating on a ProcessGDBRemote process.",
6478 "process plugin <subcommand> [<subcommand-options>]") {
6489 m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(
6490 GetTarget().GetDebugger().GetCommandInterpreter());
6495 bool enable,
bool is_expression_fork) {
6501 if (!enable && is_expression_fork) {
6502 if (
auto entry =
GetTarget().GetEntryPointAddress())
6503 entry_addr = entry->GetOpcodeLoadAddress(&
GetTarget());
6517 "DidForkSwitchSoftwareBreakpoints: retaining expression-"
6518 "return trap at {0:x} in forked child",
6542 addr_t addr = wp_res_sp->GetLoadAddress();
6543 size_t size = wp_res_sp->GetByteSize();
6545 m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,
6551 bool is_expression_fork) {
6560 bool overrode_follow_mode =
false;
6563 if (is_expression_fork) {
6564 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6565 "to parent during expression evaluation");
6567 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6568 "to parent during expression evaluation. Child process "
6569 "{0} is available for manual attachment.",
6573 overrode_follow_mode =
true;
6584 switch (follow_fork_mode) {
6586 follow_pid = parent_pid;
6587 follow_tid = parent_tid;
6588 detach_pid = child_pid;
6589 detach_tid = child_tid;
6592 follow_pid = child_pid;
6593 follow_tid = child_tid;
6594 detach_pid = parent_pid;
6595 detach_tid = parent_tid;
6600 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6601 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to set pid/tid");
6615 if (!
m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) ||
6616 !
m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) {
6617 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to reset pid/tid");
6621 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6624 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6626 if (
error.Fail() && keep_stopped) {
6627 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach-and-stay-stopped not "
6628 "supported, falling back to normal detach");
6629 keep_stopped =
false;
6633 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach packet send failed: {0}",
6634 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6640 if (overrode_follow_mode && !is_expression_fork) {
6644 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
6645 "'parent' because an expression is being evaluated.\n"
6646 "Child process %" PRIu64
6647 " has been detached%s.\n"
6648 "You can attach to it with: process attach -p %" PRIu64
6651 keep_stopped ?
" and stopped" :
" (running)",
6667 bool is_expression_fork) {
6672 "ProcessGDBRemote::DidVFork() called for child_pid: {0}, child_tid {1}",
6673 child_pid, child_tid);
6679 bool overrode_follow_mode =
false;
6682 if (is_expression_fork) {
6683 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6684 "to parent during expression evaluation");
6686 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6687 "to parent during expression evaluation. Child process "
6688 "{0} is available for manual attachment.",
6692 overrode_follow_mode =
true;
6702 switch (follow_fork_mode) {
6704 detach_pid = child_pid;
6705 detach_tid = child_tid;
6708 detach_pid =
m_gdb_comm.GetCurrentProcessID();
6714 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6715 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to set pid/tid");
6723 if (!
m_gdb_comm.SetCurrentThread(child_tid, child_pid) ||
6724 !
m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) {
6725 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to reset pid/tid");
6731 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6732 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6734 if (
error.Fail() && keep_stopped) {
6735 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() detach-and-stay-stopped not "
6736 "supported, falling back to normal detach");
6737 keep_stopped =
false;
6742 "ProcessGDBRemote::DidVFork() detach packet send failed: {0}",
6743 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6747 if (overrode_follow_mode && !is_expression_fork) {
6751 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
6752 "'parent' because an expression is being evaluated.\n"
6753 "Child process %" PRIu64
6754 " has been detached%s.\n"
6755 "You can attach to it with: process attach -p %" PRIu64
6758 keep_stopped ?
" and stopped" :
" (running)",
6791 llvm::Error joined = llvm::Error::success();
6792 for (
auto &[site, action] : site_to_action) {
6796 joined = llvm::joinErrors(std::move(joined), std::move(
error));
6804static llvm::SmallVector<std::optional<uint8_t>>
6806 llvm::SmallVector<std::optional<uint8_t>> results;
6810 parsed ? parsed->GetAsDictionary() :
nullptr;
6818 llvm::StringRef token;
6819 if (
auto *
string = object->GetAsString())
6820 token =
string->GetValue();
6821 if (token ==
"OK") {
6822 results.push_back(std::nullopt);
6825 if (token.size() != 3 || !token.starts_with(
"E")) {
6826 results.push_back(uint8_t(0xff));
6829 uint8_t error_code = 0;
6830 if (token.drop_front(1).getAsInteger(
BASE_16, error_code))
6831 results.push_back(0xff);
6833 results.push_back(error_code);
6842static std::optional<GDBStoppointType>
6851 return std::nullopt;
6860 return std::nullopt;
6862 llvm_unreachable(
"unhandled BreakpointSite type");
6866struct BreakpointPacketInfo {
6867 BreakpointSite &site;
6868 size_t trap_opcode_size;
6873std::string to_string(
const BreakpointPacketInfo &info) {
6874 char packet = info.is_enable ?
'Z' :
'z';
6875 return llvm::formatv(
"{0}{1},{2:x-},{3:x-}", packet,
6877 info.trap_opcode_size)
6884 if (site_to_action.empty())
6885 return llvm::Error::success();
6886 if (!
m_gdb_comm.GetMultiBreakpointSupported())
6891 std::vector<BreakpointPacketInfo> breakpoint_infos;
6892 for (
auto [site, action] : site_to_action) {
6894 std::optional<GDBStoppointType> type =
6898 LLDB_LOG(log,
"MultiBreakpoint: site {0} at {1:x} can't be batched",
6899 site->GetID(), site->GetLoadAddress());
6903 breakpoint_infos.push_back(
6908 stream <<
"jMultiBreakpoint:";
6910 auto args_array = std::make_shared<StructuredData::Array>();
6911 for (
auto &bp_info : breakpoint_infos)
6912 args_array->AddStringItem(to_string(bp_info));
6915 packet_dict.
AddItem(
"breakpoint_requests", args_array);
6916 packet_dict.
Dump(stream,
false);
6920 llvm::Expected<StringExtractorGDBRemote> response =
6925 LLDB_LOG_ERROR(log, response.takeError(),
"jMultiBreakpoint failed: {0}");
6929 llvm::SmallVector<std::optional<uint8_t>> results =
6933 if (results.size() != breakpoint_infos.size())
6934 return llvm::createStringErrorV(
6935 "MultiBreakpoint response count mismatch (expected {0}, got {1})",
6936 site_to_action.size(), results.size());
6938 llvm::Error joined = llvm::Error::success();
6939 for (
auto [error_code, bp_info] :
6940 llvm::zip_equal(results, breakpoint_infos)) {
6943 auto error = llvm::createStringErrorV(
6944 "MultiBreakpoint: site {0} at {1:x} failed with E{2}",
6945 bp_info.site.GetID(), bp_info.site.GetLoadAddress(), error_code);
6946 joined = llvm::joinErrors(std::move(joined), std::move(
error));
6950 if (bp_info.is_enable)
static llvm::raw_ostream & error(Stream &strm)
static PluginProperties & GetGlobalPluginProperties()
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF_VERBOSE(log,...)
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_LOG_VERBOSE(log,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
static PluginProperties & GetGlobalPluginProperties()
static const char *const s_async_json_packet_prefix
#define DEBUGSERVER_BASENAME
static size_t SplitCommaSeparatedRegisterNumberString(const llvm::StringRef &comma_separated_register_numbers, std::vector< uint32_t > ®nums, int base)
static const char * end_delimiter
static GDBStoppointType GetGDBStoppointType(const WatchpointResourceSP &wp_res_sp)
static StructuredData::ObjectSP ParseStructuredDataPacket(llvm::StringRef packet)
static std::string BinaryInformationLevelToJSONKey(BinaryInformationLevel info_level)
static uint64_t ComputeNumRangesMultiMemRead(uint64_t max_packet_size, llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges)
Returns the number of ranges that is safe to request using MultiMemRead while respecting max_packet_s...
static std::optional< GDBStoppointType > GetStoppointType(BreakpointSite &site, bool insert, GDBRemoteCommunicationClient &gdb_comm)
Determine the GDB stoppoint type for a breakpoint site by checking which packet types the remote supp...
static FileSpec GetDebugserverPath(Platform &platform)
static llvm::SmallVector< std::optional< uint8_t > > ParseMultiBreakpointResponse(llvm::StringRef response_str)
Parse a MultiBreakpoint response into per-request results.
static const int end_delimiter_len
CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
~CommandObjectMultiwordProcessGDBRemote() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectProcessGDBRemotePacketHistory() override=default
CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter)
~CommandObjectProcessGDBRemotePacketMonitor() override=default
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override
CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter)
CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter)
~CommandObjectProcessGDBRemotePacketSend() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectProcessGDBRemotePacketXferSize() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter)
~CommandObjectProcessGDBRemotePacket() override=default
CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter)
Options * GetOptions() override
OptionGroupBoolean m_json
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectProcessGDBRemoteSpeedTest() override=default
OptionGroupOptions m_option_group
OptionGroupUInt64 m_max_send
OptionGroupUInt64 m_num_packets
CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter)
OptionGroupUInt64 m_max_recv
static lldb::ABISP FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch)
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetHighmemAddressableBits(uint32_t highmem_addressing_bits)
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
void SetLowmemAddressableBits(uint32_t lowmem_addressing_bits)
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
void Clear()
Clears the object state.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
A command line argument class.
static lldb::Encoding StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value=lldb::eEncodingInvalid)
static uint32_t StringToGenericRegister(llvm::StringRef s)
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
void ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char='\0')
Replaces the argument value at index idx to arg_str if idx is a valid argument index.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Class that manages the actual breakpoint that will be inserted into the running program.
BreakpointSite::Type GetType() const
void SetType(BreakpointSite::Type type)
void BroadcastEvent(lldb::EventSP &event_sp)
Broadcast an event which has no associated data.
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
friend class CommandInterpreter
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help="", llvm::StringRef syntax="", uint32_t flags=0)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
CommandInterpreter & m_interpreter
void SetStatus(lldb::ReturnStatus status)
void SetImmediateOutputStream(const lldb::StreamSP &stream_sp)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
lldb::StreamSP GetImmediateOutputStream() const
Stream & GetOutputStream()
A uniqued constant string class.
void SetCString(const char *cstr)
Set the C string value.
void SetString(llvm::StringRef s)
A subclass of DataBuffer that stores a data buffer on the heap.
lldb::StreamUP GetAsyncErrorStream()
TargetList & GetTargetList()
Get accessor for the target list.
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
lldb::StreamUP GetAsyncOutputStream()
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
ArtifactProviderID AddArtifactProvider(std::string name, ArtifactProvider provider)
Register provider to contribute file name.
void RemoveArtifactProvider(ArtifactProviderID id)
Unregister a provider. Thread-safe.
static Diagnostics & Instance()
static llvm::Expected< lldb::ModuleSP > LocateAndLoadBinary(Process *process, BinarySpec &bin_spec)
Find a binary and load it into a Target.
virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Locates or creates a module given by file and updates/loads the resulting module at the virtual base ...
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
const void * GetBytes() const
static const EventDataBytes * GetEventDataFromEvent(const Event *event_ptr)
size_t GetByteSize() const
lldb::ProcessSP GetProcessSP() const
Get accessor that creates a strong reference from the weak process reference contained in this object...
Represents a file descriptor action to be performed during process launch.
Action GetAction() const
Get the type of action.
const FileSpec & GetFileSpec() const
Get the file specification for open actions.
void Append(const FileSpec &file)
Append a FileSpec object to the list.
size_t GetSize() const
Get the number of files in the file list.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
void AppendPathComponent(llvm::StringRef component)
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Clear()
Clears the object state.
static const char * DEV_NULL
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
ValueType Get() const
Get accessor for all flags.
static Environment GetEnvironment()
static void Kill(lldb::pid_t pid, int signo)
static lldb::ListenerSP MakeListener(llvm::StringRef name)
bool get_name(std::string &out) const
bool get_link_map(lldb::addr_t &out) const
bool get_base_is_offset(bool &out) const
bool get_base(lldb::addr_t &out) const
void add(const LoadedModuleInfo &mod)
std::vector< LoadedModuleInfo > m_list
void PutCString(const char *cstr)
LazyBool GetFlash() const
lldb::offset_t GetBlocksize() const
lldb::SymbolSharedCacheUse GetSharedCacheBinaryLoading() const
A collection class for Module objects.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
static ModuleListProperties & GetGlobalModuleListProperties()
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
size_t GetSize() const
Gets the size of the module list.
void ForEach(std::function< IterationAction(const lldb::ModuleSP &module_sp)> const &callback) const
Applies 'callback' to each module in this ModuleList.
void Dump(Stream &strm) const
A class that describes an executable image and its associated object and symbol files.
virtual ObjectFile * GetObjectFile()
Get the object file representation for the current architecture.
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
A plug-in interface definition class for object file parsers.
@ eTypeExecutable
A normal executable.
@ eTypeDebugInfo
An object file that contains only debug information.
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
@ eTypeObjectFile
An intermediate object file.
@ eTypeDynamicLinker
The platform's dynamic linker executable.
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
@ eTypeSharedLibrary
A shared library that can be used during execution.
@ eTypeJIT
JIT code that has symbols, sections and possibly debug info.
A command line option parsing protocol class.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool CreateSettingForProcessPlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, llvm::StringRef description, bool is_global_property)
static lldb::OptionValuePropertiesSP GetSettingForProcessPlugin(Debugger &debugger, llvm::StringRef setting_name)
static bool UnregisterPlugin(ABICreateInstance create_callback)
An address in a process, qualified by an address space.
lldb::addr_t GetValue() const
bool GetIgnoreExisting() const
bool GetDetachOnError() const
bool GetWaitForLaunch() const
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
lldb::pid_t GetProcessID() const
FileSpec & GetExecutableFile()
uint32_t GetUserID() const
Environment & GetEnvironment()
void SetUserID(uint32_t uid)
const char * GetLaunchEventData() const
const FileAction * GetFileActionForFD(int fd) const
void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback)
void SetLaunchInSeparateProcessGroup(bool separate)
const FileSpec & GetWorkingDirectory() const
Args GetExtraStartupCommands() const
FollowForkMode GetFollowForkMode() const
std::chrono::seconds GetInterruptTimeout() const
A plug-in interface definition class for debugging a process.
lldb::IOHandlerSP m_process_input_reader
std::mutex m_process_input_reader_mutex
StopPointSiteList< lldb_private::BreakpointSite > & GetBreakpointSiteList()
virtual Status DisableSoftwareBreakpoint(BreakpointSite *bp_site)
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
ThreadList & GetThreadList()
void SetAddressableBitMasks(AddressableBits bit_masks)
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
void SetUnixSignals(lldb::UnixSignalsSP &&signals_sp)
virtual void ModulesDidLoad(ModuleList &module_list)
virtual llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buffer)
Reads each range individually via ReadMemoryFromInferior, bypassing the memory cache.
void ResumePrivateStateThread()
void MapSupportedStructuredDataPlugins(const StructuredData::Array &supported_type_names)
Loads any plugins associated with asynchronous structured data and maps the relevant supported type n...
std::map< lldb::BreakpointSiteSP, BreakpointAction, SiteIDCmp > BreakpointSiteToActionMap
virtual SystemRuntime * GetSystemRuntime()
Get the system runtime plug-in for this process.
std::map< uint64_t, uint32_t > m_thread_id_to_index_id_map
lldb::StateType GetPrivateState() const
void SetBreakpointSiteEnabled(BreakpointSite &site, bool is_enabled=true)
lldb::DynamicLoaderUP m_dyld_up
virtual Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries)
StopPointSiteList< lldb_private::WatchpointResource > m_watchpoint_resource_list
Watchpoint resources currently in use.
bool IsBreakpointSitePhysicallyEnabled(const BreakpointSite &site)
void AppendSTDOUT(const char *s, size_t len)
bool HasAssignedIndexIDToThread(uint64_t sb_thread_id)
lldb::ByteOrder GetByteOrder() const
void UpdateThreadListIfNeeded()
bool IsValid() const
Return whether this object is valid (i.e.
virtual void DidExec()
Called after a process re-execs itself.
void BroadcastAsyncProfileData(const std::string &one_profile_data)
lldb::UnixSignalsSP m_unix_signals_sp
lldb::tid_t m_interrupt_tid
virtual Status EnableSoftwareBreakpoint(BreakpointSite *bp_site)
bool RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp)
Route the incoming structured data dictionary to the right plugin.
virtual bool IsAlive()
Check if a process is still alive.
ThreadList m_thread_list_real
The threads for this process as are known to the protocol we are debugging with.
lldb::StateType m_last_broadcast_state
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
uint32_t AssignIndexIDToThread(uint64_t thread_id)
virtual bool SetExitStatus(int exit_status, llvm::StringRef exit_string)
Set accessor for the process exit status (return code).
MemoryCache m_memory_cache
uint32_t GetAddressByteSize() const
uint32_t GetStopID() const
void SetPrivateState(lldb::StateType state)
lldb::StateType GetPublicState() const
void SetSTDIOFileDescriptor(int file_descriptor)
Associates a file descriptor with the process' STDIO handling and configures an asynchronous reading ...
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
ThreadList m_thread_list
The threads for this process as the user will see them.
const lldb::UnixSignalsSP & GetUnixSignals()
std::weak_ptr< Target > m_target_wp
The target that owns this process.
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
friend class DynamicLoader
size_t GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site)
const ProcessModID & GetModIDRef() const
ThreadedCommunication m_stdio_communication
Target & GetTarget()
Get the target object pointer for this module.
lldb::OptionValuePropertiesSP GetValueProperties() const
A pseudo terminal helper class.
llvm::Error OpenFirstAvailablePrimary(int oflag)
Open the first available pseudo terminal.
@ invalid_fd
Invalid file descriptor value.
int GetPrimaryFileDescriptor() const
The primary file descriptor accessor.
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
std::string GetSecondaryName() const
Get the name of the secondary pseudo terminal.
std::vector< Enumerator > Enumerators
const Enumerators & GetEnumerators() const
void DumpToLog(Log *log) const
unsigned GetSizeInBits() const
Get size of the field in bits. Will always be at least 1.
uint64_t GetMaxValue() const
The maximum unsigned value that could be contained in this field.
virtual StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Status &error)
virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error)
Status CompleteSending(lldb::pid_t child_pid)
shared_fd_t GetSendableFD()
static llvm::Expected< Pair > CreatePair(std::optional< SocketProtocol > protocol=std::nullopt)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
static lldb::StopInfoSP CreateStopReasonWithMachException(Thread &thread, uint32_t exc_type, uint32_t exc_data_count, uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, bool pc_already_adjusted=true, bool adjust_pc_if_needed=false)
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread)
static lldb::StopInfoSP CreateStopReasonVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonWithInterrupt(Thread &thread, int signo, const char *description)
static lldb::StopInfoSP CreateStopReasonWithSignal(Thread &thread, int signo, const char *description=nullptr, std::optional< int > code=std::nullopt)
static lldb::StopInfoSP CreateStopReasonFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonVForkDone(Thread &thread)
static lldb::StopInfoSP CreateStopReasonWithWatchpointID(Thread &thread, lldb::break_id_t watch_id, bool silently_continue=false)
static lldb::StopInfoSP CreateStopReasonWithException(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(Thread &thread, lldb::break_id_t break_id)
static lldb::StopInfoSP CreateStopReasonHistoryBoundary(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonProcessorTrace(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread)
void ForEach(std::function< void(StopPointSite *)> const &callback)
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
ExecutionContextRef exe_ctx_ref
lldb::break_id_t GetID() const
virtual lldb::addr_t GetLoadAddress() const
bool HardwareRequired() const
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
const char * GetData() const
void Flush() override
Flush the stream.
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
size_t PutStringAsRawHex8(llvm::StringRef s)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
ObjectSP GetItemAtIndex(size_t idx) const
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
ObjectSP GetValueForKey(llvm::StringRef key) const
bool HasKey(llvm::StringRef key) const
void AddItem(llvm::StringRef key, ObjectSP value_sp)
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
void ForEach(std::function< bool(llvm::StringRef key, Object *object)> const &callback) const
Dictionary * GetAsDictionary()
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
uint64_t GetUnsignedIntegerValue(uint64_t fail_value=0)
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
std::shared_ptr< Array > ArraySP
Integer< uint64_t > UnsignedInteger
Defines a list of symbol context objects.
Defines a symbol context baton that can be handed other debug core functions.
A plug-in interface definition class for system runtimes.
virtual void AddThreadExtendedInfoPacketHints(lldb_private::StructuredData::ObjectSP dict)
Add key-value pairs to the StructuredData dictionary object with information debugserver may need whe...
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
Module * GetExecutableModulePointer()
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Debugger & GetDebugger() const
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
lldb::PlatformSP GetPlatform()
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
@ eBroadcastBitNewTargetCreated
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
bool MergeArchitecture(const ArchSpec &arch_spec)
void AddThreadSortedByIndexID(const lldb::ThreadSP &thread_sp)
static llvm::Expected< HostThread > LaunchThread(llvm::StringRef name, std::function< lldb::thread_result_t()> thread_function, size_t min_stack_byte_size=0)
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid, bool can_update=true)
Represents UUID's of various sizes.
bool SetFromStringRef(llvm::StringRef str)
static lldb::UnixSignalsSP Create(const ArchSpec &arch)
static std::vector< lldb::WatchpointResourceSP > AtomizeWatchpointRequest(lldb::addr_t addr, size_t size, bool read, bool write, WatchpointHardwareFeature supported_features, ArchSpec &arch)
Convert a user's watchpoint request into an array of memory regions, each region watched by one hardw...
XMLNode GetRootElement(const char *required_name=nullptr)
bool ParseMemory(const char *xml, size_t xml_length, const char *url="untitled.xml")
void ForEachChildElement(NodeCallback const &callback) const
llvm::StringRef GetName() const
bool GetElementText(std::string &text) const
std::string GetAttributeValue(const char *name, const char *fail_value=nullptr) const
void ForEachChildElementWithName(const char *name, NodeCallback const &callback) const
XMLNode FindFirstChildElementWithName(const char *name) const
void ForEachAttribute(AttributeCallback const &callback) const
@ eBroadcastBitRunPacketSent
PacketResult SendPacketAndReceiveResponseWithOutputSupport(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout, llvm::function_ref< void(llvm::StringRef)> output_callback)
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0), bool sync_on_timeout=true)
lldb::StateType SendContinuePacketAndWaitForResponse(ContinueDelegate &delegate, const UnixSignals &signals, llvm::StringRef payload, std::chrono::seconds interrupt_timeout, StringExtractorGDBRemote &response)
bool SupportsGDBStoppointPacket(GDBStoppointType type)
llvm::Expected< std::string > ReadExtFeature(llvm::StringRef object, llvm::StringRef annex)
void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm)
bool GetQXferLibrariesSVR4ReadSupported()
bool GetQXferLibrariesReadSupported()
void DumpHistory(Stream &strm)
Status FlashErase(lldb::addr_t addr, size_t size)
Status DisableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
llvm::SmallVector< llvm::MutableArrayRef< uint8_t > > DoReadMemoryRanges(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges, llvm::MutableArrayRef< uint8_t > buf) override
Override of DoReadMemoryRanges that uses MultiMemRead to perform this operation in a single packet.
friend class ThreadGDBRemote
DataExtractor GetAuxvData() override
GDBRemoteCommunicationClient & GetGDBRemote()
static bool AcceleratorBreakpointHitCallback(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
Breakpoint callback invoked when an accelerator-plugin-requested breakpoint is hit.
Status DoConnectRemote(llvm::StringRef remote_url) override
Attach to a remote system via a URL.
void HandleAsyncStructuredDataPacket(llvm::StringRef data) override
Process asynchronously-received structured data.
void KillDebugserverProcess()
Status DoDestroy() override
llvm::Error DoDisableBreakpointSite(BreakpointSite &bp_site)
Disable a single breakpoint site directly by sending the appropriate z packet or restoring the origin...
std::vector< std::unique_ptr< RegisterType > > m_register_types
Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info)
StructuredData::ObjectSP m_jstopinfo_sp
virtual std::shared_ptr< ThreadGDBRemote > CreateThread(lldb::tid_t tid)
StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(lldb::addr_t image_list_address, lldb::addr_t image_count) override
Retrieve the list of shared libraries that are loaded for this process This method is used on pre-mac...
llvm::Error HandleAcceleratorActions(const AcceleratorActions &actions)
Handle a set of actions requested by an accelerator plugin.
StructuredData::ObjectSP m_shared_cache_info_sp
StructuredData::ObjectSP m_jthreadsinfo_sp
lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet)
static void MonitorDebugserverProcess(std::weak_ptr< ProcessGDBRemote > process_wp, lldb::pid_t pid, int signo, int exit_status)
StructuredData::ObjectSP GetSharedCacheInfo() override
Status DisableBreakpointSite(BreakpointSite *bp_site) override
Status EnableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
Status DoSignal(int signal) override
Sends a process a UNIX signal signal.
Status DoDeallocateMemory(lldb::addr_t ptr) override
Actually deallocate memory in the process.
Broadcaster m_async_broadcaster
bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec)
llvm::Error UpdateBreakpointSitesNotBatched(const BreakpointSiteToActionMap &site_to_action)
bool StopNoticingNewThreads() override
Call this to turn off the stop & notice new threads mode.
static bool NewThreadNotifyBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid, bool is_expression_fork=false) override
Called after a reported fork.
void DumpPluginHistory(Stream &s) override
The underlying plugin might store the low-level communication history for this session.
FlashRangeVector m_erased_flash_ranges
Status DoDetach(bool keep_stopped) override
Detaches from a running or stopped process.
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) override
Actually allocate memory in the process.
tid_sig_collection m_continue_C_tids
bool HasErased(FlashRange range)
std::optional< bool > DoGetWatchpointReportedAfter() override
Provide an override value in the subclass for lldb's CPU-based logic for whether watchpoint exception...
void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid, bool is_expression_fork=false) override
Called after a reported vfork.
Status WillLaunchOrAttach()
std::optional< uint32_t > GetWatchpointSlotCount() override
Get the number of watchpoints supported by this target.
GDBRemoteCommunicationClient m_gdb_comm
llvm::Expected< std::vector< uint8_t > > DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) override
Does the final operation to read memory tags.
llvm::DenseMap< ModuleCacheKey, ModuleSpec, ModuleCacheInfo > m_cached_module_specs
Status DoWillAttachToProcessWithID(lldb::pid_t pid) override
Called before attaching to a process.
friend class GDBRemoteCommunicationClient
void DidForkSwitchSoftwareBreakpoints(bool enable, bool is_expression_fork=false)
Status DoResume(lldb::RunDirection direction) override
Resumes all of a process's threads as configured using the Thread run control functions.
Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo ®ion_info) override
DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has removed non address bits from loa...
void DidLaunchOrAttach(ArchSpec &process_arch)
size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value)
FlashRangeVector::Entry FlashRange
Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded, lldb::addr_t &load_addr) override
Try to find the load address of a file.
MMapMap m_addr_to_mmap_size
bool GetThreadStopInfoFromJSON(ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp)
void DidLaunch() override
Called after launching a process.
void SetUserSpecifiedMaxMemoryTransferSize(uint64_t user_specified_max)
void AddRemoteRegisters(std::vector< DynamicRegisterInfo::Register > ®isters, const ArchSpec &arch_to_use)
Status UpdateAutomaticSignalFiltering() override
void HandleAsyncStdout(llvm::StringRef out) override
static llvm::StringRef GetPluginDescriptionStatic()
tid_sig_collection m_continue_S_tids
bool m_allow_flash_writes
lldb::BreakpointSP m_thread_create_bp_sp
std::map< uint32_t, std::string > ExpeditedRegisterMap
llvm::Error TraceStop(const TraceStopRequest &request) override
Stop tracing a live process or its threads.
StructuredData::ObjectSP GetExtendedInfoForThread(lldb::tid_t tid)
llvm::Error DoEnableBreakpointSite(BreakpointSite &bp_site)
Enable a single breakpoint site by trying Z0 (software), then Z1 (hardware), then manual memory write...
lldb::ThreadSP HandleThreadAsyncInterrupt(uint8_t signo, const std::string &description) override
Handle thread specific async interrupt and return the original thread that requested the async interr...
llvm::Expected< LoadedModuleInfoList > GetLoadedModuleList() override
Query remote GDBServer for a detailed loaded library list.
bool AcceleratorBreakpointHit(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
bool m_waiting_for_attach
llvm::Error HandleAcceleratorConnection(const AcceleratorActions &actions)
Create a new target for an accelerator and connect it to the GDB server described by the action's con...
llvm::Error GetGDBServerRegisterInfo(ArchSpec &arch)
Status DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a process ID.
void HandleStopReply() override
Status EstablishConnectionIfNeeded(const ProcessInfo &process_info)
llvm::Error UpdateBreakpointSites(const BreakpointSiteToActionMap &site_to_action) override
bool UpdateThreadIDList()
static llvm::StringRef GetPluginNameStatic()
Status DoHalt(bool &caused_stop) override
Halts a running process.
uint64_t m_last_signals_version
llvm::Expected< TraceSupportedResponse > TraceSupported() override
Get the processor tracing type supported for this process.
std::map< std::string, int64_t > m_processed_accelerator_actions
Tracks the last action identifier handled per accelerator plugin so the same actions are not processe...
llvm::Error TraceStart(const llvm::json::Value &request) override
Start tracing a process or its threads.
void ParseExpeditedRegisters(ExpeditedRegisterMap &expedited_register_map, lldb::ThreadSP thread_sp)
size_t DoReadMemory(const ProcessAddress &process_addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a process.
void WillPublicStop() override
Called when the process is about to broadcast a public stop.
Status SendEventData(const char *data) override
bool StartNoticingNewThreads() override
Call this to set the lldb in the mode where it breaks on new thread creations, and then auto-restarts...
DynamicLoader * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
void RemoveNewThreadBreakpoints()
Remove the breakpoints associated with thread creation from the Target.
ArchSpec GetSystemArchitecture() override
Get the system architecture for this process.
Status ConfigureStructuredData(llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) override
Configure asynchronous structured data feature.
bool SupportsReverseDirection() override
Reports whether this process supports reverse execution.
void DidExec() override
Called after a process re-execs itself.
size_t PutSTDIN(const char *buf, size_t buf_size, Status &error) override
Puts data into this process's STDIN.
static void DebuggerInitialize(Debugger &debugger)
tid_collection m_thread_ids
Status DoAttachToProcessWithName(const char *process_name, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a partial process name.
std::string m_partial_profile_data
StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos_sender(StructuredData::ObjectSP args)
void MaybeLoadExecutableModule()
std::vector< lldb::addr_t > m_thread_pcs
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
void SetThreadPc(const lldb::ThreadSP &thread_sp, uint64_t index)
std::recursive_mutex m_async_thread_state_mutex
Status ConnectToDebugserver(llvm::StringRef host_port)
void SetUnixSignals(const lldb::UnixSignalsSP &signals_sp)
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
uint64_t m_remote_stub_max_memory_size
std::optional< StringExtractorGDBRemote > m_last_stop_packet
CommandObject * GetPluginCommandObject() override
Return a multi-word command object that can be used to expose plug-in specific commands.
int64_t m_breakpoint_pc_offset
size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, Status &error) override
Actually do the writing of memory to a process.
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override
Launch a new process.
lldb::CommandObjectSP m_command_sp
void DidVForkDone() override
Called after reported vfork completion.
std::string HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &inputStringExtractor)
bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, std::string xml_filename, std::vector< DynamicRegisterInfo::Register > ®isters)
lldb::tid_t m_last_stop_primary_tid
bool m_use_g_packet_for_reading
Status DoWillAttachToProcessWithName(const char *process_name, bool wait_for_launch) override
Called before attaching to a process.
static std::chrono::seconds GetPacketTimeout()
lldb::ListenerSP m_async_listener_sp
std::pair< std::string, std::string > ModuleCacheKey
bool CalculateThreadStopInfo(ThreadGDBRemote *thread)
lldb::DynamicRegisterInfoSP m_register_info_sp
tid_collection m_continue_c_tids
bool SupportsMemoryTagging() override
Check whether the process supports memory tagging.
void BuildDynamicRegisterInfo(bool force)
tid_collection m_continue_s_tids
size_t UpdateThreadPCsFromStopReplyThreadsValue(llvm::StringRef value)
~ProcessGDBRemote() override
llvm::VersionTuple GetHostOSVersion() override
Sometimes the connection to a process can detect the host OS version that the process is running on.
lldb::tid_t m_initial_tid
llvm::Expected< StringExtractorGDBRemote > SendMultiMemReadPacket(llvm::ArrayRef< Range< lldb::addr_t, size_t > > ranges)
std::map< uint64_t, uint32_t > m_thread_id_to_used_usec_map
Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, const std::vector< uint8_t > &tags) override
Does the final operation to write memory tags.
llvm::Error ParseMultiMemReadPacket(llvm::StringRef response_str, llvm::MutableArrayRef< uint8_t > buffer, unsigned expected_num_ranges, llvm::SmallVectorImpl< llvm::MutableArrayRef< uint8_t > > &memory_regions)
llvm::Expected< std::vector< uint8_t > > TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override
Get binary data given a trace technology and a data identifier.
llvm::Error HandleAcceleratorBreakpoints(const AcceleratorActions &actions)
Set the breakpoints requested by an accelerator plugin as internal breakpoints with a callback that n...
Status EnableBreakpointSite(BreakpointSite *bp_site) override
void ModulesDidLoad(ModuleList &module_list) override
ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
uint32_t m_vfork_in_progress_count
@ eBroadcastBitAsyncContinue
@ eBroadcastBitAsyncThreadShouldExit
@ eBroadcastBitAsyncThreadDidExit
Status WillResume() override
Called before resuming to a process.
std::mutex m_shared_cache_info_mutex
lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr, bool value_is_offset)
void SetLastStopPacket(const StringExtractorGDBRemote &response)
lldb::thread_result_t AsyncThread()
Status WriteObjectFile(std::vector< ObjectFile::LoadableData > entries) override
static std::chrono::milliseconds GetPacketTestDelay()
llvm::Error LoadModules() override
Sometimes processes know how to retrieve and load shared libraries.
uint64_t m_max_memory_size
void HandleAsyncMisc(llvm::StringRef data) override
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path, bool can_connect)
void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple) override
llvm::VersionTuple GetHostMacCatalystVersion() override
void DidForkSwitchHardwareTraps(bool enable)
HostThread m_async_thread
StructuredData::ObjectSP GetDynamicLoaderProcessState() override
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override
Try to fetch the module specification for a module with the given file name and architecture.
Status DoWillLaunch(Module *module) override
Called before launching to a process.
void DidAttach(ArchSpec &process_arch) override
Called after attaching a process.
llvm::Expected< bool > SaveCore(llvm::StringRef outfile) override
Save core dump into the specified file.
std::atomic< lldb::pid_t > m_debugserver_pid
std::optional< Diagnostics::ArtifactProviderID > m_diagnostics_artifact_id
Registration for the packet-history diagnostics provider, if enabled.
llvm::Expected< std::string > TraceGetState(llvm::StringRef type) override
Get the current tracing state of the process and its threads.
bool IsAlive() override
Check if a process is still alive.
void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override
void SetQueueInfo(std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue)
void SetNewlyAddedBinaries(const std::vector< lldb::addr_t > &added_binaries)
void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr)
void PrivateSetRegisterUnavailable(uint32_t reg)
lldb::RegisterContextSP GetRegisterContext() override
void SetDetailedBinariesInfo(StructuredData::ObjectSP &detailed_info)
void SetAssociatedWithLibdispatchQueue(lldb_private::LazyBool associated_with_libdispatch_queue) override
bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef< uint8_t > data)
#define LLDB_INVALID_SITE_ID
#define LLDB_INVALID_WATCH_ID
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_THREAD_ID
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_INVALID_PROCESS_ID
#define LLDB_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
std::shared_ptr< lldb_private::Event > EventSP
@ eReturnStatusSuccessFinishResult
@ eArgTypeUnsignedInteger
std::shared_ptr< lldb_private::Watchpoint > WatchpointSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::WatchpointResource > WatchpointResourceSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
BinaryInformationLevel
When the Process plugin can retrieve information about all binaries loaded in the target process,...
@ eBinaryInformationLevelAddrName
@ eBinaryInformationLevelAddrNameUUID
@ eBinaryInformationLevelFull
@ eBinaryInformationLevelAddrOnly
std::shared_ptr< lldb_private::Target > TargetSP
std::unique_ptr< lldb_private::Stream > StreamUP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindProcessPlugin
num used by the process plugin - e.g.
Actions to be performed in the native process on behalf of an accelerator plugin.
std::vector< AcceleratorBreakpointInfo > breakpoints
New breakpoints to set. Nothing to set if this is empty.
int64_t identifier
Unique identifier for this action within the plugin.
std::string plugin_name
Unique name identifying the accelerator plugin.
std::optional< AcceleratorConnectionInfo > connect_info
If set, the client should create a new target and connect to the accelerator GDB server described her...
std::string session_name
Human-readable label for the accelerator target.
Sent by the client when a plugin-requested breakpoint is hit.
AcceleratorBreakpointInfo breakpoint
std::vector< SymbolValue > symbol_values
int64_t identifier
Unique breakpoint ID used to identify this breakpoint in the BreakpointWasHit callback.
std::vector< std::string > symbol_names
Symbol names whose values should be supplied when the breakpoint is hit.
std::optional< AcceleratorBreakpointByAddress > by_address
Breakpoint by load address.
std::optional< AcceleratorBreakpointByName > by_name
Breakpoint by function name.
Information the client needs to connect to an accelerator GDB server.
std::string triple
Target triple for the accelerator target.
bool synchronous
If true, connect synchronously: the client blocks until the accelerator process is connected and stop...
std::optional< std::string > exe_path
Path to the executable to use when creating the accelerator target.
std::string connect_url
Connection URL the client should connect to (as in "process connect<url>").
std::string platform_name
Name of the platform to select when creating the accelerator target.
A binary to find and load into a Target.
lldb::addr_t value
Address where the binary should be loaded, or read out of memory.
UUID uuid
UUID of the binary to be loaded.
bool force_symbol_search
Allow the search to do a possibly expensive external search for the ObjectFile and/or SymbolFile.
bool set_address_in_target
Whether the address of the binary should be set in the Target if it is added.
bool notify
Whether ModulesDidLoad should be called once the binary has been added to the Target.
bool value_is_offset
A flag indicating that value is an address, or an offset to be applied to the file addresses.
const RegisterType * register_type
std::vector< uint32_t > value_regs
std::vector< uint32_t > invalidate_regs
static Status ToFormat(const char *s, lldb::Format &format, size_t *byte_size_ptr)
BaseType GetRangeBase() const
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
BaseType GetRangeEnd() const
void SetByteSize(SizeType s)
jLLDBTraceGetBinaryData gdb-remote packet
jLLDBTraceStop gdb-remote packet