9#include "lldb/Host/Config.h"
14#include <netinet/in.h>
17#include <sys/socket.h>
22#include <sys/sysctl.h>
101#include "llvm/ADT/STLExtras.h"
102#include "llvm/ADT/ScopeExit.h"
103#include "llvm/ADT/StringMap.h"
104#include "llvm/ADT/StringSwitch.h"
105#include "llvm/Support/ErrorExtras.h"
106#include "llvm/Support/FormatAdapters.h"
107#include "llvm/Support/Threading.h"
108#include "llvm/Support/raw_ostream.h"
110#if defined(__APPLE__)
111#define DEBUGSERVER_BASENAME "debugserver"
113#define DEBUGSERVER_BASENAME "lldb-server.exe"
115#define DEBUGSERVER_BASENAME "lldb-server"
135 llvm::consumeError(file.takeError());
139 ((
Process *)p)->DumpPluginHistory(stream);
145#define LLDB_PROPERTIES_processgdbremote
146#include "ProcessGDBRemoteProperties.inc"
149#define LLDB_PROPERTIES_processgdbremote
150#include "ProcessGDBRemotePropertiesEnum.inc"
155 static llvm::StringRef GetSettingName() {
159 PluginProperties() : Properties() {
160 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
161 m_collection_sp->Initialize(g_processgdbremote_properties_def);
164 ~PluginProperties()
override =
default;
166 uint64_t GetPacketTimeout() {
167 const uint32_t idx = ePropertyPacketTimeout;
168 return GetPropertyAtIndexAs<uint64_t>(
169 idx, g_processgdbremote_properties[idx].default_uint_value);
172 bool SetPacketTimeout(uint64_t timeout) {
173 const uint32_t idx = ePropertyPacketTimeout;
174 return SetPropertyAtIndex(idx, timeout);
177 FileSpec GetTargetDefinitionFile()
const {
178 const uint32_t idx = ePropertyTargetDefinitionFile;
179 return GetPropertyAtIndexAs<FileSpec>(idx, {});
182 bool GetUseSVR4()
const {
183 const uint32_t idx = ePropertyUseSVR4;
184 return GetPropertyAtIndexAs<bool>(
185 idx, g_processgdbremote_properties[idx].default_uint_value != 0);
188 bool GetUseGPacketForReading()
const {
189 const uint32_t idx = ePropertyUseGPacketForReading;
190 return GetPropertyAtIndexAs<bool>(idx,
true);
193 uint64_t GetPacketTestDelay()
const {
194 const uint32_t idx = ePropertyPacketTestDelay;
195 return GetPropertyAtIndexAs<uint64_t>(
196 idx, g_processgdbremote_properties[idx].default_uint_value);
200std::chrono::seconds ResumeTimeout() {
return std::chrono::seconds(5); }
202static std::pair<uint16_t, uint16_t> GetClientTerminalSize() {
204 CONSOLE_SCREEN_BUFFER_INFO csbi{};
205 HANDLE h = ::GetStdHandle(STD_OUTPUT_HANDLE);
206 if (h != INVALID_HANDLE_VALUE && ::GetConsoleScreenBufferInfo(h, &csbi)) {
207 int cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
208 int rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
209 if (cols > 0 && rows > 0)
210 return {
static_cast<uint16_t
>(cols),
static_cast<uint16_t
>(rows)};
212#elif LLDB_ENABLE_POSIX
214 if (::ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0 &&
216 return {ws.ws_col, ws.ws_row};
224 static PluginProperties g_settings;
232#if defined(__APPLE__)
233#define LOW_PORT (IPPORT_RESERVED)
234#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
236#define LOW_PORT (1024u)
237#define HIGH_PORT (49151u)
241 return "GDB Remote protocol based debugging plug-in.";
250 const FileSpec *crash_file_path,
bool can_connect) {
266 return std::chrono::milliseconds(
275 bool plugin_specified_by_name) {
276 if (plugin_specified_by_name)
280 Module *exe_module = target_sp->GetExecutableModulePointer();
284 switch (exe_objfile->
GetType()) {
308 :
Process(target_sp, listener_sp),
312 Listener::MakeListener(
"lldb.process.gdb-remote.async-listener")),
323 "async thread should exit");
325 "async thread continue");
327 "async thread did exit");
331 const uint32_t async_event_mask =
337 "ProcessGDBRemote::%s failed to listen for "
338 "m_async_broadcaster events",
342 const uint64_t timeout_seconds =
344 if (timeout_seconds > 0)
345 m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
369std::shared_ptr<ThreadGDBRemote>
371 return std::make_shared<ThreadGDBRemote>(*
this, tid);
375 const FileSpec &target_definition_fspec) {
381 if (module_object_sp) {
384 "gdb-server-target-definition",
error));
386 if (target_definition_sp) {
388 target_definition_sp->GetValueForKey(
"host-info"));
390 if (
auto host_info_dict = target_object->GetAsDictionary()) {
392 host_info_dict->GetValueForKey(
"triple");
393 if (
auto triple_string_value = triple_value->GetAsString()) {
394 std::string triple_string =
395 std::string(triple_string_value->GetValue());
396 ArchSpec host_arch(triple_string.c_str());
405 target_definition_sp->GetValueForKey(
"breakpoint-pc-offset");
406 if (breakpoint_pc_offset_value) {
407 if (
auto breakpoint_pc_int_value =
408 breakpoint_pc_offset_value->GetAsSignedInteger())
413 *target_definition_sp,
GetTarget().GetArchitecture()) > 0) {
422 const llvm::StringRef &comma_separated_register_numbers,
423 std::vector<uint32_t> ®nums,
int base) {
425 for (llvm::StringRef x : llvm::split(comma_separated_register_numbers,
',')) {
427 if (llvm::to_integer(x, reg, base))
428 regnums.push_back(reg);
430 return regnums.size();
442 const auto host_packet_timeout =
m_gdb_comm.GetHostDefaultPacketTimeout();
443 if (host_packet_timeout > std::chrono::seconds(0)) {
461 if (target_definition_fspec) {
467 target_definition_fspec.
GetPath() +
478 if (remote_process_arch.
IsValid())
479 arch_to_use = remote_process_arch;
481 arch_to_use = remote_host_arch;
484 arch_to_use = target_arch;
487 if (!register_info_err) {
494 "Failed to read register information from target XML: {0}");
495 LLDB_LOG(log,
"Now trying to use qRegisterInfo instead.");
498 std::vector<DynamicRegisterInfo::Register> registers;
499 uint32_t reg_num = 0;
503 const int packet_len =
504 ::snprintf(packet,
sizeof(packet),
"qRegisterInfo%x", reg_num);
505 assert(packet_len < (
int)
sizeof(packet));
508 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
512 llvm::StringRef name;
513 llvm::StringRef value;
517 if (name ==
"name") {
519 }
else if (name ==
"alt-name") {
521 }
else if (name ==
"bitsize") {
522 if (!value.getAsInteger(0, reg_info.
byte_size))
524 }
else if (name ==
"offset") {
526 }
else if (name ==
"encoding") {
530 }
else if (name ==
"format") {
534 llvm::StringSwitch<Format>(value)
576 }
else if (name ==
"set") {
578 }
else if (name ==
"gcc" || name ==
"ehframe") {
580 }
else if (name ==
"dwarf") {
582 }
else if (name ==
"generic") {
584 }
else if (name ==
"container-regs") {
586 }
else if (name ==
"invalidate-regs") {
592 registers.push_back(reg_info);
605 "the debug server supports Target Description XML but LLDB does "
606 "not have XML parsing enabled. Using \"qRegisterInfo\" was also "
607 "not possible. Register information may be incorrect or missing",
617 if (registers.empty()) {
619 if (!registers.empty())
622 "All other methods failed, using fallback register information.");
637 bool wait_for_launch) {
669 if (
m_gdb_comm.GetProcessArchitecture().IsValid()) {
672 if (
m_gdb_comm.GetHostArchitecture().IsValid()) {
683 "Process %" PRIu64
" was reported after connecting to "
684 "'%s', but state was not stopped: %s",
688 "Process %" PRIu64
" was reported after connecting to '%s', "
689 "but no stop reply packet was received",
690 pid, remote_url.str().c_str());
694 "ProcessGDBRemote::%s pid %" PRIu64
695 ": normalizing target architecture initial triple: %s "
696 "(GetTarget().GetArchitecture().IsValid() %s, "
697 "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
698 __FUNCTION__,
GetID(),
699 GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
701 m_gdb_comm.GetHostArchitecture().IsValid() ?
"true" :
"false");
707 if (
m_gdb_comm.GetProcessArchitecture().IsValid())
714 "ProcessGDBRemote::%s pid %" PRIu64
715 ": normalized target architecture triple: %s",
716 __FUNCTION__,
GetID(),
717 GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
734 LLDB_LOGF(log,
"ProcessGDBRemote::%s() entered", __FUNCTION__);
736 uint32_t launch_flags = launch_info.
GetFlags().
Get();
759 if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
761 "ProcessGDBRemote::%s provided with STDIO paths via "
762 "launch_info: stdin=%s, stdout=%s, stderr=%s",
764 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
765 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
766 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
768 LLDB_LOGF(log,
"ProcessGDBRemote::%s no STDIO paths given via launch_info",
771 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
772 if (stdin_file_spec || disable_stdio) {
787 if (
error.Success()) {
789 const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
794 if (!stdin_file_spec)
796 FileSpec::Style::native);
797 if (!stdout_file_spec)
799 FileSpec::Style::native);
800 if (!stderr_file_spec)
802 FileSpec::Style::native);
803 }
else if (platform_sp && platform_sp->IsHost()) {
808 if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
812 if (!stdin_file_spec)
813 stdin_file_spec = secondary_name;
815 if (!stdout_file_spec)
816 stdout_file_spec = secondary_name;
818 if (!stderr_file_spec)
819 stderr_file_spec = secondary_name;
823 "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
824 "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
827 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
828 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
829 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
833 "ProcessGDBRemote::%s final STDIO paths after all "
834 "adjustments: stdin=%s, stdout=%s, stderr=%s",
836 stdin_file_spec ? stdin_file_spec.
GetPath().c_str() :
"<null>",
837 stdout_file_spec ? stdout_file_spec.
GetPath().c_str() :
"<null>",
838 stderr_file_spec ? stderr_file_spec.
GetPath().c_str() :
"<null>");
842 if (stdout_file_spec)
844 if (stderr_file_spec)
847 if (launch_flags & eLaunchFlagUsePipes) {
850 auto [terminal_cols, terminal_rows] = GetClientTerminalSize();
851 m_gdb_comm.SetSTDIOWindowSize(terminal_cols, terminal_rows);
854 m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
855 m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
858 GetTarget().GetArchitecture().GetArchitectureName());
861 if (launch_event_data !=
nullptr && *launch_event_data !=
'\0')
862 m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
874 std::chrono::seconds(10));
880 const llvm::Triple &remote_triple =
882 if (remote_triple.getOS() != llvm::Triple::UnknownOS) {
883 FileSpec remote_exe_file(exe_file.GetPath(
false),
886 0, remote_exe_file.
GetPath(
true));
889 exe_file.GetPath(
true));
892 if (llvm::Error err =
m_gdb_comm.LaunchProcess(args)) {
895 llvm::fmt_consume(std::move(err)));
902 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
924 if (!disable_stdio) {
934 std::make_shared<IOHandlerProcessSTDIOWindows>(
this);
940 LLDB_LOGF(log,
"failed to connect to debugserver: %s",
error.AsCString());
950 if (!connect_url.empty()) {
951 LLDB_LOGF(log,
"ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
952 connect_url.str().c_str());
953 std::unique_ptr<ConnectionFileDescriptor> conn_up(
956 const uint32_t max_retry_count = 50;
957 uint32_t retry_count = 0;
966 if (retry_count >= max_retry_count)
969 std::this_thread::sleep_for(std::chrono::milliseconds(100));
993 m_gdb_comm.GetListThreadsInStopReplySupported();
1000 auto handle_cmds = [&] (
const Args &args) ->
void {
1004 entry.c_str(), response);
1010 handle_cmds(platform_sp->GetExtraStartupCommands());
1027 if (remote_process_arch.
IsValid()) {
1028 process_arch = remote_process_arch;
1029 LLDB_LOG(log,
"gdb-remote had process architecture, using {0} {1}",
1033 process_arch =
m_gdb_comm.GetHostArchitecture();
1035 "gdb-remote did not have process architecture, using gdb-remote "
1036 "host architecture {0} {1}",
1047 LLDB_LOG(log,
"analyzing target arch, currently {0} {1}",
1059 if ((process_arch.
GetMachine() == llvm::Triple::arm ||
1060 process_arch.
GetMachine() == llvm::Triple::thumb) &&
1061 process_arch.
GetTriple().getVendor() == llvm::Triple::Apple) {
1064 "remote process is ARM/Apple, "
1065 "setting target arch to {0} {1}",
1070 const llvm::Triple &remote_triple = process_arch.
GetTriple();
1071 llvm::Triple new_target_triple = target_arch.
GetTriple();
1072 if (new_target_triple.getVendorName().size() == 0) {
1073 new_target_triple.setVendor(remote_triple.getVendor());
1075 if (new_target_triple.getOSName().size() == 0) {
1076 new_target_triple.setOS(remote_triple.getOS());
1078 if (new_target_triple.getEnvironmentName().size() == 0)
1079 new_target_triple.setEnvironment(remote_triple.getEnvironment());
1082 ArchSpec new_target_arch = target_arch;
1083 new_target_arch.
SetTriple(new_target_triple);
1089 "final target arch after adjustments for remote architecture: "
1108 m_gdb_comm.GetSupportedStructuredDataPlugins())
1117 if (platform_sp && platform_sp->IsConnected())
1125 llvm::Expected<std::vector<AcceleratorActions>> init_actions =
1126 m_gdb_comm.GetAcceleratorInitializeActions();
1127 if (!init_actions) {
1129 "failed to get accelerator initialize actions: {0}");
1134 "failed to handle accelerator actions: {0}");
1144 UUID standalone_uuid;
1146 bool standalone_value_is_offset;
1147 if (
m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value,
1148 standalone_value_is_offset)) {
1151 if (standalone_uuid.
IsValid()) {
1152 const bool force_symbol_search =
true;
1153 const bool notify =
true;
1154 const bool set_address_in_target =
true;
1155 const bool allow_memory_image_last_resort =
false;
1157 this,
"", standalone_uuid, standalone_value,
1158 standalone_value_is_offset, force_symbol_search, notify,
1159 set_address_in_target, allow_memory_image_last_resort);
1171 std::vector<addr_t> bin_addrs =
m_gdb_comm.GetProcessStandaloneBinaries();
1172 if (bin_addrs.size()) {
1174 const bool value_is_slide =
false;
1175 for (
addr_t addr : bin_addrs) {
1176 const bool notify =
true;
1183 .LoadPlatformBinaryAndSetup(
this, addr, notify))
1186 const bool force_symbol_search =
true;
1187 const bool set_address_in_target =
true;
1188 const bool allow_memory_image_last_resort =
false;
1191 this, llvm::StringRef(), uuid, addr, value_is_slide,
1192 force_symbol_search, notify, set_address_in_target,
1193 allow_memory_image_last_resort);
1203 std::optional<QOffsets> offsets =
m_gdb_comm.GetQOffsets();
1208 size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==
1209 offsets->offsets.size();
1213 bool changed =
false;
1214 module_sp->SetLoadAddress(
GetTarget(), offsets->offsets[0],
1219 m_process->GetTarget().ModulesDidLoad(list);
1233 LLDB_LOGF(log,
"ProcessGDBRemote::%s()", __FUNCTION__);
1239 if (
error.Success()) {
1243 const int packet_len =
1244 ::snprintf(packet,
sizeof(packet),
"vAttach;%" PRIx64, attach_pid);
1247 std::make_shared<EventDataBytes>(llvm::StringRef(packet, packet_len));
1262 if (process_name && process_name[0]) {
1264 if (
error.Success()) {
1270 if (!
m_gdb_comm.GetVAttachOrWaitSupported()) {
1285 auto data_sp = std::make_shared<EventDataBytes>(packet.
GetString());
1306llvm::Expected<std::string>
1311llvm::Expected<std::vector<uint8_t>>
1323 process_arch.
Clear();
1339 return m_gdb_comm.GetReverseStepSupported() ||
1346 LLDB_LOGF(log,
"ProcessGDBRemote::Resume(%s)",
1351 if (listener_sp->StartListeningForEvents(
1353 listener_sp->StartListeningForEvents(
1360 bool continue_packet_error =
false;
1374 std::string pid_prefix;
1376 pid_prefix = llvm::formatv(
"p{0:x-}.",
GetID());
1378 if (num_continue_c_tids == num_threads ||
1383 continue_packet.
Format(
"vCont;c:{0}-1", pid_prefix);
1391 for (tid_collection::const_iterator
1394 t_pos != t_end; ++t_pos)
1395 continue_packet.
Format(
";c:{0}{1:x-}", pid_prefix, *t_pos);
1397 continue_packet_error =
true;
1402 for (tid_sig_collection::const_iterator
1405 s_pos != s_end; ++s_pos)
1406 continue_packet.
Format(
";C{0:x-2}:{1}{2:x-}", s_pos->second,
1407 pid_prefix, s_pos->first);
1409 continue_packet_error =
true;
1414 for (tid_collection::const_iterator
1417 t_pos != t_end; ++t_pos)
1418 continue_packet.
Format(
";s:{0}{1:x-}", pid_prefix, *t_pos);
1420 continue_packet_error =
true;
1425 for (tid_sig_collection::const_iterator
1428 s_pos != s_end; ++s_pos)
1429 continue_packet.
Format(
";S{0:x-2}:{1}{2:x-}", s_pos->second,
1430 pid_prefix, s_pos->first);
1432 continue_packet_error =
true;
1435 if (continue_packet_error)
1436 continue_packet.
Clear();
1439 continue_packet_error =
true;
1445 if (num_continue_c_tids > 0) {
1446 if (num_continue_c_tids == num_threads) {
1450 continue_packet_error =
false;
1451 }
else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
1452 num_continue_s_tids == 0 && num_continue_S_tids == 0) {
1456 continue_packet_error =
false;
1460 if (continue_packet_error && num_continue_C_tids > 0) {
1461 if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
1462 num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
1463 num_continue_S_tids == 0) {
1466 if (num_continue_C_tids > 1) {
1471 if (num_continue_C_tids > 1) {
1472 continue_packet_error =
false;
1475 continue_packet_error =
true;
1478 if (!continue_packet_error)
1482 continue_packet_error =
false;
1485 if (!continue_packet_error) {
1487 continue_packet.
Printf(
"C%2.2x", continue_signo);
1492 if (continue_packet_error && num_continue_s_tids > 0) {
1493 if (num_continue_s_tids == num_threads) {
1499 continue_packet_error =
false;
1500 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1501 num_continue_s_tids == 1 && num_continue_S_tids == 0) {
1505 continue_packet_error =
false;
1509 if (!continue_packet_error && num_continue_S_tids > 0) {
1510 if (num_continue_S_tids == num_threads) {
1513 continue_packet_error =
false;
1514 if (num_continue_S_tids > 1) {
1515 for (
size_t i = 1; i < num_threads; ++i) {
1517 continue_packet_error =
true;
1520 if (!continue_packet_error) {
1523 continue_packet.
Printf(
"S%2.2x", step_signo);
1525 }
else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
1526 num_continue_s_tids == 0 && num_continue_S_tids == 1) {
1530 continue_packet_error =
false;
1536 if (num_continue_s_tids > 0 || num_continue_S_tids > 0) {
1538 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1539 "support reverse-stepping");
1541 "target does not support reverse-stepping");
1544 if (num_continue_S_tids > 0) {
1547 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1549 "can't deliver signals while running in reverse");
1552 if (num_continue_s_tids > 1) {
1553 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: can't step multiple "
1554 "threads in reverse");
1556 "can't step multiple threads while reverse-stepping");
1562 if (!
m_gdb_comm.GetReverseContinueSupported()) {
1563 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: target does not "
1564 "support reverse-continue");
1566 "target does not support reverse execution of processes");
1569 if (num_continue_C_tids > 0) {
1572 "ProcessGDBRemote::DoResume: Signals not supported in reverse");
1574 "can't deliver signals while running in reverse");
1582 continue_packet_error =
false;
1585 if (continue_packet_error) {
1587 "can't make continue packet for this resume");
1592 "Trying to resume but the async thread is dead.");
1593 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Trying to resume but the "
1594 "async thread is dead.");
1599 std::make_shared<EventDataBytes>(continue_packet.
GetString());
1602 if (!listener_sp->GetEvent(event_sp, ResumeTimeout())) {
1604 LLDB_LOGF(log,
"ProcessGDBRemote::DoResume: Resume timed out.");
1607 "Broadcast continue, but the async thread was "
1608 "killed before we got an ack back.");
1610 "ProcessGDBRemote::DoResume: Broadcast continue, but the "
1611 "async thread was killed before we got an ack back.");
1627 llvm::StringRef value) {
1633 auto pid_tid = thread_ids.
GetPidTid(pid);
1634 if (pid_tid && pid_tid->first == pid) {
1640 }
while (thread_ids.
GetChar() ==
',');
1646 llvm::StringRef value) {
1648 for (llvm::StringRef x : llvm::split(value,
',')) {
1650 if (llvm::to_integer(x,
pc, 16))
1662 if (thread_infos && thread_infos->
GetSize() > 0) {
1686 const llvm::StringRef stop_info_str = stop_info.
GetStringRef();
1689 const size_t thread_pcs_pos = stop_info_str.find(
";thread-pcs:");
1690 if (thread_pcs_pos != llvm::StringRef::npos) {
1691 const size_t start = thread_pcs_pos + strlen(
";thread-pcs:");
1692 const size_t end = stop_info_str.find(
';', start);
1693 if (end != llvm::StringRef::npos) {
1694 llvm::StringRef value = stop_info_str.substr(start, end - start);
1699 const size_t threads_pos = stop_info_str.find(
";threads:");
1700 if (threads_pos != llvm::StringRef::npos) {
1701 const size_t start = threads_pos + strlen(
";threads:");
1702 const size_t end = stop_info_str.find(
';', start);
1703 if (end != llvm::StringRef::npos) {
1704 llvm::StringRef value = stop_info_str.substr(start, end - start);
1712 bool sequence_mutex_unavailable =
false;
1714 if (sequence_mutex_unavailable) {
1729 if (num_thread_ids == 0) {
1735 ThreadList old_thread_list_copy(old_thread_list);
1736 if (num_thread_ids > 0) {
1737 for (
size_t i = 0; i < num_thread_ids; ++i) {
1744 thread_sp.get(), thread_sp->GetID());
1747 thread_sp.get(), thread_sp->GetID());
1757 size_t old_num_thread_ids = old_thread_list_copy.
GetSize(
false);
1758 for (
size_t i = 0; i < old_num_thread_ids; i++) {
1760 if (old_thread_sp) {
1761 lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
1776 uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1789 if (thread_infos_sp) {
1793 const size_t n = thread_infos->
GetSize();
1794 for (
size_t i = 0; i < n; ++i) {
1800 if (tid == thread->GetID())
1829 if (
GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
1839 for (
const auto &pair : expedited_register_map) {
1840 uint32_t lldb_regnum = gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
1850 reg_value_extractor.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
1858 uint8_t signo,
const std::string &thread_name,
const std::string &reason,
1859 const std::string &description, uint32_t exc_type,
1860 const std::vector<addr_t> &exc_data,
addr_t thread_dispatch_qaddr,
1861 bool queue_vars_valid,
1863 LazyBool associated_with_dispatch_queue,
addr_t dispatch_queue_t,
1864 std::string &queue_name,
QueueKind queue_kind, uint64_t queue_serial,
1865 std::vector<lldb::addr_t> &added_binaries,
1890 reg_ctx_sp->InvalidateIfNeeded(
true);
1898 if (reg_ctx_sp->ReconfigureRegisterInfo()) {
1901 reg_ctx_sp->InvalidateAllRegisters();
1908 thread_sp->SetName(thread_name.empty() ?
nullptr : thread_name.c_str());
1913 if (queue_vars_valid)
1914 gdb_thread->
SetQueueInfo(std::move(queue_name), queue_kind, queue_serial,
1915 dispatch_queue_t, associated_with_dispatch_queue);
1929 StopInfoSP current_stop_info_sp = thread_sp->GetPrivateStopInfo(
false);
1931 current_stop_info_sp) {
1932 thread_sp->SetStopInfo(current_stop_info_sp);
1936 if (!thread_sp->StopInfoIsUpToDate()) {
1939 addr_t pc = thread_sp->GetRegisterContext()->GetPC();
1941 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
pc);
1943 thread_sp->SetThreadStoppedAtUnexecutedBP(
pc);
1945 if (exc_type != 0) {
1953 if (interrupt_thread)
1954 thread_sp = interrupt_thread;
1956 const size_t exc_data_size = exc_data.size();
1957 thread_sp->SetStopInfo(
1959 *thread_sp, exc_type, exc_data_size,
1960 exc_data_size >= 1 ? exc_data[0] : 0,
1961 exc_data_size >= 2 ? exc_data[1] : 0,
1962 exc_data_size >= 3 ? exc_data[2] : 0));
1965 bool handled =
false;
1966 bool did_exec =
false;
1969 if (!reason.empty() && reason !=
"none") {
1970 if (reason ==
"trace") {
1973 }
else if (reason ==
"breakpoint") {
1974 thread_sp->SetThreadHitBreakpointSite();
1982 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
1983 thread_sp->SetStopInfo(
1985 *thread_sp, bp_site_sp->GetID()));
1988 thread_sp->SetStopInfo(invalid_stop_info_sp);
1991 }
else if (reason ==
"trap") {
1993 }
else if (reason ==
"watchpoint") {
2029 bool silently_continue =
false;
2039 silently_continue =
true;
2043 if (!wp_resource_sp) {
2045 LLDB_LOGF(log,
"failed to find watchpoint");
2052 watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
2055 *thread_sp, watch_id, silently_continue));
2057 }
else if (reason ==
"exception") {
2059 *thread_sp, description.c_str()));
2061 }
else if (reason ==
"history boundary") {
2063 *thread_sp, description.c_str()));
2065 }
else if (reason ==
"exec") {
2067 thread_sp->SetStopInfo(
2070 }
else if (reason ==
"processor trace") {
2072 *thread_sp, description.c_str()));
2073 }
else if (reason ==
"fork") {
2078 thread_sp->SetStopInfo(
2081 }
else if (reason ==
"vfork") {
2087 *thread_sp, child_pid, child_tid));
2089 }
else if (reason ==
"vforkdone") {
2090 thread_sp->SetStopInfo(
2096 if (!handled && signo && !did_exec) {
2117 thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
2127 thread_sp->SetThreadHitBreakpointSite();
2129 if (bp_site_sp->ValidForThisThread(*thread_sp)) {
2131 thread_sp->GetRegisterContext()->SetPC(
pc);
2132 thread_sp->SetStopInfo(
2134 *thread_sp, bp_site_sp->GetID()));
2137 thread_sp->SetStopInfo(invalid_stop_info_sp);
2143 thread_sp->SetStopInfo(
2147 *thread_sp, signo, description.c_str()));
2158 if (interrupt_thread)
2159 thread_sp = interrupt_thread;
2162 *thread_sp, signo, description.c_str()));
2166 if (!description.empty()) {
2169 const char *stop_info_desc = stop_info_sp->GetDescription();
2170 if (!stop_info_desc || !stop_info_desc[0])
2171 stop_info_sp->SetDescription(description.c_str());
2174 *thread_sp, description.c_str()));
2184 const std::string &description) {
2193 *thread_sp, signo, description.c_str()));
2202 static constexpr llvm::StringLiteral g_key_tid(
"tid");
2203 static constexpr llvm::StringLiteral g_key_name(
"name");
2204 static constexpr llvm::StringLiteral g_key_reason(
"reason");
2205 static constexpr llvm::StringLiteral g_key_metype(
"metype");
2206 static constexpr llvm::StringLiteral g_key_medata(
"medata");
2207 static constexpr llvm::StringLiteral g_key_qaddr(
"qaddr");
2208 static constexpr llvm::StringLiteral g_key_dispatch_queue_t(
2209 "dispatch_queue_t");
2210 static constexpr llvm::StringLiteral g_key_associated_with_dispatch_queue(
2211 "associated_with_dispatch_queue");
2212 static constexpr llvm::StringLiteral g_key_queue_name(
"qname");
2213 static constexpr llvm::StringLiteral g_key_queue_kind(
"qkind");
2214 static constexpr llvm::StringLiteral g_key_queue_serial_number(
"qserialnum");
2215 static constexpr llvm::StringLiteral g_key_registers(
"registers");
2216 static constexpr llvm::StringLiteral g_key_memory(
"memory");
2217 static constexpr llvm::StringLiteral g_key_description(
"description");
2218 static constexpr llvm::StringLiteral g_key_signal(
"signal");
2219 static constexpr llvm::StringLiteral g_key_added_binaries(
"added-binaries");
2220 static constexpr llvm::StringLiteral g_key_detailed_binaries_info(
2221 "detailed-binaries-info");
2226 std::string thread_name;
2228 std::string description;
2229 uint32_t exc_type = 0;
2230 std::vector<addr_t> exc_data;
2233 bool queue_vars_valid =
false;
2236 std::string queue_name;
2238 uint64_t queue_serial_number = 0;
2239 std::vector<addr_t> added_binaries;
2245 thread_dict->
ForEach([
this, &tid, &expedited_register_map, &thread_name,
2246 &signo, &reason, &description, &exc_type, &exc_data,
2247 &thread_dispatch_qaddr, &queue_vars_valid,
2248 &associated_with_dispatch_queue, &dispatch_queue_t,
2249 &queue_name, &queue_kind, &queue_serial_number,
2250 &added_binaries, &detailed_binaries_info](
2251 llvm::StringRef key,
2253 if (key == g_key_tid) {
2256 }
else if (key == g_key_metype) {
2258 exc_type =
object->GetUnsignedIntegerValue(0);
2259 }
else if (key == g_key_medata) {
2264 exc_data.push_back(object->GetUnsignedIntegerValue());
2268 }
else if (key == g_key_name) {
2269 thread_name = std::string(object->GetStringValue());
2270 }
else if (key == g_key_qaddr) {
2271 thread_dispatch_qaddr =
2273 }
else if (key == g_key_queue_name) {
2274 queue_vars_valid =
true;
2275 queue_name = std::string(object->GetStringValue());
2276 }
else if (key == g_key_queue_kind) {
2277 std::string queue_kind_str = std::string(object->GetStringValue());
2278 if (queue_kind_str ==
"serial") {
2279 queue_vars_valid =
true;
2281 }
else if (queue_kind_str ==
"concurrent") {
2282 queue_vars_valid =
true;
2285 }
else if (key == g_key_queue_serial_number) {
2286 queue_serial_number =
object->GetUnsignedIntegerValue(0);
2287 if (queue_serial_number != 0)
2288 queue_vars_valid =
true;
2289 }
else if (key == g_key_dispatch_queue_t) {
2290 dispatch_queue_t =
object->GetUnsignedIntegerValue(0);
2292 queue_vars_valid =
true;
2293 }
else if (key == g_key_associated_with_dispatch_queue) {
2294 queue_vars_valid =
true;
2295 bool associated =
object->GetBooleanValue();
2300 }
else if (key == g_key_reason) {
2301 reason = std::string(object->GetStringValue());
2302 }
else if (key == g_key_description) {
2303 description = std::string(object->GetStringValue());
2304 }
else if (key == g_key_registers) {
2307 if (registers_dict) {
2309 [&expedited_register_map](llvm::StringRef key,
2312 if (llvm::to_integer(key, reg))
2313 expedited_register_map[reg] =
2314 std::string(object->GetStringValue());
2318 }
else if (key == g_key_memory) {
2324 if (mem_cache_dict) {
2327 "address", mem_cache_addr)) {
2329 llvm::StringRef str;
2334 const size_t byte_size = bytes.
GetStringRef().size() / 2;
2337 const size_t bytes_copied =
2339 if (bytes_copied == byte_size)
2349 }
else if (key == g_key_signal)
2351 else if (key == g_key_added_binaries) {
2354 array->
ForEach([&added_binaries](
2357 object->GetAsUnsignedInteger();
2361 added_binaries.push_back(value);
2366 }
else if (key == g_key_detailed_binaries_info) {
2371 if (object->GetAsDictionary()) {
2373 object->Dump(json_str);
2374 detailed_binaries_info =
2382 tid, expedited_register_map, signo, thread_name, reason, description,
2383 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2384 associated_with_dispatch_queue, dispatch_queue_t, queue_name, queue_kind,
2385 queue_serial_number, added_binaries, detailed_binaries_info);
2391 const char stop_type = stop_packet.
GetChar();
2392 switch (stop_type) {
2411 const uint8_t signo = stop_packet.
GetHexU8();
2412 llvm::StringRef key;
2413 llvm::StringRef value;
2414 std::string thread_name;
2416 std::string description;
2417 std::vector<addr_t> added_binaries;
2419 uint32_t exc_type = 0;
2420 std::vector<addr_t> exc_data;
2422 bool queue_vars_valid =
2426 std::string queue_name;
2428 uint64_t queue_serial_number = 0;
2432 if (key.compare(
"metype") == 0) {
2434 value.getAsInteger(16, exc_type);
2435 }
else if (key.compare(
"medata") == 0) {
2438 value.getAsInteger(16, x);
2439 exc_data.push_back(x);
2440 }
else if (key.compare(
"thread") == 0) {
2443 auto pid_tid = thread_id.
GetPidTid(pid);
2445 stop_pid = pid_tid->first;
2446 tid = pid_tid->second;
2449 }
else if (key.compare(
"threads") == 0) {
2450 std::lock_guard<std::recursive_mutex> guard(
2453 }
else if (key.compare(
"thread-pcs") == 0) {
2458 while (!value.empty()) {
2459 llvm::StringRef pc_str;
2460 std::tie(pc_str, value) = value.split(
',');
2461 if (pc_str.getAsInteger(16,
pc))
2465 }
else if (key.compare(
"jstopinfo") == 0) {
2474 }
else if (key.compare(
"hexname") == 0) {
2478 }
else if (key.compare(
"name") == 0) {
2479 thread_name = std::string(value);
2480 }
else if (key.compare(
"qaddr") == 0) {
2481 value.getAsInteger(16, thread_dispatch_qaddr);
2482 }
else if (key.compare(
"dispatch_queue_t") == 0) {
2483 queue_vars_valid =
true;
2484 value.getAsInteger(16, dispatch_queue_t);
2485 }
else if (key.compare(
"qname") == 0) {
2486 queue_vars_valid =
true;
2490 }
else if (key.compare(
"qkind") == 0) {
2491 queue_kind = llvm::StringSwitch<QueueKind>(value)
2496 }
else if (key.compare(
"qserialnum") == 0) {
2497 if (!value.getAsInteger(0, queue_serial_number))
2498 queue_vars_valid =
true;
2499 }
else if (key.compare(
"reason") == 0) {
2500 reason = std::string(value);
2501 }
else if (key.compare(
"description") == 0) {
2505 }
else if (key.compare(
"memory") == 0) {
2519 llvm::StringRef addr_str, bytes_str;
2520 std::tie(addr_str, bytes_str) = value.split(
'=');
2521 if (!addr_str.empty() && !bytes_str.empty()) {
2523 if (!addr_str.getAsInteger(0, mem_cache_addr)) {
2528 const size_t bytes_copied =
2530 if (bytes_copied == byte_size)
2534 }
else if (key.compare(
"watch") == 0 || key.compare(
"rwatch") == 0 ||
2535 key.compare(
"awatch") == 0) {
2538 value.getAsInteger(16, wp_addr);
2546 reason =
"watchpoint";
2548 ostr.
Printf(
"%" PRIu64, wp_addr);
2549 description = std::string(ostr.
GetString());
2550 }
else if (key.compare(
"swbreak") == 0 || key.compare(
"hwbreak") == 0) {
2551 reason =
"breakpoint";
2552 }
else if (key.compare(
"replaylog") == 0) {
2553 reason =
"history boundary";
2554 }
else if (key.compare(
"library") == 0) {
2560 }
else if (key.compare(
"fork") == 0 || key.compare(
"vfork") == 0) {
2566 LLDB_LOG(log,
"Invalid PID/TID to fork: {0}", value);
2572 ostr.
Printf(
"%" PRIu64
" %" PRIu64, pid_tid->first, pid_tid->second);
2573 description = std::string(ostr.
GetString());
2574 }
else if (key.compare(
"addressing_bits") == 0) {
2575 uint64_t addressing_bits;
2576 if (!value.getAsInteger(0, addressing_bits)) {
2579 }
else if (key.compare(
"low_mem_addressing_bits") == 0) {
2580 uint64_t addressing_bits;
2581 if (!value.getAsInteger(0, addressing_bits)) {
2584 }
else if (key.compare(
"high_mem_addressing_bits") == 0) {
2585 uint64_t addressing_bits;
2586 if (!value.getAsInteger(0, addressing_bits)) {
2589 }
else if (key ==
"added-binaries") {
2593 while (!value.empty()) {
2594 llvm::StringRef pc_str;
2595 std::tie(pc_str, value) = value.split(
',');
2596 if (pc_str.getAsInteger(16,
pc))
2598 added_binaries.push_back(
pc);
2600 }
else if (key ==
"detailed-binaries-info") {
2608 }
else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
2610 if (!key.getAsInteger(16, reg))
2611 expedited_register_map[reg] = std::string(std::move(value));
2621 "Received stop for incorrect PID = {0} (inferior PID = {1})",
2643 tid, expedited_register_map, signo, thread_name, reason, description,
2644 exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
2645 associated_with_dispatch_queue, dispatch_queue_t, queue_name,
2646 queue_kind, queue_serial_number, added_binaries,
2647 detailed_binaries_info);
2695 if (!selected_thread_sp ||
2696 selected_thread_sp->GetID() != primary_thread_sp->GetID())
2697 m_thread_list.SetSelectedThreadByID(primary_thread_sp->GetID());
2724 LLDB_LOGF(log,
"ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
2728 if (
error.Success())
2730 "ProcessGDBRemote::DoDetach() detach packet sent successfully");
2733 "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
2734 error.AsCString() ?
error.AsCString() :
"<unknown error>");
2737 if (!
error.Success())
2752 LLDB_LOGF(log,
"ProcessGDBRemote::DoDestroy()");
2755 int exit_status = SIGABRT;
2756 std::string exit_string;
2763 exit_status = kill_res.get();
2764#if defined(__APPLE__)
2776 if (platform_sp && platform_sp->IsHost()) {
2779 reap_pid = waitpid(
GetID(), &status, WNOHANG);
2780 LLDB_LOGF(log,
"Reaped pid: %d, status: %d.\n", reap_pid, status);
2784 exit_string.assign(
"killed");
2786 exit_string.assign(llvm::toString(kill_res.takeError()));
2789 exit_string.assign(
"killed or interrupted while attaching.");
2795 exit_string.assign(
"destroying when not connected to debugserver");
2816 const bool did_exec =
2817 response.
GetStringRef().find(
";reason:exec;") != std::string::npos;
2820 LLDB_LOGF(log,
"ProcessGDBRemote::SetLastStopPacket () - detected exec");
2825 m_gdb_comm.ResetDiscoverableSettings(did_exec);
2850 LLDB_LOG_ERROR(log, list.takeError(),
"Failed to read module list: {0}.");
2852 addr = list->m_link_map;
2872 const size_t n = thread_infos->
GetSize();
2873 for (
size_t i = 0; i < n; ++i) {
2889 xPacketState x_state =
m_gdb_comm.GetxPacketState();
2892 size_t max_memory_size = x_state != xPacketState::Unimplemented
2895 if (size > max_memory_size) {
2899 size = max_memory_size;
2904 packet_len = ::snprintf(packet,
sizeof(packet),
"%c%" PRIx64
",%" PRIx64,
2905 x_state != xPacketState::Unimplemented ?
'x' :
'm',
2906 (uint64_t)addr, (uint64_t)size);
2907 assert(packet_len + 1 < (
int)
sizeof(packet));
2910 if (
m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
2915 if (x_state != xPacketState::Unimplemented) {
2920 llvm::StringRef data_received = response.
GetStringRef();
2921 if (x_state == xPacketState::Prefixed &&
2922 !data_received.consume_front(
"b")) {
2924 "unexpected response to GDB server memory read packet '{0}': "
2926 packet, data_received);
2931 size_t memcpy_size = std::min(size, data_received.size());
2932 memcpy(buf, data_received.data(), memcpy_size);
2936 llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size),
'\xdd');
2940 "memory read failed for 0x%" PRIx64, addr);
2943 "GDB server does not support reading memory");
2946 "unexpected response to GDB server memory read packet '%s': '%s'",
2958 uint64_t max_packet_size,
2962 constexpr uint64_t range_overhead = 33;
2963 uint64_t current_size = 0;
2964 for (
auto [idx, range] : llvm::enumerate(ranges)) {
2965 uint64_t potential_size = current_size + range.size + range_overhead;
2966 if (potential_size > max_packet_size) {
2969 "MultiMemRead input has a range (base = {0:x}, size = {1}) "
2970 "bigger than the maximum allowed by remote",
2971 range.base, range.size);
2975 return ranges.size();
2978llvm::SmallVector<llvm::MutableArrayRef<uint8_t>>
2981 llvm::MutableArrayRef<uint8_t> buffer) {
2985 const llvm::ArrayRef<Range<lldb::addr_t, size_t>> original_ranges = ranges;
2986 llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> memory_regions;
2988 while (!ranges.empty()) {
2989 uint64_t num_ranges =
2991 if (num_ranges == 0)
2994 auto ranges_for_request = ranges.take_front(num_ranges);
2995 ranges = ranges.drop_front(num_ranges);
2997 llvm::Expected<StringExtractorGDBRemote> response =
3001 "MultiMemRead error response: {0}");
3005 llvm::StringRef response_str = response->GetStringRef();
3006 const unsigned expected_num_ranges = ranges_for_request.size();
3008 response_str, buffer, expected_num_ranges, memory_regions)) {
3010 "MultiMemRead error parsing response: {0}");
3014 return memory_regions;
3017llvm::Expected<StringExtractorGDBRemote>
3020 std::string packet_str;
3021 llvm::raw_string_ostream stream(packet_str);
3022 stream <<
"MultiMemRead:ranges:";
3024 auto range_to_stream = [&](
auto range) {
3026 stream << llvm::formatv(
"{0:x-},{1:x-}", range.base, range.size);
3028 llvm::interleave(ranges, stream, range_to_stream,
",");
3033 m_gdb_comm.SendPacketAndWaitForResponse(packet_str.data(), response,
3036 return llvm::createStringErrorV(
"MultiMemRead failed to send packet: '{0}'",
3040 return llvm::createStringErrorV(
"MultiMemRead failed: '{0}'",
3044 return llvm::createStringErrorV(
"MultiMemRead unexpected response: '{0}'",
3051 llvm::StringRef response_str, llvm::MutableArrayRef<uint8_t> buffer,
3052 unsigned expected_num_ranges,
3055 auto [sizes_str, memory_data] = response_str.split(
';');
3056 if (sizes_str.size() == response_str.size())
3057 return llvm::createStringErrorV(
3058 "MultiMemRead response missing field separator ';' in: '{0}'",
3062 for (llvm::StringRef size_str : llvm::split(sizes_str,
',')) {
3064 if (size_str.getAsInteger(16, read_size))
3065 return llvm::createStringErrorV(
3066 "MultiMemRead response has invalid size string: {0}", size_str);
3068 if (memory_data.size() < read_size)
3069 return llvm::createStringErrorV(
"MultiMemRead response did not have "
3070 "enough data, requested sizes: {0}",
3073 llvm::StringRef region_to_read = memory_data.take_front(read_size);
3074 memory_data = memory_data.drop_front(read_size);
3076 assert(buffer.size() >= read_size);
3077 llvm::MutableArrayRef<uint8_t> region_to_write =
3078 buffer.take_front(read_size);
3079 buffer = buffer.drop_front(read_size);
3081 memcpy(region_to_write.data(), region_to_read.data(), read_size);
3082 memory_regions.push_back(region_to_write);
3085 return llvm::Error::success();
3089 return m_gdb_comm.GetMemoryTaggingSupported();
3092llvm::Expected<std::vector<uint8_t>>
3099 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3100 "Error reading memory tags from remote");
3104 llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
3105 std::vector<uint8_t> got;
3106 got.reserve(tag_data.size());
3107 std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
3113 const std::vector<uint8_t> &tags) {
3116 return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
3120 std::vector<ObjectFile::LoadableData> entries) {
3130 if (
error.Success())
3144 for (
size_t i = 0; i < size; ++i)
3169 if (blocksize == 0) {
3177 lldb::addr_t block_start_addr = addr - (addr % blocksize);
3178 size += (addr - block_start_addr);
3179 if ((size % blocksize) != 0)
3180 size += (blocksize - size % blocksize);
3196 auto overlap = last_range.GetRangeEnd() - range.
GetRangeBase();
3217 "flash erase failed for 0x%" PRIx64, addr);
3220 "GDB server does not support flashing");
3223 "unexpected response to GDB server flash erase packet '%s': '%s'",
3240 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"vFlashDone", response,
3250 "GDB server does not support flashing");
3253 "unexpected response to GDB server flash done packet: '%s'",
3268 if (size > max_memory_size) {
3272 size = max_memory_size;
3292 if (!
error.Success())
3294 packet.
Printf(
"vFlashWrite:%" PRIx64
":", addr);
3297 packet.
Printf(
"M%" PRIx64
",%" PRIx64
":", addr, (uint64_t)size);
3310 "memory write failed for 0x%" PRIx64, addr);
3313 "GDB server does not support writing memory");
3316 "unexpected response to GDB server memory write packet '%s': '%s'",
3326 uint32_t permissions,
3332 allocated_addr =
m_gdb_comm.AllocateMemory(size, permissions);
3335 return allocated_addr;
3341 if (permissions & lldb::ePermissionsReadable)
3343 if (permissions & lldb::ePermissionsWritable)
3345 if (permissions & lldb::ePermissionsExecutable)
3354 "ProcessGDBRemote::%s no direct stub support for memory "
3355 "allocation, and InferiorCallMmap also failed - is stub "
3356 "missing register context save/restore capability?",
3363 "unable to allocate %" PRIu64
" bytes of memory with permissions %s",
3367 return allocated_addr;
3382 return m_gdb_comm.GetWatchpointReportedAfter();
3389 switch (supported) {
3394 "tried to deallocate memory without ever allocating memory");
3400 "unable to deallocate memory at 0x%" PRIx64, addr);
3412 "unable to deallocate memory at 0x%" PRIx64, addr);
3445 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3447 if (error_no == 0) {
3450 return llvm::Error::success();
3453 if (error_no != UINT8_MAX)
3454 return llvm::createStringErrorV(
3455 "error sending the breakpoint request: {0}", error_no);
3456 return llvm::createStringError(
"error sending the breakpoint request");
3458 LLDB_LOG(log,
"Software breakpoints are unsupported");
3463 uint8_t error_no = gdb_comm.SendGDBStoppointTypePacket(
3465 if (error_no == 0) {
3468 return llvm::Error::success();
3471 if (error_no != UINT8_MAX)
3472 return llvm::createStringErrorV(
3473 "error sending the hardware breakpoint request: {0} "
3474 "(hardware breakpoint resources might be exhausted or unavailable)",
3476 return llvm::createStringError(
3477 "error sending the hardware breakpoint request "
3478 "(hardware breakpoint resources might be exhausted or unavailable)");
3480 LLDB_LOG(log,
"Hardware breakpoints are unsupported");
3484 return llvm::createStringError(
"hardware breakpoints are not supported");
3500 return error.takeError();
3506 return llvm::createStringError(
"unknown error");
3511 return llvm::createStringError(
"unknown error");
3515 return llvm::Error::success();
3519 assert(bp_site !=
nullptr);
3530 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3531 ") address = 0x%" PRIx64,
3532 site_id, (uint64_t)addr);
3537 "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
3538 ") address = 0x%" PRIx64
" -- SUCCESS (already enabled)",
3539 site_id, (uint64_t)addr);
3547 assert(bp_site !=
nullptr);
3552 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3553 ") addr = 0x%8.8" PRIx64,
3554 site_id, (uint64_t)addr);
3558 "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
3559 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3560 site_id, (uint64_t)addr);
3571 bool read = wp_res_sp->WatchpointResourceRead();
3572 bool write = wp_res_sp->WatchpointResourceWrite();
3574 assert((read || write) &&
3575 "WatchpointResource type is neither read nor write");
3591 addr_t addr = wp_sp->GetLoadAddress();
3593 LLDB_LOGF(log,
"ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
")",
3595 if (wp_sp->IsEnabled()) {
3597 "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
3598 ") addr = 0x%8.8" PRIx64
": watchpoint already enabled.",
3599 watchID, (uint64_t)addr);
3603 bool read = wp_sp->WatchpointRead();
3604 bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
3605 size_t size = wp_sp->GetByteSize();
3608 WatchpointHardwareFeature supported_features =
3611 std::vector<WatchpointResourceSP> resources =
3613 addr, size, read, write, supported_features, target_arch);
3638 bool set_all_resources =
true;
3639 std::vector<WatchpointResourceSP> succesfully_set_resources;
3640 for (
const auto &wp_res_sp : resources) {
3641 addr_t addr = wp_res_sp->GetLoadAddress();
3642 size_t size = wp_res_sp->GetByteSize();
3644 if (!
m_gdb_comm.SupportsGDBStoppointPacket(type) ||
3645 m_gdb_comm.SendGDBStoppointTypePacket(type,
true, addr, size,
3647 set_all_resources =
false;
3650 succesfully_set_resources.push_back(wp_res_sp);
3653 if (set_all_resources) {
3654 wp_sp->SetEnabled(
true, notify);
3655 for (
const auto &wp_res_sp : resources) {
3658 wp_res_sp->AddConstituent(wp_sp);
3666 for (
const auto &wp_res_sp : succesfully_set_resources) {
3667 addr_t addr = wp_res_sp->GetLoadAddress();
3668 size_t size = wp_res_sp->GetByteSize();
3670 m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3674 "Setting one of the watchpoint resources failed");
3690 addr_t addr = wp_sp->GetLoadAddress();
3693 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3694 ") addr = 0x%8.8" PRIx64,
3695 watchID, (uint64_t)addr);
3697 if (!wp_sp->IsEnabled()) {
3699 "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
3700 ") addr = 0x%8.8" PRIx64
" -- SUCCESS (already disabled)",
3701 watchID, (uint64_t)addr);
3705 wp_sp->SetEnabled(
false, notify);
3709 if (wp_sp->IsHardware()) {
3710 bool disabled_all =
true;
3712 std::vector<WatchpointResourceSP> unused_resources;
3714 if (wp_res_sp->ConstituentsContains(wp_sp)) {
3716 addr_t addr = wp_res_sp->GetLoadAddress();
3717 size_t size = wp_res_sp->GetByteSize();
3718 if (
m_gdb_comm.SendGDBStoppointTypePacket(type,
false, addr, size,
3720 disabled_all =
false;
3722 wp_res_sp->RemoveConstituent(wp_sp);
3723 if (wp_res_sp->GetNumberOfConstituents() == 0)
3724 unused_resources.push_back(wp_res_sp);
3728 for (
auto &wp_res_sp : unused_resources)
3731 wp_sp->SetEnabled(
false, notify);
3734 "Failure disabling one of the watchpoint locations");
3747 LLDB_LOGF(log,
"ProcessGDBRemote::DoSignal (signal = %d)", signo);
3762 if (platform_sp && !platform_sp->IsHost())
3767 const char *error_string =
error.AsCString();
3768 if (error_string ==
nullptr)
3777 static FileSpec g_debugserver_file_spec;
3784 std::string env_debugserver_path = host_env.lookup(
"LLDB_DEBUGSERVER_PATH");
3785 if (!env_debugserver_path.empty()) {
3786 debugserver_file_spec.
SetFile(env_debugserver_path,
3787 FileSpec::Style::native);
3788 LLDB_LOG(log,
"gdb-remote stub exe path set from environment variable: {0}",
3789 env_debugserver_path);
3791 debugserver_file_spec = g_debugserver_file_spec;
3793 return debugserver_file_spec;
3796 debugserver_file_spec = HostInfo::GetSupportExeDir();
3797 if (debugserver_file_spec) {
3800 LLDB_LOG(log,
"found gdb-remote stub exe '{0}'", debugserver_file_spec);
3802 g_debugserver_file_spec = debugserver_file_spec;
3805 if (!debugserver_file_spec) {
3808 LLDB_LOG(log,
"could not find gdb-remote stub exe '{0}'",
3809 debugserver_file_spec);
3813 g_debugserver_file_spec.
Clear();
3816 return debugserver_file_spec;
3821 using namespace std::placeholders;
3831 const std::weak_ptr<ProcessGDBRemote> this_wp =
3832 std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
3839#if defined(__APPLE__)
3843 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
3845 struct kinfo_proc processInfo;
3846 size_t bufsize =
sizeof(processInfo);
3847 if (sysctl(mib, (
unsigned)(
sizeof(mib) /
sizeof(
int)), &processInfo, &bufsize,
3850 if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
3851 debugserver_path =
FileSpec(
"/Library/Apple/usr/libexec/oah/debugserver");
3858 "'. Please ensure it is properly installed "
3859 "and available in your PATH");
3874 debugserver_launch_info,
nullptr);
3879 LLDB_LOGF(log,
"failed to start debugserver process: %s",
3889 m_gdb_comm.SetConnection(std::make_unique<ConnectionFileDescriptor>(
3890 std::move(socket_pair->second)));
3904 std::weak_ptr<ProcessGDBRemote> process_wp,
lldb::pid_t debugserver_pid,
3913 "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
3914 ", signo=%i (0x%x), exit_status=%i)",
3915 __FUNCTION__, debugserver_pid, signo, signo, exit_status);
3917 std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
3918 LLDB_LOGF(log,
"ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
3919 static_cast<void *
>(process_sp.get()));
3920 if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
3926 std::this_thread::sleep_for(std::chrono::milliseconds(500));
3930 const StateType state = process_sp->GetState();
3939 llvm::StringRef signal_name =
3940 process_sp->GetUnixSignals()->GetSignalAsStringRef(signo);
3942 if (!signal_name.empty())
3943 stream.
Format(format_str, signal_name);
3945 stream.
Format(format_str, signo);
3947 process_sp->SetExitStatus(-1, stream.
GetString());
3970 debugger, PluginProperties::GetSettingName())) {
3971 const bool is_global_setting =
true;
3974 "Properties for the gdb-remote process plug-in.", is_global_setting);
3981 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
3988 llvm::Expected<HostThread> async_thread =
3992 if (!async_thread) {
3994 "failed to launch host thread: {0}");
4000 "ProcessGDBRemote::%s () - Called when Async thread was "
4010 LLDB_LOGF(log,
"ProcessGDBRemote::%s ()", __FUNCTION__);
4025 "ProcessGDBRemote::%s () - Called when Async thread was not running.",
4031 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread starting...",
4032 __FUNCTION__,
GetID());
4050 "ProcessGDBRemote::%s(pid = %" PRIu64
4051 ") listener.WaitForEvent (NULL, event_sp)...",
4052 __FUNCTION__,
GetID());
4055 const uint32_t event_type = event_sp->GetType();
4058 "ProcessGDBRemote::%s(pid = %" PRIu64
4059 ") Got an event of type: %d...",
4060 __FUNCTION__,
GetID(), event_type);
4062 switch (event_type) {
4067 if (continue_packet) {
4068 const char *continue_cstr =
4069 (
const char *)continue_packet->
GetBytes();
4070 const size_t continue_cstr_len = continue_packet->
GetByteSize();
4072 "ProcessGDBRemote::%s(pid = %" PRIu64
4073 ") got eBroadcastBitAsyncContinue: %s",
4074 __FUNCTION__,
GetID(), continue_cstr);
4076 if (::strstr(continue_cstr,
"vAttach") ==
nullptr)
4083 llvm::StringRef(continue_cstr, continue_cstr_len),
4094 switch (stop_state) {
4107 int exit_status = response.
GetHexU8();
4108 std::string desc_string;
4110 llvm::StringRef desc_str;
4111 llvm::StringRef desc_token;
4113 if (desc_token !=
"description")
4128 if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4131 "System Integrity Protection");
4132 }
else if (::strstr(continue_cstr,
"vAttach") !=
nullptr &&
4152 "ProcessGDBRemote::%s(pid = %" PRIu64
4153 ") got eBroadcastBitAsyncThreadShouldExit...",
4154 __FUNCTION__,
GetID());
4160 "ProcessGDBRemote::%s(pid = %" PRIu64
4161 ") got unknown event 0x%8.8x",
4162 __FUNCTION__,
GetID(), event_type);
4169 "ProcessGDBRemote::%s(pid = %" PRIu64
4170 ") listener.WaitForEvent (NULL, event_sp) => false",
4171 __FUNCTION__,
GetID());
4176 LLDB_LOGF(log,
"ProcessGDBRemote::%s(pid = %" PRIu64
") thread exiting...",
4177 __FUNCTION__,
GetID());
4209 LLDB_LOGF(log,
"Hit New Thread Notification breakpoint.");
4216class AcceleratorBreakpointCallbackBaton
4217 :
public TypedBaton<AcceleratorBreakpointHitArgs> {
4219 explicit AcceleratorBreakpointCallbackBaton(
4220 std::unique_ptr<AcceleratorBreakpointHitArgs> data)
4239 "ProcessGDBRemote::HandleAcceleratorActions skipping already "
4240 "processed actions for plugin '{0}' with identifier {1}",
4242 return llvm::Error::success();
4259 return llvm::Error::success();
4269 std::string exe_path = connect_info.
exe_path.value_or(
"");
4273 &platform_options, accelerator_target_sp);
4275 return error.takeError();
4276 if (!accelerator_target_sp)
4277 return llvm::createStringError(
"failed to create accelerator target");
4279 PlatformSP platform_sp = accelerator_target_sp->GetPlatform();
4281 return llvm::createStringErrorV(
4282 "no platform '{0}' compatible with triple '{1}' for the accelerator "
4287 ? platform_sp->ConnectProcessSynchronous(
4291 : platform_sp->ConnectProcess(connect_info.
connect_url,
4293 accelerator_target_sp.get(),
error);
4295 return error.takeError();
4297 return llvm::createStringError(
"failed to connect to the accelerator");
4299 accelerator_target_sp->SetTargetSessionName(actions.
session_name);
4302 auto event_sp = std::make_shared<Event>(
4305 accelerator_target_sp));
4307 return llvm::Error::success();
4313 llvm::Error
error = llvm::Error::success();
4317 auto args_up = std::make_unique<AcceleratorBreakpointHitArgs>();
4319 args_up->breakpoint = bp;
4326 error = llvm::joinErrors(
4328 llvm::createStringErrorV(
4329 "accelerator breakpoint {0} specifies both a by_name and a "
4330 "by_address specification",
4338 bp_modules.
GetSize() ? &bp_modules :
nullptr,
4340 bp.
by_name->function_name.c_str(),
4341 eFunctionNameTypeFull,
4353 error = llvm::joinErrors(
4355 llvm::createStringErrorV(
4356 "accelerator breakpoint {0} has neither a by_name nor a "
4357 "by_address specification",
4363 error = llvm::joinErrors(
4365 llvm::createStringErrorV(
"failed to set accelerator breakpoint {0}",
4373 llvm::formatv(
"accelerator-plugin ({0})", actions.
plugin_name);
4374 bp_sp->SetBreakpointKind(kind.c_str());
4375 auto baton_sp = std::make_shared<AcceleratorBreakpointCallbackBaton>(
4376 std::move(args_up));
4404 for (
size_t i = 0; i < symbol_names.size(); ++i) {
4412 addr_t load_addr = sc.symbol->GetAddress().GetLoadAddress(&target);
4421 llvm::Expected<AcceleratorBreakpointHitResponse> response =
4425 "accelerator breakpoint hit notification failed: {0}");
4433 if (response->disable_bp) {
4435 bp_sp->SetEnabled(
false);
4440 if (response->actions) {
4444 std::string message = llvm::toString(std::move(
error));
4445 LLDB_LOG(log,
"failed to handle accelerator actions: {0}", message);
4447 "error: accelerator plugin '%s': %s\n",
4448 response->actions->plugin_name.c_str(), message.c_str());
4453 return !response->auto_resume_native;
4458 LLDB_LOG(log,
"Check if need to update ignored signals");
4472 LLDB_LOG(log,
"Signals' version hasn't changed. version={0}",
4477 auto signals_to_ignore =
4482 "Signals' version changed. old version={0}, new version={1}, "
4483 "signals ignored={2}, update result={3}",
4485 signals_to_ignore.size(),
error);
4487 if (
error.Success())
4502 platform_sp->SetThreadCreationBreakpoint(
GetTarget());
4505 log,
"Successfully created new thread notification breakpoint %i",
4510 LLDB_LOGF(log,
"Failed to create new thread notification breakpoint.");
4539 return_value =
m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
4540 if (return_value != 0) {
4543 "Sending events is not supported for this process.");
4553 if (
m_gdb_comm.GetQXferAuxvReadSupported()) {
4554 llvm::Expected<std::string> response =
m_gdb_comm.ReadExtFeature(
"auxv",
"");
4556 buf = std::make_shared<DataBufferHeap>(response->c_str(),
4557 response->length());
4568 if (
m_gdb_comm.GetThreadExtendedInfoSupported()) {
4574 args_dict->GetAsDictionary()->AddIntegerItem(
"thread", tid);
4577 packet <<
"jThreadExtendedInfo:";
4578 args_dict->Dump(packet,
false);
4585 packet << (char)(0x7d ^ 0x20);
4594 if (!response.
Empty()) {
4607 args_dict->GetAsDictionary()->AddIntegerItem(
"image_list_address",
4608 image_list_address);
4609 args_dict->GetAsDictionary()->AddIntegerItem(
"image_count", image_count);
4616 std::string info_level_str;
4618 info_level_str =
"address-only";
4620 info_level_str =
"address-name";
4622 info_level_str =
"address-name-uuid";
4624 info_level_str =
"full";
4626 return info_level_str;
4633 args_dict->GetAsDictionary()->AddBooleanItem(
"fetch_all_solibs",
true);
4635 args_dict->GetAsDictionary()->AddBooleanItem(
"report_load_commands",
false);
4637 if (!info_level_str.empty())
4638 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4639 info_level_str.c_str());
4646 const std::vector<lldb::addr_t> &load_addresses) {
4650 for (
auto addr : load_addresses)
4651 addresses->AddIntegerItem(addr);
4653 args_dict->GetAsDictionary()->AddItem(
"solib_addresses", addresses);
4656 if (!info_level_str.empty())
4657 args_dict->GetAsDictionary()->AddStringItem(
"information-level",
4658 info_level_str.c_str());
4668 if (
m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
4671 std::chrono::seconds(10));
4674 packet <<
"jGetLoadedDynamicLibrariesInfos:";
4675 args_dict->Dump(packet,
false);
4682 packet << (char)(0x7d ^ 0x20);
4691 if (!response.
Empty()) {
4704 if (
m_gdb_comm.GetDynamicLoaderProcessStateSupported()) {
4707 if (
m_gdb_comm.SendPacketAndWaitForResponse(
"jGetDyldProcessState",
4713 if (!response.
Empty()) {
4730 packet <<
"jGetSharedCacheInfo:";
4731 args_dict->Dump(packet,
false);
4740 if (response.
Empty())
4749 if (!dict->
HasKey(
"shared_cache_uuid"))
4751 llvm::StringRef uuid_str;
4753 uuid_str ==
"00000000-0000-0000-0000-000000000000")
4755 if (dict->
HasKey(
"shared_cache_path")) {
4769 HostInfo::SharedCacheIndexFiles(sc_path, uuid, sc_mode);
4780 return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
4793 const uint64_t reasonable_largeish_default = 128 * 1024;
4794 const uint64_t conservative_default = 512;
4797 uint64_t stub_max_size =
m_gdb_comm.GetRemoteMaxPacketSize();
4798 if (stub_max_size !=
UINT64_MAX && stub_max_size != 0) {
4804 if (stub_max_size > reasonable_largeish_default) {
4805 stub_max_size = reasonable_largeish_default;
4811 if (stub_max_size > 70)
4812 stub_max_size -= 32 + 32 + 6;
4817 LLDB_LOG(log,
"warning: Packet size is too small. "
4818 "LLDB may face problems while writing memory");
4829 uint64_t user_specified_max) {
4830 if (user_specified_max != 0) {
4858 module_spec = cached->second;
4859 return bool(module_spec);
4862 if (!
m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
4863 LLDB_LOGF(log,
"ProcessGDBRemote::%s - failed to get module info for %s:%s",
4864 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4871 module_spec.
Dump(stream);
4872 LLDB_LOGF(log,
"ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
4873 __FUNCTION__, module_file_spec.
GetPath().c_str(),
4882 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4883 auto module_specs =
m_gdb_comm.GetModulesInfo(module_file_specs, triple);
4885 for (
const FileSpec &spec : module_file_specs)
4890 triple.getTriple())] = spec;
4904typedef std::vector<std::string> stringVec;
4906typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
4907struct RegisterSetInfo {
4911typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
4913struct GdbServerTargetInfo {
4917 RegisterSetMap reg_set_map;
4934 std::map<uint64_t, FieldEnum::Enumerator> enumerators;
4937 "evalue", [&enumerators, &log](
const XMLNode &enumerator_node) {
4938 std::optional<llvm::StringRef> name;
4939 std::optional<uint64_t> value;
4942 [&name, &value, &log](
const llvm::StringRef &attr_name,
4943 const llvm::StringRef &attr_value) {
4944 if (attr_name ==
"name") {
4945 if (attr_value.size())
4948 LLDB_LOG(log,
"ProcessGDBRemote::ParseEnumEvalues "
4949 "Ignoring empty name in evalue");
4950 }
else if (attr_name ==
"value") {
4951 uint64_t parsed_value = 0;
4952 if (llvm::to_integer(attr_value, parsed_value))
4953 value = parsed_value;
4956 "ProcessGDBRemote::ParseEnumEvalues "
4957 "Invalid value \"{0}\" in "
4962 "ProcessGDBRemote::ParseEnumEvalues Ignoring "
4963 "unknown attribute "
4964 "\"{0}\" in evalue",
4972 enumerators.insert_or_assign(
4973 *value, FieldEnum::Enumerator(*value, name->str()));
4980 for (
auto [_, enumerator] : enumerators)
4981 final_enumerators.push_back(enumerator);
4983 return final_enumerators;
4987ParseEnums(XMLNode feature_node,
4988 llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
4993 "enum", [log, ®isters_enum_types](
const XMLNode &enum_node) {
4997 const llvm::StringRef &attr_value) {
4998 if (attr_name ==
"id")
5016 if (!enumerators.empty()) {
5018 "ProcessGDBRemote::ParseEnums Found enum type \"{0}\"",
5020 registers_enum_types.insert_or_assign(
5021 id, std::make_unique<FieldEnum>(
id, enumerators));
5030static std::vector<RegisterFlags::Field> ParseFlagsFields(
5031 XMLNode flags_node,
unsigned size,
5032 const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
5034 const unsigned max_start_bit = size * 8 - 1;
5037 std::vector<RegisterFlags::Field> fields;
5039 ®isters_enum_types](
5042 std::optional<llvm::StringRef> name;
5043 std::optional<unsigned> start;
5044 std::optional<unsigned> end;
5045 std::optional<llvm::StringRef> type;
5048 &log](
const llvm::StringRef &attr_name,
5049 const llvm::StringRef &attr_value) {
5052 if (attr_name ==
"name") {
5055 "ProcessGDBRemote::ParseFlagsFields Found field node name \"{0}\"",
5058 }
else if (attr_name ==
"start") {
5059 unsigned parsed_start = 0;
5060 if (llvm::to_integer(attr_value, parsed_start)) {
5061 if (parsed_start > max_start_bit) {
5063 "ProcessGDBRemote::ParseFlagsFields Invalid start {0} in "
5066 parsed_start, max_start_bit);
5068 start = parsed_start;
5072 "ProcessGDBRemote::ParseFlagsFields Invalid start \"{0}\" in "
5076 }
else if (attr_name ==
"end") {
5077 unsigned parsed_end = 0;
5078 if (llvm::to_integer(attr_value, parsed_end))
5079 if (parsed_end > max_start_bit) {
5081 "ProcessGDBRemote::ParseFlagsFields Invalid end {0} in "
5084 parsed_end, max_start_bit);
5089 "ProcessGDBRemote::ParseFlagsFields Invalid end \"{0}\" in "
5093 }
else if (attr_name ==
"type") {
5098 "ProcessGDBRemote::ParseFlagsFields Ignoring unknown attribute "
5099 "\"{0}\" in field node",
5106 if (name && start && end) {
5110 "ProcessGDBRemote::ParseFlagsFields Start {0} > end {1} in field "
5111 "\"{2}\", ignoring",
5112 *start, *end, name->data());
5116 "ProcessGDBRemote::ParseFlagsFields Ignoring field \"{}\" "
5117 "that has size > 64 bits, this is not supported",
5121 const FieldEnum *enum_type =
nullptr;
5122 if (type && !type->empty()) {
5123 auto found = registers_enum_types.find(*type);
5124 if (found != registers_enum_types.end()) {
5125 enum_type = found->second.get();
5128 uint64_t max_value =
5131 if (enumerator.m_value > max_value) {
5132 enum_type =
nullptr;
5135 "ProcessGDBRemote::ParseFlagsFields In enum \"{0}\" "
5136 "evalue \"{1}\" with value {2} exceeds the maximum value "
5137 "of field \"{3}\" ({4}), ignoring enum",
5138 type->data(), enumerator.m_name, enumerator.m_value,
5139 name->data(), max_value);
5145 "ProcessGDBRemote::ParseFlagsFields Could not find type "
5147 "for field \"{1}\", ignoring",
5148 type->data(), name->data());
5153 RegisterFlags::Field(name->str(), *start, *end, enum_type));
5164 XMLNode feature_node,
5165 llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
5166 const llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
5171 [&log, ®isters_flags_types,
5172 ®isters_enum_types](
const XMLNode &flags_node) ->
bool {
5173 LLDB_LOG(log,
"ProcessGDBRemote::ParseFlags Found flags node \"{0}\"",
5176 std::optional<llvm::StringRef>
id;
5177 std::optional<unsigned> size;
5179 [&
id, &size, &log](
const llvm::StringRef &name,
5180 const llvm::StringRef &value) {
5183 }
else if (name ==
"size") {
5184 unsigned parsed_size = 0;
5185 if (llvm::to_integer(value, parsed_size))
5189 "ProcessGDBRemote::ParseFlags Invalid size \"{0}\" "
5195 "ProcessGDBRemote::ParseFlags Ignoring unknown "
5196 "attribute \"{0}\" in flags node",
5204 std::vector<RegisterFlags::Field> fields =
5205 ParseFlagsFields(flags_node, *size, registers_enum_types);
5206 if (fields.size()) {
5208 std::sort(fields.rbegin(), fields.rend());
5209 std::vector<RegisterFlags::Field>::const_iterator overlap =
5210 std::adjacent_find(fields.begin(), fields.end(),
5211 [](
const RegisterFlags::Field &lhs,
5212 const RegisterFlags::Field &rhs) {
5213 return lhs.Overlaps(rhs);
5217 if (overlap == fields.end()) {
5218 if (registers_flags_types.contains(*
id)) {
5232 "ProcessGDBRemote::ParseFlags Definition of flags "
5234 "previous definition, using original definition instead.",
5237 registers_flags_types.insert_or_assign(
5238 *
id, std::make_unique<RegisterFlags>(
id->str(), *size,
5239 std::move(fields)));
5243 std::vector<RegisterFlags::Field>::const_iterator next =
5247 "ProcessGDBRemote::ParseFlags Ignoring flags because fields "
5248 "{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) "
5250 overlap->GetName().c_str(), overlap->GetStart(),
5251 overlap->GetEnd(), next->GetName().c_str(), next->GetStart(),
5257 "ProcessGDBRemote::ParseFlags Ignoring definition of flags "
5258 "\"{0}\" because it contains no fields.",
5268 XMLNode feature_node, GdbServerTargetInfo &target_info,
5269 std::vector<DynamicRegisterInfo::Register> ®isters,
5270 llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types,
5271 llvm::StringMap<std::unique_ptr<FieldEnum>> ®isters_enum_types) {
5278 ParseEnums(feature_node, registers_enum_types);
5279 for (
const auto &enum_type : registers_enum_types)
5282 ParseFlags(feature_node, registers_flags_types, registers_enum_types);
5283 for (
const auto &flags : registers_flags_types)
5284 flags.second->DumpToLog(log);
5288 [&target_info, ®isters, ®isters_flags_types,
5289 log](
const XMLNode ®_node) ->
bool {
5290 std::string gdb_group;
5291 std::string gdb_type;
5292 DynamicRegisterInfo::Register reg_info;
5293 bool encoding_set =
false;
5294 bool format_set =
false;
5298 &encoding_set, &format_set, ®_info,
5299 log](
const llvm::StringRef &name,
5300 const llvm::StringRef &value) ->
bool {
5301 if (name ==
"name") {
5303 }
else if (name ==
"bitsize") {
5304 if (llvm::to_integer(value, reg_info.
byte_size))
5306 llvm::divideCeil(reg_info.
byte_size, CHAR_BIT);
5307 }
else if (name ==
"type") {
5308 gdb_type = value.str();
5309 }
else if (name ==
"group") {
5310 gdb_group = value.str();
5311 }
else if (name ==
"regnum") {
5313 }
else if (name ==
"offset") {
5315 }
else if (name ==
"altname") {
5317 }
else if (name ==
"encoding") {
5318 encoding_set =
true;
5320 }
else if (name ==
"format") {
5326 llvm::StringSwitch<lldb::Format>(value)
5337 }
else if (name ==
"group_id") {
5339 llvm::to_integer(value, set_id);
5340 RegisterSetMap::const_iterator pos =
5341 target_info.reg_set_map.find(set_id);
5342 if (pos != target_info.reg_set_map.end())
5343 reg_info.
set_name = pos->second.name;
5344 }
else if (name ==
"gcc_regnum" || name ==
"ehframe_regnum") {
5346 }
else if (name ==
"dwarf_regnum") {
5348 }
else if (name ==
"generic") {
5350 }
else if (name ==
"value_regnums") {
5353 }
else if (name ==
"invalidate_regnums") {
5358 "ProcessGDBRemote::ParseRegisters unhandled reg "
5359 "attribute %s = %s",
5360 name.data(), value.data());
5365 if (!gdb_type.empty()) {
5367 llvm::StringMap<std::unique_ptr<RegisterFlags>>::iterator it =
5368 registers_flags_types.find(gdb_type);
5369 if (it != registers_flags_types.end()) {
5370 auto flags_type = it->second.get();
5371 if (reg_info.
byte_size == flags_type->GetSize())
5376 "ProcessGDBRemote::ParseRegisters Size of register flags {0} "
5377 "({1} bytes) for register {2} does not match the register "
5378 "size ({3} bytes). Ignoring this set of flags.",
5379 flags_type->GetID().c_str(), flags_type->GetSize(),
5386 if (!gdb_type.empty() && !(encoding_set || format_set)) {
5387 if (llvm::StringRef(gdb_type).starts_with(
"int")) {
5390 }
else if (gdb_type ==
"data_ptr" || gdb_type ==
"code_ptr") {
5393 }
else if (gdb_type ==
"float" || gdb_type ==
"ieee_single" ||
5394 gdb_type ==
"ieee_double") {
5397 }
else if (gdb_type ==
"aarch64v" ||
5398 llvm::StringRef(gdb_type).starts_with(
"vec") ||
5399 gdb_type ==
"i387_ext" || gdb_type ==
"uint128" ||
5412 "ProcessGDBRemote::ParseRegisters Could not determine lldb"
5413 "format and encoding for gdb type %s",
5423 if (!gdb_group.empty()) {
5434 "ProcessGDBRemote::{0} Skipping zero bitsize register {1}",
5435 __FUNCTION__, reg_info.
name);
5437 registers.push_back(reg_info);
5452 ArchSpec &arch_to_use, std::string xml_filename,
5453 std::vector<DynamicRegisterInfo::Register> ®isters) {
5455 llvm::Expected<std::string> raw =
m_gdb_comm.ReadExtFeature(
"features", xml_filename);
5456 if (errorToBool(raw.takeError()))
5461 if (xml_document.
ParseMemory(raw->c_str(), raw->size(),
5462 xml_filename.c_str())) {
5463 GdbServerTargetInfo target_info;
5464 std::vector<XMLNode> feature_nodes;
5470 const XMLNode &node) ->
bool {
5471 llvm::StringRef name = node.
GetName();
5472 if (name ==
"architecture") {
5474 }
else if (name ==
"osabi") {
5476 }
else if (name ==
"xi:include" || name ==
"include") {
5479 target_info.includes.push_back(href);
5480 }
else if (name ==
"feature") {
5481 feature_nodes.push_back(node);
5482 }
else if (name ==
"groups") {
5484 "group", [&target_info](
const XMLNode &node) ->
bool {
5486 RegisterSetInfo set_info;
5489 [&set_id, &set_info](
const llvm::StringRef &name,
5490 const llvm::StringRef &value) ->
bool {
5493 llvm::to_integer(value, set_id);
5500 target_info.reg_set_map[set_id] = set_info;
5513 feature_nodes.push_back(feature_node);
5515 const XMLNode &node) ->
bool {
5516 llvm::StringRef name = node.
GetName();
5517 if (name ==
"xi:include" || name ==
"include") {
5520 target_info.includes.push_back(href);
5534 if (!arch_to_use.
IsValid() && !target_info.arch.empty()) {
5536 arch_to_use.
SetTriple(llvm::StringSwitch<std::string>(target_info.arch)
5537 .Case(
"i386:x86-64",
"x86_64")
5538 .Case(
"riscv:rv64",
"riscv64")
5539 .Case(
"riscv:rv32",
"riscv32")
5540 .Default(target_info.arch) +
5548 for (
auto &feature_node : feature_nodes) {
5549 ParseRegisters(feature_node, target_info, registers,
5553 for (
const auto &include : target_info.includes) {
5565 std::vector<DynamicRegisterInfo::Register> ®isters,
5567 std::map<uint32_t, uint32_t> remote_to_local_map;
5568 uint32_t remote_regnum = 0;
5569 for (
auto it : llvm::enumerate(registers)) {
5577 remote_to_local_map[remote_reg_info.
regnum_remote] = it.index();
5583 auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) {
5584 auto lldb_regit = remote_to_local_map.find(process_regnum);
5585 return lldb_regit != remote_to_local_map.end() ? lldb_regit->second
5589 llvm::transform(remote_reg_info.value_regs,
5590 remote_reg_info.value_regs.begin(), proc_to_lldb);
5591 llvm::transform(remote_reg_info.invalidate_regs,
5592 remote_reg_info.invalidate_regs.begin(), proc_to_lldb);
5599 abi_sp->AugmentRegisterInfo(registers);
5609 if (!
m_gdb_comm.GetQXferFeaturesReadSupported())
5610 return llvm::createStringError(
5611 llvm::inconvertibleErrorCode(),
5612 "the debug server does not support \"qXfer:features:read\"");
5615 return llvm::createStringError(
5616 llvm::inconvertibleErrorCode(),
5617 "the debug server supports \"qXfer:features:read\", but LLDB does not "
5618 "have XML parsing enabled (check LLLDB_ENABLE_LIBXML2)");
5628 std::vector<DynamicRegisterInfo::Register> registers;
5636 ? llvm::ErrorSuccess()
5637 : llvm::createStringError(
5638 llvm::inconvertibleErrorCode(),
5639 "the debug server did not describe any registers");
5645 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5646 "XML parsing not available");
5649 LLDB_LOGF(log,
"ProcessGDBRemote::%s", __FUNCTION__);
5658 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries-svr4",
"");
5660 return raw.takeError();
5663 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5666 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5667 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5668 "Error reading noname.xml");
5672 return llvm::createStringError(
5673 llvm::inconvertibleErrorCode(),
5674 "Error finding library-list-svr4 xml element");
5679 if (!main_lm.empty())
5683 "library", [log, &list](
const XMLNode &library) ->
bool {
5688 [&module](
const llvm::StringRef &name,
5689 const llvm::StringRef &value) ->
bool {
5692 module.set_name(value.str());
5693 else if (name ==
"lm") {
5695 llvm::to_integer(value, uint_value);
5696 module.set_link_map(uint_value);
5697 }
else if (name ==
"l_addr") {
5700 llvm::to_integer(value, uint_value);
5701 module.set_base(uint_value);
5704 module.set_base_is_offset(true);
5705 }
else if (name ==
"l_ld") {
5707 llvm::to_integer(value, uint_value);
5708 module.set_dynamic(uint_value);
5717 bool base_is_offset;
5719 module.get_name(name);
5720 module.get_link_map(lm);
5721 module.get_base(base);
5722 module.get_base_is_offset(base_is_offset);
5723 module.get_dynamic(ld);
5726 "found (link_map:0x%08" PRIx64
", base:0x%08" PRIx64
5727 "[%s], ld:0x%08" PRIx64
", name:'%s')",
5728 lm, base, (base_is_offset ?
"offset" :
"absolute"), ld,
5737 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5738 (
int)list.
m_list.size());
5742 llvm::Expected<std::string> raw = comm.
ReadExtFeature(
"libraries",
"");
5745 return raw.takeError();
5747 LLDB_LOGF(log,
"parsing: %s", raw->c_str());
5750 if (!doc.
ParseMemory(raw->c_str(), raw->size(),
"noname.xml"))
5751 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5752 "Error reading noname.xml");
5756 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5757 "Error finding library-list xml element");
5761 "library", [log, &list](
const XMLNode &library) ->
bool {
5765 module.set_name(name);
5774 llvm::to_integer(address, address_value);
5775 module.set_base(address_value);
5777 module.set_base_is_offset(false);
5782 bool base_is_offset;
5783 module.get_name(name);
5784 module.get_base(base);
5785 module.get_base_is_offset(base_is_offset);
5787 LLDB_LOGF(log,
"found (base:0x%08" PRIx64
"[%s], name:'%s')", base,
5788 (base_is_offset ?
"offset" :
"absolute"), name.c_str());
5796 LLDB_LOGF(log,
"found %" PRId32
" modules in total",
5797 (
int)list.
m_list.size());
5800 return llvm::createStringError(llvm::inconvertibleErrorCode(),
5801 "Remote libraries not supported");
5808 bool value_is_offset) {
5823 return module_list.takeError();
5829 std::string mod_name;
5832 bool mod_base_is_offset;
5835 valid &= modInfo.
get_name(mod_name);
5836 valid &= modInfo.
get_base(mod_base);
5849 if (module_sp.get())
5850 new_modules.
Append(module_sp);
5853 if (new_modules.
GetSize() > 0) {
5858 for (
size_t i = 0; i < loaded_modules.
GetSize(); ++i) {
5862 for (
size_t j = 0; j < new_modules.
GetSize(); ++j) {
5871 removed_modules.
Append(loaded_module);
5875 loaded_modules.
Remove(removed_modules);
5876 m_process->GetTarget().ModulesDidUnload(removed_modules,
false);
5895 m_process->GetTarget().ModulesDidLoad(new_modules);
5898 return llvm::ErrorSuccess();
5907 std::string file_path = file.
GetPath(
false);
5908 if (file_path.empty())
5929 "Fetching file load address from remote server returned an error");
5939 "Unknown error happened during sending the load address packet");
5960 std::string input = data.str();
5967 size_t found, pos = 0, len = input.length();
5968 while ((found = input.find(
end_delimiter, pos)) != std::string::npos) {
5970 input.substr(pos, found).c_str());
5971 std::string profile_data =
5986 std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
5988 llvm::raw_string_ostream output_stream(output);
5989 llvm::StringRef name, value;
5993 if (name.compare(
"thread_used_id") == 0) {
5995 uint64_t thread_id = threadIDHexExtractor.
GetHexMaxU64(
false, 0);
5997 bool has_used_usec =
false;
5998 uint32_t curr_used_usec = 0;
5999 llvm::StringRef usec_name, usec_value;
6000 uint32_t input_file_pos = profileDataExtractor.
GetFilePos();
6002 if (usec_name ==
"thread_used_usec") {
6003 has_used_usec =
true;
6004 usec_value.getAsInteger(0, curr_used_usec);
6008 profileDataExtractor.
SetFilePos(input_file_pos);
6012 if (has_used_usec) {
6013 uint32_t prev_used_usec = 0;
6014 std::map<uint64_t, uint32_t>::iterator iterator =
6017 prev_used_usec = iterator->second;
6019 uint32_t real_used_usec = curr_used_usec - prev_used_usec;
6021 bool good_first_time =
6022 (prev_used_usec == 0) && (real_used_usec > 250000);
6023 bool good_subsequent_time =
6024 (prev_used_usec > 0) &&
6027 if (good_first_time || good_subsequent_time) {
6031 output_stream << name <<
":";
6033 output_stream << index_id <<
";";
6035 output_stream << usec_name <<
":" << usec_value <<
";";
6038 llvm::StringRef local_name, local_value;
6044 new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
6047 output_stream << name <<
":" << value <<
";";
6050 output_stream << name <<
":" << value <<
";";
6085 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6086 "qSaveCore returned an error");
6091 for (
auto x : llvm::split(response.
GetStringRef(),
';')) {
6092 if (x.consume_front(
"core-path:"))
6098 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6099 "qSaveCore returned no core path");
6102 FileSpec remote_core{llvm::StringRef(path)};
6108 platform.
Unlink(remote_core);
6110 return error.ToError();
6116 return llvm::createStringError(llvm::inconvertibleErrorCode(),
6117 "Unable to send qSaveCore");
6129 "GDBRemoteCommunicationClientBase::%s() received $J packet "
6130 "but was not a StructuredData packet: packet starts with "
6142 json_sp->Dump(json_str,
true);
6145 "ProcessGDBRemote::%s() "
6146 "received Async StructuredData packet: %s",
6147 __FUNCTION__, json_str.
GetData());
6150 "ProcessGDBRemote::%s"
6151 "() received StructuredData packet:"
6161 if (structured_data_sp)
6169 "Tests packet speeds of various sizes to determine "
6170 "the performance characteristics of the GDB remote "
6175 "The number of packets to send of each varying size "
6176 "(default is 1000).",
6179 "The maximum number of bytes to send in a packet. Sizes "
6180 "increase in powers of 2 while the size is less than or "
6181 "equal to this option value. (default 1024).",
6184 "The maximum number of bytes to receive in a packet. Sizes "
6185 "increase in powers of 2 while the size is less than or "
6186 "equal to this option value. (default 1024).",
6189 "Print the output as JSON data for easy parsing.", false, true) {
6209 if (!output_stream_sp)
6210 output_stream_sp =
m_interpreter.GetDebugger().GetAsyncOutputStream();
6213 const uint32_t num_packets =
6215 const uint64_t max_send =
m_max_send.GetOptionValue().GetCurrentValue();
6216 const uint64_t max_recv =
m_max_recv.GetOptionValue().GetCurrentValue();
6217 const bool json =
m_json.GetOptionValue().GetCurrentValue();
6218 const uint64_t k_recv_amount =
6221 num_packets, max_send, max_recv, k_recv_amount, json,
6246 "Dumps the packet history buffer. ", nullptr) {}
6267 interpreter,
"process plugin packet xfer-size",
6268 "Maximum size that lldb will try to read/write one one chunk.",
6279 "amount to be transferred when "
6290 uint64_t user_specified_max = strtoul(packet_size,
nullptr, 10);
6291 if (errno == 0 && user_specified_max != 0) {
6306 "Send a custom packet through the GDB remote "
6307 "protocol and print the answer. "
6308 "The packet header and footer will automatically "
6309 "be added to the packet prior to sending and "
6310 "stripped from the result.",
6321 "'%s' takes a one or more packet content arguments",
6329 for (
size_t i = 0; i < argc; ++i) {
6336 output_strm.
Printf(
" packet: %s\n", packet_cstr);
6337 std::string response_str = std::string(response.
GetStringRef());
6339 if (strstr(packet_cstr,
"qGetProfileData") !=
nullptr) {
6343 if (response_str.empty())
6344 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6357 "Send a qRcmd packet through the GDB remote protocol "
6358 "and print the response. "
6359 "The argument passed to this command will be hex "
6360 "encoded into a valid 'qRcmd' packet, sent and the "
6361 "response will be printed.") {}
6367 if (command.empty()) {
6384 [&output_strm](llvm::StringRef output) { output_strm << output; });
6387 const std::string &response_str = std::string(response.
GetStringRef());
6389 if (response_str.empty())
6390 output_strm.
PutCString(
"response: \nerror: UNIMPLEMENTED\n");
6402 "Commands that deal with GDB remote packets.",
6431 interpreter,
"process plugin",
6432 "Commands for operating on a ProcessGDBRemote process.",
6433 "process plugin <subcommand> [<subcommand-options>]") {
6444 m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(
6445 GetTarget().GetDebugger().GetCommandInterpreter());
6450 bool enable,
bool is_expression_fork) {
6456 if (!enable && is_expression_fork) {
6457 if (
auto entry =
GetTarget().GetEntryPointAddress())
6458 entry_addr = entry->GetOpcodeLoadAddress(&
GetTarget());
6472 "DidForkSwitchSoftwareBreakpoints: retaining expression-"
6473 "return trap at {0:x} in forked child",
6497 addr_t addr = wp_res_sp->GetLoadAddress();
6498 size_t size = wp_res_sp->GetByteSize();
6500 m_gdb_comm.SendGDBStoppointTypePacket(type, enable, addr, size,
6506 bool is_expression_fork) {
6515 bool overrode_follow_mode =
false;
6518 if (is_expression_fork) {
6519 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6520 "to parent during expression evaluation");
6522 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() overriding follow-fork-mode "
6523 "to parent during expression evaluation. Child process "
6524 "{0} is available for manual attachment.",
6528 overrode_follow_mode =
true;
6539 switch (follow_fork_mode) {
6541 follow_pid = parent_pid;
6542 follow_tid = parent_tid;
6543 detach_pid = child_pid;
6544 detach_tid = child_tid;
6547 follow_pid = child_pid;
6548 follow_tid = child_tid;
6549 detach_pid = parent_pid;
6550 detach_tid = parent_tid;
6555 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6556 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to set pid/tid");
6570 if (!
m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) ||
6571 !
m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) {
6572 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() unable to reset pid/tid");
6576 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6579 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6581 if (
error.Fail() && keep_stopped) {
6582 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach-and-stay-stopped not "
6583 "supported, falling back to normal detach");
6584 keep_stopped =
false;
6588 LLDB_LOG(log,
"ProcessGDBRemote::DidFork() detach packet send failed: {0}",
6589 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6595 if (overrode_follow_mode && !is_expression_fork) {
6599 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
6600 "'parent' because an expression is being evaluated.\n"
6601 "Child process %" PRIu64
6602 " has been detached%s.\n"
6603 "You can attach to it with: process attach -p %" PRIu64
6606 keep_stopped ?
" and stopped" :
" (running)",
6622 bool is_expression_fork) {
6627 "ProcessGDBRemote::DidVFork() called for child_pid: {0}, child_tid {1}",
6628 child_pid, child_tid);
6634 bool overrode_follow_mode =
false;
6637 if (is_expression_fork) {
6638 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6639 "to parent during expression evaluation");
6641 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() overriding follow-fork-mode "
6642 "to parent during expression evaluation. Child process "
6643 "{0} is available for manual attachment.",
6647 overrode_follow_mode =
true;
6657 switch (follow_fork_mode) {
6659 detach_pid = child_pid;
6660 detach_tid = child_tid;
6663 detach_pid =
m_gdb_comm.GetCurrentProcessID();
6669 if (!
m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) {
6670 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to set pid/tid");
6678 if (!
m_gdb_comm.SetCurrentThread(child_tid, child_pid) ||
6679 !
m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) {
6680 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() unable to reset pid/tid");
6686 LLDB_LOG(log,
"Detaching process {0}", detach_pid);
6687 bool keep_stopped = overrode_follow_mode && !is_expression_fork;
6689 if (
error.Fail() && keep_stopped) {
6690 LLDB_LOG(log,
"ProcessGDBRemote::DidVFork() detach-and-stay-stopped not "
6691 "supported, falling back to normal detach");
6692 keep_stopped =
false;
6697 "ProcessGDBRemote::DidVFork() detach packet send failed: {0}",
6698 error.AsCString() ?
error.AsCString() :
"<unknown error>");
6702 if (overrode_follow_mode && !is_expression_fork) {
6706 output_up->Printf(
"warning: follow-fork-mode 'child' was overridden to "
6707 "'parent' because an expression is being evaluated.\n"
6708 "Child process %" PRIu64
6709 " has been detached%s.\n"
6710 "You can attach to it with: process attach -p %" PRIu64
6713 keep_stopped ?
" and stopped" :
" (running)",
6746 llvm::Error joined = llvm::Error::success();
6747 for (
auto &[site, action] : site_to_action) {
6751 joined = llvm::joinErrors(std::move(joined), std::move(
error));
6759static llvm::SmallVector<std::optional<uint8_t>>
6761 llvm::SmallVector<std::optional<uint8_t>> results;
6765 parsed ? parsed->GetAsDictionary() :
nullptr;
6773 llvm::StringRef token;
6774 if (
auto *
string = object->GetAsString())
6775 token =
string->GetValue();
6776 if (token ==
"OK") {
6777 results.push_back(std::nullopt);
6780 if (token.size() != 3 || !token.starts_with(
"E")) {
6781 results.push_back(uint8_t(0xff));
6784 uint8_t error_code = 0;
6785 if (token.drop_front(1).getAsInteger(16, error_code))
6786 results.push_back(0xff);
6788 results.push_back(error_code);
6797static std::optional<GDBStoppointType>
6806 return std::nullopt;
6815 return std::nullopt;
6817 llvm_unreachable(
"unhandled BreakpointSite type");
6821struct BreakpointPacketInfo {
6822 BreakpointSite &site;
6823 size_t trap_opcode_size;
6828std::string to_string(
const BreakpointPacketInfo &info) {
6829 char packet = info.is_enable ?
'Z' :
'z';
6830 return llvm::formatv(
"{0}{1},{2:x-},{3:x-}", packet,
6832 info.trap_opcode_size)
6839 if (site_to_action.empty())
6840 return llvm::Error::success();
6841 if (!
m_gdb_comm.GetMultiBreakpointSupported())
6846 std::vector<BreakpointPacketInfo> breakpoint_infos;
6847 for (
auto [site, action] : site_to_action) {
6849 std::optional<GDBStoppointType> type =
6853 LLDB_LOG(log,
"MultiBreakpoint: site {0} at {1:x} can't be batched",
6854 site->GetID(), site->GetLoadAddress());
6858 breakpoint_infos.push_back(
6863 stream <<
"jMultiBreakpoint:";
6865 auto args_array = std::make_shared<StructuredData::Array>();
6866 for (
auto &bp_info : breakpoint_infos)
6867 args_array->AddStringItem(to_string(bp_info));
6870 packet_dict.
AddItem(
"breakpoint_requests", args_array);
6871 packet_dict.
Dump(stream,
false);
6875 llvm::Expected<StringExtractorGDBRemote> response =
6880 LLDB_LOG_ERROR(log, response.takeError(),
"jMultiBreakpoint failed: {0}");
6884 llvm::SmallVector<std::optional<uint8_t>> results =
6888 if (results.size() != breakpoint_infos.size())
6889 return llvm::createStringErrorV(
6890 "MultiBreakpoint response count mismatch (expected {0}, got {1})",
6891 site_to_action.size(), results.size());
6893 llvm::Error joined = llvm::Error::success();
6894 for (
auto [error_code, bp_info] :
6895 llvm::zip_equal(results, breakpoint_infos)) {
6898 auto error = llvm::createStringErrorV(
6899 "MultiBreakpoint: site {0} at {1:x} failed with E{2}",
6900 bp_info.site.GetID(), bp_info.site.GetLoadAddress(), error_code);
6901 joined = llvm::joinErrors(std::move(joined), std::move(
error));
6905 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={})
static lldb::ModuleSP LoadBinaryWithUUIDAndAddress(Process *process, llvm::StringRef name, UUID uuid, lldb::addr_t value, bool value_is_offset, bool force_symbol_search, bool notify, bool set_address_in_target, bool allow_memory_image_last_resort)
Find/load a binary into lldb given a UUID and the address where it is loaded in memory,...
virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Locates or creates a module given by file and updates/loads the resulting module at the virtual base ...
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
const void * GetBytes() const
static const EventDataBytes * GetEventDataFromEvent(const Event *event_ptr)
size_t GetByteSize() const
lldb::ProcessSP GetProcessSP() const
Get accessor that creates a strong reference from the weak process reference contained in this object...
std::vector< Enumerator > Enumerators
const Enumerators & GetEnumerators() const
void DumpToLog(Log *log) const
Represents a file descriptor action to be performed during process launch.
Action GetAction() const
Get the type of action.
const FileSpec & GetFileSpec() const
Get the file specification for open actions.
void 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(const char *name)
bool get_name(std::string &out) const
bool get_link_map(lldb::addr_t &out) const
bool get_base_is_offset(bool &out) const
bool get_base(lldb::addr_t &out) const
void add(const LoadedModuleInfo &mod)
std::vector< LoadedModuleInfo > m_list
void PutCString(const char *cstr)
LazyBool GetFlash() const
lldb::offset_t GetBlocksize() const
lldb::SymbolSharedCacheUse GetSharedCacheBinaryLoading() const
A collection class for Module objects.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
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)
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.
uint64_t GetMaxValue() const
The maximum unsigned value that could be contained in this field.
unsigned GetSizeInBits() const
Get size of the field in bits. Will always be at least 1.
virtual StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Status &error)
virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error)
Status CompleteSending(lldb::pid_t child_pid)
shared_fd_t GetSendableFD()
static llvm::Expected< Pair > CreatePair(std::optional< SocketProtocol > protocol=std::nullopt)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
static lldb::StopInfoSP CreateStopReasonWithMachException(Thread &thread, uint32_t exc_type, uint32_t exc_data_count, uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code, bool pc_already_adjusted=true, bool adjust_pc_if_needed=false)
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread)
static lldb::StopInfoSP CreateStopReasonVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonWithInterrupt(Thread &thread, int signo, const char *description)
static lldb::StopInfoSP CreateStopReasonWithSignal(Thread &thread, int signo, const char *description=nullptr, std::optional< int > code=std::nullopt)
static lldb::StopInfoSP CreateStopReasonFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonVForkDone(Thread &thread)
static lldb::StopInfoSP CreateStopReasonWithWatchpointID(Thread &thread, lldb::break_id_t watch_id, bool silently_continue=false)
static lldb::StopInfoSP CreateStopReasonWithException(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(Thread &thread, lldb::break_id_t break_id)
static lldb::StopInfoSP CreateStopReasonHistoryBoundary(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonProcessorTrace(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread)
void ForEach(std::function< void(StopPointSite *)> const &callback)
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
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...
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
llvm::StringMap< std::unique_ptr< FieldEnum > > m_registers_enum_types
Status EstablishConnectionIfNeeded(const ProcessInfo &process_info)
llvm::Error UpdateBreakpointSites(const BreakpointSiteToActionMap &site_to_action) override
bool UpdateThreadIDList()
static llvm::StringRef GetPluginNameStatic()
Status DoHalt(bool &caused_stop) override
Halts a running process.
uint64_t m_last_signals_version
llvm::Expected< TraceSupportedResponse > TraceSupported() override
Get the processor tracing type supported for this process.
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)
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
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a process.
std::optional< StringExtractorGDBRemote > m_last_stop_packet
CommandObject * GetPluginCommandObject() override
Return a multi-word command object that can be used to expose plug-in specific commands.
int64_t m_breakpoint_pc_offset
size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, Status &error) override
Actually do the writing of memory to a process.
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override
Launch a new process.
lldb::CommandObjectSP m_command_sp
void DidVForkDone() override
Called after reported vfork completion.
std::string HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &inputStringExtractor)
bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, std::string xml_filename, std::vector< DynamicRegisterInfo::Register > ®isters)
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.
llvm::StringMap< std::unique_ptr< RegisterFlags > > m_registers_flags_types
Status DoWillLaunch(Module *module) override
Called before launching to a process.
void DidAttach(ArchSpec &process_arch) override
Called after attaching a process.
llvm::Expected< bool > SaveCore(llvm::StringRef outfile) override
Save core dump into the specified file.
std::atomic< lldb::pid_t > m_debugserver_pid
llvm::Expected< std::string > TraceGetState(llvm::StringRef type) override
Get the current tracing state of the process and its threads.
bool IsAlive() override
Check if a process is still alive.
void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override
void SetQueueInfo(std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue)
void SetNewlyAddedBinaries(const std::vector< lldb::addr_t > &added_binaries)
void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr)
void PrivateSetRegisterUnavailable(uint32_t reg)
lldb::RegisterContextSP GetRegisterContext() override
void SetDetailedBinariesInfo(StructuredData::ObjectSP &detailed_info)
void SetAssociatedWithLibdispatchQueue(lldb_private::LazyBool associated_with_libdispatch_queue) override
bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef< uint8_t > data)
#define LLDB_INVALID_SITE_ID
#define LLDB_INVALID_WATCH_ID
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_THREAD_ID
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_INVALID_PROCESS_ID
#define LLDB_REGNUM_GENERIC_PC
lldb::ByteOrder InlHostByteOrder()
std::vector< DynamicRegisterInfo::Register > GetFallbackRegisters(const ArchSpec &arch_to_use)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length)
bool 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.
const RegisterFlags * flags_type
std::vector< uint32_t > value_regs
std::vector< uint32_t > invalidate_regs
static Status ToFormat(const char *s, lldb::Format &format, size_t *byte_size_ptr)
BaseType GetRangeBase() const
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
BaseType GetRangeEnd() const
void SetByteSize(SizeType s)
jLLDBTraceGetBinaryData gdb-remote packet
jLLDBTraceStop gdb-remote packet