11#include "lldb/Host/Config.h"
44#include "llvm/Support/JSON.h"
45#include "llvm/Support/ScopedPrinter.h"
46#include "llvm/TargetParser/Triple.h"
60enum GDBRemoteServerError {
63 eErrorNoProcess = eErrorFirst,
73 m_process_manager(process_manager), m_current_process(nullptr),
74 m_continue_process(nullptr), m_stdio_communication() {
229 bool &interrupt,
bool &quit) {
265 "%s: no process command line specified to launch", __FUNCTION__);
267 const bool should_forward_stdio =
274 if (should_forward_stdio) {
287 "process but one already exists");
297 SetEnabledExtensions(*m_current_process);
304 if (should_forward_stdio) {
309 "pid = {0}: setting up stdout/stderr redirection via $O "
310 "gdb-remote commands",
311 m_current_process->GetID());
314 auto terminal_fd = m_current_process->GetTerminalFileDescriptor();
315 if (terminal_fd >= 0) {
317 "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
318 "inferior STDIO fd to %d",
319 __FUNCTION__, terminal_fd);
320 Status status = SetSTDIOFileDescriptor(terminal_fd);
325 "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
326 "inferior STDIO since terminal fd reported as %d",
327 __FUNCTION__, terminal_fd);
331 "pid = {0} skipping stdout/stderr redirection via $O: inferior "
332 "will communicate over client-provided file descriptors",
333 m_current_process->GetID());
336 printf(
"Launched '%s' as process %" PRIu64
"...\n",
337 m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
338 m_current_process->GetID());
345 LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
352 "cannot attach to process %" PRIu64
353 " when another process with pid %" PRIu64
" is being debugged.",
360 llvm::errs() << llvm::formatv(
"failed to attach to process {0}: {1}\n", pid,
368 SetEnabledExtensions(*m_current_process);
371 auto terminal_fd = m_current_process->GetTerminalFileDescriptor();
372 if (terminal_fd >= 0) {
374 "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
375 "inferior STDIO fd to %d",
376 __FUNCTION__, terminal_fd);
377 Status status = SetSTDIOFileDescriptor(terminal_fd);
382 "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
383 "inferior STDIO since terminal fd reported as %d",
384 __FUNCTION__, terminal_fd);
387 printf(
"Attached to process %" PRIu64
"...\n", pid);
392 llvm::StringRef process_name,
bool include_existing) {
395 std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1);
401 process_name, llvm::sys::path::Style::native);
404 if (include_existing) {
405 LLDB_LOG(log,
"including existing processes in search");
409 LLDB_LOG(log,
"placed '{0}' processes in the exclusion list.",
410 exclusion_list.size());
413 LLDB_LOG(log,
"waiting for '{0}' to appear", process_name);
415 auto is_in_exclusion_list =
417 for (
auto &excluded : exclusion_list) {
418 if (excluded.GetProcessID() == info.GetProcessID())
426 loop_process_list.clear();
429 llvm::erase_if(loop_process_list, is_in_exclusion_list);
432 if (loop_process_list.size() == 1) {
433 auto matching_process_pid = loop_process_list[0].GetProcessID();
434 LLDB_LOG(log,
"found pid {0}", matching_process_pid);
439 if (loop_process_list.size() > 1) {
442 "Multiple executables with name: '{0}' found. Pids: ",
444 for (
size_t i = 0; i < loop_process_list.size() - 1; ++i) {
445 error_stream.
Format(
"{0}, ", loop_process_list[i].GetProcessID());
447 error_stream.
Format(
"{0}.", loop_process_list.back().GetProcessID());
455 LLDB_LOG(log,
"sleep {0} seconds", polling_interval);
456 std::this_thread::sleep_for(polling_interval);
462 assert(process &&
"process cannot be NULL");
466 "GDBRemoteCommunicationServerLLGS::%s called with "
467 "NativeProcessProtocol pid %" PRIu64
", current state: %s",
468 __FUNCTION__, process->
GetID(),
476 assert(process &&
"process cannot be NULL");
482 LLDB_LOG(log,
"pid = {0}, failed to retrieve process exit status",
487 response.
PutHex8(GDBRemoteServerError::eErrorExitStatus);
491 LLDB_LOG(log,
"pid = {0}, returning exit type {1}", process->
GetID(),
500 response.
Format(
"{0:g}", *wait_status);
503 response.
Format(
";process:{0:x-}", process->
GetID());
511 uint32_t buf_size,
bool swap) {
514 for (i = buf_size - 1; i >= 0; i--)
517 for (i = 0; i < buf_size; i++)
538 switch (reg_info.
format) {
548 return "vector-sint8";
550 return "vector-uint8";
552 return "vector-sint16";
554 return "vector-uint16";
556 return "vector-sint32";
558 return "vector-uint32";
560 return "vector-float32";
562 return "vector-uint64";
564 return "vector-uint128";
571 switch (reg_info.
kinds[RegisterKind::eRegisterKindGeneric]) {
611 response.
Printf(
"%" PRIx32, *reg_num);
613 response.
Printf(
"%" PRIu32, *reg_num);
625 reg_value_p = ®_value;
636 std::vector<uint8_t> zeros(reg_info.
byte_size,
'\0');
642static std::optional<json::Object>
648 json::Object register_object;
650#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
651 const auto expedited_regs =
654 const auto expedited_regs =
657 if (expedited_regs.empty())
660 for (
auto ®_num : expedited_regs) {
663 if (reg_info_p ==
nullptr) {
665 "%s failed to get register info for register index %" PRIu32,
666 __FUNCTION__, reg_num);
677 LLDB_LOGF(log,
"%s failed to read register '%s' index %" PRIu32
": %s",
679 reg_info_p->
name ? reg_info_p->
name :
"<unnamed-register>",
680 reg_num,
error.AsCString());
688 register_object.try_emplace(llvm::to_string(reg_num),
692 return register_object;
696 switch (stop_reason) {
710 return "processor trace";
718 return "async interrupt";
729static llvm::Expected<json::Array>
733 json::Array threads_array;
740 std::string description;
741 if (!thread.GetStopReason(tid_stop_info, description))
742 return llvm::make_error<llvm::StringError>(
743 "failed to get stop reason", llvm::inconvertibleErrorCode());
745 const int signum = tid_stop_info.
signo;
748 "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
750 " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
751 __FUNCTION__, process.
GetID(), tid, signum,
755 json::Object thread_obj;
759 thread_obj.try_emplace(
"registers", std::move(*registers));
762 thread_obj.try_emplace(
"tid",
static_cast<int64_t
>(tid));
765 thread_obj.try_emplace(
"signal", signum);
767 const std::string thread_name = thread.GetName();
768 if (!thread_name.empty())
769 thread_obj.try_emplace(
"name", thread_name);
773 thread_obj.try_emplace(
"reason", stop_reason);
775 if (!description.empty())
776 thread_obj.try_emplace(
"description", description);
780 thread_obj.try_emplace(
783 json::Array medata_array;
786 medata_array.push_back(
789 thread_obj.try_emplace(
"medata", std::move(medata_array));
791 threads_array.push_back(std::move(thread_obj));
793 return threads_array;
803 LLDB_LOG(log,
"preparing packet for pid {0} tid {1}", process.
GetID(),
809 std::string description;
821 int signum = tid_stop_info.
signo;
824 "pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}",
829 response.
PutHex8(signum & 0xff);
837 const std::string thread_name = thread.
GetName();
838 if (!thread_name.empty()) {
839 size_t thread_name_len = thread_name.length();
841 if (::strcspn(thread_name.c_str(),
"$#+-;:") == thread_name_len) {
863 uint32_t thread_num = 0;
867 response.
Printf(
"%" PRIx64, listed_thread.GetID());
877 if (thread_num > 1) {
878 const bool threads_with_valid_stop_info_only =
true;
884 unescaped_response.
AsRawOstream() << std::move(*threads_info);
889 "failed to prepare a jstopinfo field for pid {1}: {0}",
895 char delimiter =
':';
907 LLDB_LOGF(log,
"%s failed to read register '%s' index %" PRIu32
": %s",
909 reg_info_p->
name ? reg_info_p->
name :
"<unnamed-register>",
910 reg_to_read,
error.AsCString());
929 const auto expedited_regs =
932 for (
auto ®_num : expedited_regs) {
936 if (reg_info_p !=
nullptr && reg_info_p->
value_regs ==
nullptr) {
939 if (
error.Success()) {
940 response.
Printf(
"%.02x:", reg_num);
946 "GDBRemoteCommunicationServerLLGS::%s failed to read "
947 "register '%s' index %" PRIu32
": %s",
949 reg_info_p->
name ? reg_info_p->
name :
"<unnamed-register>",
950 reg_num,
error.AsCString());
956 if (reason_str !=
nullptr) {
957 response.
Printf(
"reason:%s;", reason_str);
960 if (!description.empty()) {
991 response.
Printf(
"%s:p%" PRIx64
".%" PRIx64
";", reason_str,
1008 if (response.
Empty())
1028 if (listed_thread.GetID() != thread_to_skip) {
1030 if (!stop_reply.
Empty())
1038 assert(process &&
"process cannot be NULL");
1041 LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
1044 *process, StateType::eStateExited,
false);
1047 "GDBRemoteCommunicationServerLLGS::%s failed to send stop "
1048 "notification for PID %" PRIu64
", state: eStateExited",
1049 __FUNCTION__, process->
GetID());
1080 assert(process &&
"process cannot be NULL");
1083 LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
1086 *process, StateType::eStateStopped,
false);
1089 "GDBRemoteCommunicationServerLLGS::%s failed to send stop "
1090 "notification for PID %" PRIu64
", state: eStateExited",
1091 __FUNCTION__, process->
GetID());
1097 assert(process &&
"process cannot be NULL");
1101 "GDBRemoteCommunicationServerLLGS::%s called with "
1102 "NativeProcessProtocol pid %" PRIu64
", state: %s",
1107 case StateType::eStateRunning:
1110 case StateType::eStateStopped:
1121 case StateType::eStateExited:
1132 "GDBRemoteCommunicationServerLLGS::%s didn't handle state "
1133 "change for pid %" PRIu64
", new state: %s",
1146 std::unique_ptr<NativeProcessProtocol> child_process) {
1158 bool interrupt =
false;
1163 std::chrono::microseconds(0),
error, interrupt, done);
1169 "GDBRemoteCommunicationServerLLGS::%s processing a packet "
1171 __FUNCTION__,
error.AsCString());
1179 std::unique_ptr<Connection> connection) {
1180 IOObjectSP read_object_sp = connection->GetReadObject();
1193 if ((buffer ==
nullptr) || (len == 0)) {
1212 std::unique_ptr<ConnectionFileDescriptor> conn_up(
1224 "failed to set connection for inferior I/O communication");
1246 LLDB_LOG(log,
"Failed to set up stdio forwarding: {0}",
error);
1260 buffer,
sizeof buffer, std::chrono::microseconds(0), status, &
error);
1271 "GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
1272 "forwarding as communication returned status %d (error: "
1274 __FUNCTION__, status,
error.AsCString());
1306 Expected<TraceStopRequest> stop_request =
1307 json::parse<TraceStopRequest>(packet.
Peek(),
"TraceStopRequest");
1327 Expected<TraceStartRequest> request =
1328 json::parse<TraceStartRequest>(packet.
Peek(),
"TraceStartRequest");
1348 Expected<TraceGetStateRequest> request =
1349 json::parse<TraceGetStateRequest>(packet.
Peek(),
"TraceGetStateRequest");
1366 llvm::Expected<TraceGetBinaryDataRequest> request =
1367 llvm::json::parse<TraceGetBinaryDataRequest>(packet.
Peek(),
1368 "TraceGetBinaryDataRequest");
1372 if (Expected<std::vector<uint8_t>> bytes =
1435 LLDB_LOG(log,
"No debugged process found.");
1441 LLDB_LOG(log,
"Killing process {0}", it->first);
1444 LLDB_LOG(log,
"Failed to kill debugged process {0}: {1}", it->first,
1465 "vKill failed to parse the process id");
1483 packet.
SetFilePos(::strlen(
"QSetDisableASLR:"));
1494 packet.
SetFilePos(::strlen(
"QSetWorkingDir:"));
1536 LLDB_LOG(log,
"process {0} cannot be resumed (state={1})", process.
GetID(),
1555 LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
1560 "GDBRemoteCommunicationServerLLGS::%s no debugged process "
1572 const uint32_t signo =
1573 packet.
GetHexMaxU32(
false, std::numeric_limits<uint32_t>::max());
1574 if (signo == std::numeric_limits<uint32_t>::max())
1580 if (*packet.
Peek() ==
';')
1584 packet,
"unexpected content after $C{signal-number}");
1590 LLDB_LOG(log,
"process cannot be resumed (state={0})",
1611 static_cast<int>(signo)};
1615 resume_actions.
Append(action);
1621 LLDB_LOG(log,
"failed to send signal for process {0}: {1}",
1642 LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
1647 const bool has_continue_address = (packet.
GetBytesLeft() > 0);
1648 if (has_continue_address) {
1649 LLDB_LOG(log,
"not implemented for c[address] variant [{0} remains]",
1657 "GDBRemoteCommunicationServerLLGS::%s no debugged process "
1678 response.
Printf(
"vCont;c;C;s;S;t");
1699 LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
1706 "GDBRemoteCommunicationServerLLGS::%s missing action from "
1712 if (::strcmp(packet.
Peek(),
";s") == 0) {
1718 std::unordered_map<lldb::pid_t, ResumeActionList> thread_actions;
1730 const char action = packet.
GetChar();
1734 if (thread_action.
signal == 0)
1736 packet,
"Could not parse signal in vCont packet C action");
1746 if (thread_action.
signal == 0)
1748 packet,
"Could not parse signal in vCont packet S action");
1779 pid = pid_tid->first;
1780 tid = pid_tid->second;
1786 packet,
"'t' action not supported for individual threads");
1792 LLDB_LOG(log,
"no process selected via Hc");
1801 thread_action.
tid = tid;
1806 packet,
"vCont: p-1 is not valid with a specific tid");
1808 thread_actions[process_it.first].Append(thread_action);
1810 thread_actions[pid].Append(thread_action);
1813 assert(thread_actions.size() >= 1);
1814 if (thread_actions.size() > 1 && !
m_non_stop)
1817 "Resuming multiple processes is supported in non-stop mode only");
1819 for (std::pair<lldb::pid_t, ResumeActionList> x : thread_actions) {
1822 LLDB_LOG(log,
"vCont failed for process {0}: process not debugged",
1839 assert(process_it->second.process_up);
1841 if (process_it->second.process_up->IsRunning()) {
1844 Status error = process_it->second.process_up->Interrupt();
1846 LLDB_LOG(log,
"vCont failed to halt process {0}: {1}", x.first,
1851 LLDB_LOG(log,
"halted process {0}", x.first);
1855 assert(thread_actions.size() == 1);
1871 LLDB_LOG(log,
"setting current thread id to {0}", tid);
1880 LLDB_LOG(log,
"setting continue thread id to {0}", tid);
1894 return x.front() !=
'W' && x.front() !=
'X';
1904 if (!stop_reply.
Empty())
1931 bool force_synchronous) {
1938 if (it.second.process_up->IsRunning())
1948 switch (process_state) {
1974 LLDB_LOG(log,
"pid {0}, current state reporting not handled: {1}",
1975 process.
GetID(), process_state);
2000 const uint32_t reg_index =
2001 packet.
GetHexMaxU32(
false, std::numeric_limits<uint32_t>::max());
2002 if (reg_index == std::numeric_limits<uint32_t>::max())
2033 if (!encoding.empty())
2034 response <<
"encoding:" << encoding <<
';';
2037 if (!format.empty())
2038 response <<
"format:" << format <<
';';
2040 const char *
const register_set_name =
2042 if (register_set_name)
2043 response <<
"set:" << register_set_name <<
';';
2045 if (reg_info->
kinds[RegisterKind::eRegisterKindEHFrame] !=
2047 response.
Printf(
"ehframe:%" PRIu32
";",
2048 reg_info->
kinds[RegisterKind::eRegisterKindEHFrame]);
2051 response.
Printf(
"dwarf:%" PRIu32
";",
2052 reg_info->
kinds[RegisterKind::eRegisterKindDWARF]);
2055 if (!kind_generic.empty())
2056 response <<
"generic:" << kind_generic <<
';';
2081 LLDB_LOG(log,
"iterating over threads of process {0}", process.
GetID());
2083 LLDB_LOG(log,
"iterated thread tid={0}", thread.GetID());
2084 response.
PutChar(had_any ?
',' :
'm');
2097 bool had_any =
false;
2126 LLDB_LOG(log,
"failed, no thread available");
2133 std::vector<uint8_t> regs_buffer;
2138 if (reg_info ==
nullptr) {
2139 LLDB_LOG(log,
"failed to get register info for register index {0}",
2150 LLDB_LOG(log,
"failed to read register at index {0}", reg_num);
2177 const uint32_t reg_index =
2178 packet.
GetHexMaxU32(
false, std::numeric_limits<uint32_t>::max());
2179 if (reg_index == std::numeric_limits<uint32_t>::max()) {
2181 "GDBRemoteCommunicationServerLLGS::%s failed, could not "
2182 "parse register number from request \"%s\"",
2190 LLDB_LOG(log,
"failed, no thread available");
2201 "GDBRemoteCommunicationServerLLGS::%s failed, requested "
2202 "register %" PRIu32
" beyond register count %" PRIu32,
2210 "GDBRemoteCommunicationServerLLGS::%s failed, requested "
2211 "register %" PRIu32
" returned NULL",
2212 __FUNCTION__, reg_index);
2224 "GDBRemoteCommunicationServerLLGS::%s failed, read of "
2225 "requested register %" PRIu32
" (%s) failed: %s",
2226 __FUNCTION__, reg_index, reg_info->
name,
error.AsCString());
2230 const uint8_t *
const data =
2231 static_cast<const uint8_t *
>(reg_value.
GetBytes());
2234 "GDBRemoteCommunicationServerLLGS::%s failed to get data "
2235 "bytes from requested register %" PRIu32,
2236 __FUNCTION__, reg_index);
2241 for (uint32_t i = 0; i < reg_value.
GetByteSize(); ++i)
2257 const uint32_t reg_index =
2258 packet.
GetHexMaxU32(
false, std::numeric_limits<uint32_t>::max());
2259 if (reg_index == std::numeric_limits<uint32_t>::max()) {
2261 "GDBRemoteCommunicationServerLLGS::%s failed, could not "
2262 "parse register number from request \"%s\"",
2270 packet,
"P packet missing '=' char after register number");
2279 "GDBRemoteCommunicationServerLLGS::%s failed, no thread "
2280 "available (thread index 0)",
2290 "GDBRemoteCommunicationServerLLGS::%s failed, requested "
2291 "register %" PRIu32
" returned NULL",
2292 __FUNCTION__, reg_index);
2300 "GDBRemoteCommunicationServerLLGS::%s failed, requested "
2301 "register %" PRIu32
" beyond register count %" PRIu32,
2317 "GDBRemoteCommunicationServerLLGS::%s failed, write of "
2318 "requested register %" PRIu32
" (%s) failed: %s",
2319 __FUNCTION__, reg_index, reg_info->
name,
error.AsCString());
2334 "GDBRemoteCommunicationServerLLGS::%s failed, H command "
2335 "missing {g,c} variant",
2340 const char h_variant = packet.
GetChar();
2342 switch (h_variant) {
2354 "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c",
2355 __FUNCTION__, h_variant);
2357 "H variant unsupported, should be c or g");
2361 auto pid_tid = packet.
GetPidTid(default_process ? default_process->
GetID()
2365 inconvertibleErrorCode(),
"Malformed thread-id"));
2374 inconvertibleErrorCode(),
"No current process and no PID provided"));
2380 inconvertibleErrorCode(),
2381 llvm::formatv(
"No process with PID {0} debugged", pid)));
2387 new_process_it->second.process_up->GetThreadByID(tid);
2390 "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
2398 switch (h_variant) {
2410 assert(
false &&
"unsupported $H variant - shouldn't get here");
2412 "H variant unsupported, should be c or g");
2427 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
2461 LLDB_LOG(log,
"failed, no process available");
2488 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
2511 const uint64_t byte_count = packet.
GetHexMaxU64(
false, 0);
2512 if (byte_count == 0) {
2514 "GDBRemoteCommunicationServerLLGS::%s nothing to read: "
2515 "zero-length packet",
2521 std::string buf(byte_count,
'\0');
2526 size_t bytes_read = 0;
2528 read_addr, &buf[0], byte_count, bytes_read);
2531 "ReadMemoryWithoutTrap({0}) read {1} of {2} requested bytes (error: {3})",
2532 read_addr, byte_count, bytes_read,
error);
2533 if (bytes_read == 0)
2538 char kind = packet.
GetChar(
'?');
2542 assert(kind ==
'm');
2543 for (
size_t i = 0; i < bytes_read; ++i)
2558 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
2573 Permissions perms = {};
2577 perms |= ePermissionsReadable;
2580 perms |= ePermissionsWritable;
2583 perms |= ePermissionsExecutable;
2607 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
2635 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
2658 const uint64_t byte_count = packet.
GetHexMaxU64(
false, 0);
2659 if (byte_count == 0) {
2660 LLDB_LOG(log,
"nothing to write: zero-length packet");
2667 packet,
"Comma sep missing in M packet after byte length");
2670 std::vector<uint8_t> buf(byte_count, 0);
2676 const uint64_t convert_count = packet.
GetHexBytes(buf, 0);
2677 if (convert_count != byte_count) {
2679 "pid {0} mem {1:x}: asked to write {2} bytes, but only found {3} "
2683 "not match hex-encoded content "
2688 size_t bytes_written = 0;
2692 LLDB_LOG(log,
"pid {0} mem {1:x}: failed to write. Error: {2}",
2697 if (bytes_written == 0) {
2698 LLDB_LOG(log,
"pid {0} mem {1:x}: wrote 0 of {2} requested bytes",
2722 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
2749 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
2755 packet.
SetFilePos(strlen(
"qMemoryRegionInfo:"));
2776 response.
Printf(
"start:%" PRIx64
";size:%" PRIx64
";",
2832 LLDB_LOG(log,
"failed, no process available");
2840 packet,
"Too short Z packet, missing software/hardware specifier");
2842 bool want_breakpoint =
true;
2843 bool want_hardware =
false;
2844 uint32_t watch_flags = 0;
2848 switch (stoppoint_type) {
2850 want_hardware =
false;
2851 want_breakpoint =
true;
2854 want_hardware =
true;
2855 want_breakpoint =
true;
2859 want_hardware =
true;
2860 want_breakpoint =
false;
2864 want_hardware =
true;
2865 want_breakpoint =
false;
2869 want_hardware =
true;
2870 want_breakpoint =
false;
2874 packet,
"Z packet had invalid software/hardware specifier");
2879 packet,
"Malformed Z packet, expecting comma after stoppoint type");
2888 packet,
"Malformed Z packet, expecting comma after address");
2891 const uint32_t size =
2892 packet.
GetHexMaxU32(
false, std::numeric_limits<uint32_t>::max());
2893 if (size == std::numeric_limits<uint32_t>::max())
2895 packet,
"Malformed Z packet, failed to parse size argument");
2897 if (want_breakpoint) {
2901 if (
error.Success())
2904 LLDB_LOG(log,
"pid {0} failed to set breakpoint: {1}",
2910 addr, size, watch_flags, want_hardware);
2911 if (
error.Success())
2914 LLDB_LOG(log,
"pid {0} failed to set watchpoint: {1}",
2926 LLDB_LOG(log,
"failed, no process available");
2934 packet,
"Too short z packet, missing software/hardware specifier");
2936 bool want_breakpoint =
true;
2937 bool want_hardware =
false;
2941 switch (stoppoint_type) {
2943 want_breakpoint =
true;
2944 want_hardware =
true;
2947 want_breakpoint =
true;
2950 want_breakpoint =
false;
2953 want_breakpoint =
false;
2956 want_breakpoint =
false;
2960 packet,
"z packet had invalid software/hardware specifier");
2965 packet,
"Malformed z packet, expecting comma after stoppoint type");
2974 packet,
"Malformed z packet, expecting comma after address");
2985 if (want_breakpoint) {
2989 if (
error.Success())
2992 LLDB_LOG(log,
"pid {0} failed to remove breakpoint: {1}",
2998 if (
error.Success())
3001 LLDB_LOG(log,
"pid {0} failed to remove watchpoint: {1}",
3016 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
3054llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
3059 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3060 "No thread available");
3068 response.
Printf(
"<?xml version=\"1.0\"?>\n");
3069 response.
Printf(
"<target version=\"1.0\">\n");
3073 response.
Printf(
"<architecture>%s</architecture>\n",
3080 response.
Indent(
"<feature>\n");
3083 if (registers_count)
3086 llvm::StringSet<> field_enums_seen;
3087 for (
int reg_index = 0; reg_index < registers_count; reg_index++) {
3093 "%s failed to get register info for register index %" PRIu32,
3094 "target.xml", reg_index);
3106 response.
Printf(
"<reg name=\"%s\" bitsize=\"%" PRIu32
3107 "\" regnum=\"%d\" ",
3117 if (!encoding.empty())
3118 response <<
"encoding=\"" << encoding <<
"\" ";
3121 if (!format.empty())
3122 response <<
"format=\"" << format <<
"\" ";
3127 const char *
const register_set_name =
3129 if (register_set_name)
3130 response <<
"group=\"" << register_set_name <<
"\" ";
3132 if (reg_info->
kinds[RegisterKind::eRegisterKindEHFrame] !=
3134 response.
Printf(
"ehframe_regnum=\"%" PRIu32
"\" ",
3135 reg_info->
kinds[RegisterKind::eRegisterKindEHFrame]);
3137 if (reg_info->
kinds[RegisterKind::eRegisterKindDWARF] !=
3139 response.
Printf(
"dwarf_regnum=\"%" PRIu32
"\" ",
3140 reg_info->
kinds[RegisterKind::eRegisterKindDWARF]);
3143 if (!kind_generic.empty())
3144 response <<
"generic=\"" << kind_generic <<
"\" ";
3154 response.
PutCString(
"invalidate_regnums=\"");
3162 if (registers_count)
3165 response.
Indent(
"</feature>\n");
3167 response.
Indent(
"</target>\n");
3168 return MemoryBuffer::getMemBufferCopy(response.
GetString(),
"target.xml");
3171llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
3173 llvm::StringRef annex) {
3177 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3178 "No process available");
3181 if (
object ==
"auxv") {
3184 if (!buffer_or_error)
3185 return llvm::errorCodeToError(buffer_or_error.getError());
3186 return std::move(*buffer_or_error);
3189 if (
object ==
"siginfo") {
3192 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3193 "no current thread");
3196 if (!buffer_or_error)
3197 return buffer_or_error.takeError();
3198 return std::move(*buffer_or_error);
3201 if (
object ==
"libraries-svr4") {
3204 return library_list.takeError();
3207 response.
Printf(
"<library-list-svr4 version=\"1.0\">");
3208 for (
auto const &library : *library_list) {
3209 response.
Printf(
"<library name=\"%s\" ",
3211 response.
Printf(
"lm=\"0x%" PRIx64
"\" ", library.link_map);
3212 response.
Printf(
"l_addr=\"0x%" PRIx64
"\" ", library.base_addr);
3213 response.
Printf(
"l_ld=\"0x%" PRIx64
"\" />", library.ld_addr);
3215 response.
Printf(
"</library-list-svr4>");
3216 return MemoryBuffer::getMemBufferCopy(response.
GetString(), __FUNCTION__);
3219 if (
object ==
"features" && annex ==
"target.xml")
3222 return llvm::make_error<UnimplementedError>();
3228 SmallVector<StringRef, 5> fields;
3230 StringRef(packet.
GetStringRef()).split(fields,
':', 4);
3231 if (fields.size() != 5)
3233 StringRef &xfer_object = fields[1];
3234 StringRef &xfer_action = fields[2];
3235 StringRef &xfer_annex = fields[3];
3237 if (xfer_action !=
"read")
3240 const uint64_t xfer_offset =
3241 offset_data.
GetHexMaxU64(
false, std::numeric_limits<uint64_t>::max());
3242 if (xfer_offset == std::numeric_limits<uint64_t>::max())
3245 if (offset_data.
GetChar() !=
',')
3247 "qXfer packet missing comma after offset");
3249 const uint64_t xfer_length =
3250 offset_data.
GetHexMaxU64(
false, std::numeric_limits<uint64_t>::max());
3251 if (xfer_length == std::numeric_limits<uint64_t>::max())
3255 std::string buffer_key = (xfer_object + xfer_action + xfer_annex).str();
3262 .insert(std::make_pair(buffer_key, std::move(*buffer_up)))
3268 bool done_with_buffer =
false;
3269 llvm::StringRef buffer = buffer_it->second->getBuffer();
3270 if (xfer_offset >= buffer.size()) {
3273 done_with_buffer =
true;
3276 buffer = buffer.drop_front(xfer_offset);
3279 if (xfer_length >= buffer.size()) {
3282 done_with_buffer =
true;
3286 buffer = buffer.take_front(xfer_length);
3292 if (done_with_buffer)
3304 packet.
SetFilePos(strlen(
"QSaveRegisterState"));
3311 packet,
"No thread specified in QSaveRegisterState packet");
3314 "No thread was is set with the Hg packet");
3324 LLDB_LOG(log,
"pid {0} failed to save all register values: {1}",
3332 "GetNextRegisterSaveID() returned an existing register save id");
3342 response.
Printf(
"%" PRIu32, save_id);
3352 packet.
SetFilePos(strlen(
"QRestoreRegisterState:"));
3355 packet,
"QRestoreRegisterState packet missing register save id");
3357 const uint32_t save_id = packet.
GetU32(0);
3359 LLDB_LOG(log,
"QRestoreRegisterState packet has malformed save id, "
3360 "expecting decimal uint32_t");
3369 packet,
"No thread specified in QRestoreRegisterState packet");
3372 "No thread was is set with the Hg packet");
3387 "pid {0} does not have a register set save buffer for id {1}",
3391 register_data_sp = it->second;
3399 LLDB_LOG(log,
"pid {0} failed to restore all register values: {1}",
3421 "vAttach failed to parse the process id");
3425 "GDBRemoteCommunicationServerLLGS::%s attempting to attach to "
3433 "GDBRemoteCommunicationServerLLGS::%s failed to attach to "
3434 "pid %" PRIu64
": %s\n",
3435 __FUNCTION__, pid,
error.AsCString());
3458 std::string process_name;
3461 "vAttachWait failed to parse process name");
3463 LLDB_LOG(log,
"attempting to attach to process named '{0}'", process_name);
3467 LLDB_LOG(log,
"failed to attach to process named '{0}': {1}", process_name,
3497 std::string process_name;
3500 "vAttachOrWait failed to parse process name");
3502 LLDB_LOG(log,
"attempting to attach to process named '{0}'", process_name);
3506 LLDB_LOG(log,
"failed to attach to process named '{0}': {1}", process_name,
3524 if (!s.consume_front(
"vRun;"))
3527 llvm::SmallVector<llvm::StringRef, 16> argv;
3530 for (llvm::StringRef hex_arg : argv) {
3535 LLDB_LOGF(log,
"LLGSPacketHandler::%s added arg: \"%s\"", __FUNCTION__,
3574 llvm::Error detach_error = llvm::Error::success();
3575 bool detached =
false;
3580 "GDBRemoteCommunicationServerLLGS::%s detaching %" PRId64,
3581 __FUNCTION__, it->first);
3582 if (llvm::Error e = it->second.process_up->Detach().ToError())
3583 detach_error = llvm::joinErrors(std::move(detach_error), std::move(e));
3614 packet.
SetFilePos(strlen(
"qThreadStopInfo"));
3618 "GDBRemoteCommunicationServerLLGS::%s failed, could not "
3619 "parse thread id from request \"%s\"",
3639 const bool threads_with_valid_stop_info_only =
false;
3640 llvm::Expected<json::Value> threads_info =
3642 if (!threads_info) {
3644 "failed to prepare a packet for pid {1}: {0}",
3663 packet.
SetFilePos(strlen(
"qWatchpointSupportInfo"));
3672 if (hw_debug_cap == std::nullopt)
3673 response.
Printf(
"num:0;");
3675 response.
Printf(
"num:%d;", hw_debug_cap->second);
3688 packet.
SetFilePos(strlen(
"qFileLoadAddress:"));
3692 std::string file_name;
3705 response.
PutHex64(file_load_address);
3712 std::vector<int> signals;
3718 int signal = packet.
GetS32(-1, 16);
3721 signals.push_back(signal);
3724 char separator = packet.
GetChar();
3725 if (separator ==
'\0')
3727 if (separator !=
';')
3729 " expected semicolon.");
3753 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
3763 const char *current_char = packet.
Peek();
3764 if (!current_char || *current_char ==
',')
3769 char previous_char = packet.
GetChar();
3770 current_char = packet.
Peek();
3772 if (previous_char !=
',' || (current_char && *current_char ==
':'))
3774 "Invalid addr,length pair in qMemTags packet");
3778 packet,
"Too short qMemtags: packet (looking for length)");
3782 const char *invalid_type_err =
"Invalid type field in qMemTags: packet";
3788 const char *first_type_char = packet.
Peek();
3789 if (first_type_char && (*first_type_char ==
'+' || *first_type_char ==
'-'))
3796 packet.
GetU64(std::numeric_limits<uint64_t>::max(), 16);
3799 raw_type > std::numeric_limits<uint32_t>::max() ||
3808 uint32_t raw_type_32 = raw_type;
3809 int32_t type =
reinterpret_cast<int32_t &
>(raw_type_32);
3812 std::vector<uint8_t> tags;
3834 "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
3844 const char *current_char = packet.
Peek();
3845 if (!current_char || *current_char ==
',')
3850 char previous_char = packet.
GetChar();
3851 current_char = packet.
Peek();
3853 if (previous_char !=
',' || (current_char && *current_char ==
':'))
3855 "Invalid addr,length pair in QMemTags packet");
3859 packet,
"Too short QMemtags: packet (looking for length)");
3863 const char *invalid_type_err =
"Invalid type field in QMemTags: packet";
3868 const char *first_type_char = packet.
Peek();
3869 if (first_type_char && (*first_type_char ==
'+' || *first_type_char ==
'-'))
3877 packet.
GetU64(std::numeric_limits<uint64_t>::max(), 16);
3878 if (raw_type > std::numeric_limits<uint32_t>::max())
3883 uint32_t raw_type_32 = raw_type;
3884 int32_t type =
reinterpret_cast<int32_t &
>(raw_type_32);
3889 "Missing tag data in QMemTags: packet");
3892 const char *invalid_data_err =
"Invalid tag data in QMemTags: packet";
3899 std::vector<uint8_t> tag_data;
3904 tag_data.resize(byte_count);
3905 size_t converted_bytes = packet.
GetHexBytes(tag_data, 0);
3906 if (converted_bytes != byte_count) {
3924 std::string path_hint;
3927 assert(packet_str.starts_with(
"qSaveCore"));
3928 if (packet_str.consume_front(
"qSaveCore;")) {
3929 for (
auto x : llvm::split(packet_str,
';')) {
3930 if (x.consume_front(
"path-hint:"))
3954 assert(packet_str.starts_with(
"QNonStop:"));
3955 packet_str.consume_front(
"QNonStop:");
3956 if (packet_str ==
"0") {
3960 if (process_it.second.process_up->IsRunning()) {
3962 Status error = process_it.second.process_up->Interrupt();
3965 "while disabling nonstop, failed to halt process {0}: {1}",
3966 process_it.first,
error);
3980 }
else if (packet_str ==
"1") {
3992 std::deque<std::string> &queue) {
4036 return interrupt_res;
4048 inconvertibleErrorCode(),
"Malformed thread-id"));
4057 inconvertibleErrorCode(),
"No current process and no PID provided"));
4065 if (!new_process_it->second.process_up->GetThreadByID(tid))
4079 connection->Disconnect(&
error);
4081 if (
error.Success()) {
4083 "GDBRemoteCommunicationServerLLGS::%s disconnect process "
4084 "terminal stdio - SUCCESS",
4088 "GDBRemoteCommunicationServerLLGS::%s disconnect process "
4089 "terminal stdio - FAIL: %s",
4090 __FUNCTION__,
error.AsCString());
4109 else if (current_tid == 0) {
4121 "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
4122 "error: expected ';' prior to start of thread suffix: packet "
4132 if (strncmp(packet.
Peek(),
"thread:", strlen(
"thread:")) != 0) {
4134 "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
4135 "error: expected 'thread:' but not found, packet contents = "
4179 ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec)
4190 llvm::StringRef value) {
4192 for (
const char &c : value) {
4215 const llvm::ArrayRef<llvm::StringRef> client_features) {
4216 std::vector<std::string> ret =
4218 ret.insert(ret.end(), {
4219 "QThreadSuffixSupported+",
4220 "QListThreadsInStopReply+",
4221 "qXfer:features:read+",
4228 if (
bool(plugin_features & Extension::pass_signals))
4229 ret.push_back(
"QPassSignals+");
4230 if (
bool(plugin_features & Extension::auxv))
4231 ret.push_back(
"qXfer:auxv:read+");
4232 if (
bool(plugin_features & Extension::libraries_svr4))
4233 ret.push_back(
"qXfer:libraries-svr4:read+");
4234 if (
bool(plugin_features & Extension::siginfo_read))
4235 ret.push_back(
"qXfer:siginfo:read+");
4236 if (
bool(plugin_features & Extension::memory_tagging))
4237 ret.push_back(
"memory-tagging+");
4238 if (
bool(plugin_features & Extension::savecore))
4239 ret.push_back(
"qSaveCore+");
4243 for (llvm::StringRef x : client_features)
4245 llvm::StringSwitch<Extension>(x)
4246 .Case(
"multiprocess+", Extension::multiprocess)
4247 .Case(
"fork-events+", Extension::fork)
4248 .Case(
"vfork-events+", Extension::vfork)
4263 ret.push_back(
"multiprocess+");
4265 ret.push_back(
"fork-events+");
4267 ret.push_back(
"vfork-events+");
4293 response.
Format(
"p{0:x-}.", pid);
4294 response.
Format(
"{0:x-}", tid);
4299 bool reverse_connect) {
4301 if (std::optional<URI> url =
URI::Parse(url_arg)) {
4302 if (reverse_connect)
4303 return url_arg.str();
4308 std::string new_url = llvm::StringSwitch<std::string>(url->scheme)
4309 .Case(
"tcp",
"listen")
4310 .Case(
"unix",
"unix-accept")
4311 .Case(
"unix-abstract",
"unix-abstract-accept")
4312 .Default(url->scheme.str());
4313 llvm::append_range(new_url, url_arg.substr(url->scheme.size()));
4317 std::string host_port = url_arg.str();
4320 if (url_arg.starts_with(
":"))
4321 host_port.insert(0,
"localhost");
4325 return (reverse_connect ?
"connect://" :
"listen://") + host_port;
4328 return (reverse_connect ?
"unix-connect://" :
"unix-accept://") +
static const size_t reg_size
static llvm::raw_ostream & error(Stream &strm)
static llvm::StringRef GetEncodingNameOrEmpty(const RegisterInfo ®_info)
static llvm::StringRef GetFormatNameOrEmpty(const RegisterInfo ®_info)
static void WriteRegisterValueInHexFixedWidth(StreamString &response, NativeRegisterContext ®_ctx, const RegisterInfo ®_info, const RegisterValue *reg_value_p, lldb::ByteOrder byte_order)
static void AppendHexValue(StreamString &response, const uint8_t *buf, uint32_t buf_size, bool swap)
static std::optional< json::Object > GetRegistersAsJSON(NativeThreadProtocol &thread)
static const char * GetStopReasonString(StopReason stop_reason)
static void CollectRegNums(const uint32_t *reg_num, StreamString &response, bool usehex)
static bool ResumeActionListStopsAllThreads(ResumeActionList &actions)
static llvm::StringRef GetKindGenericOrEmpty(const RegisterInfo ®_info)
static llvm::Expected< json::Array > GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
An architecture specification class.
llvm::Triple & GetTriple()
Architecture triple accessor.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
virtual size_t Read(void *dst, size_t dst_len, const Timeout< std::micro > &timeout, lldb::ConnectionStatus &status, Status *error_ptr)
Read bytes from the current connection.
bool IsConnected() const
Check if the connection is valid.
virtual void SetConnection(std::unique_ptr< Connection > connection)
Sets the connection that it to be used by this class.
size_t WriteAll(const void *src, size_t src_len, lldb::ConnectionStatus &status, Status *error_ptr)
Repeatedly attempt writing until either src_len bytes are written or a permanent failure occurs.
lldb_private::Connection * GetConnection()
void SetCloseOnEOF(bool b)
virtual lldb::IOObjectSP GetReadObject()
Returns the underlying IOObject used by the Connection.
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
static FileSystem & Instance()
ValueType Clear(ValueType mask=~static_cast< ValueType >(0))
Clear one or more flags.
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
static uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos)
void AddPendingCallback(const Callback &callback)
virtual void RequestTermination()
ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp, const Callback &callback, Status &error) override
OptionalBool GetWritable() const
ConstString GetName() const
OptionalBool GetMemoryTagged() const
OptionalBool GetReadable() const
OptionalBool GetExecutable() const
OptionalBool IsShadowStack() const
virtual llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Attach(lldb::pid_t pid, NativeDelegate &native_delegate)=0
Attach to an existing process.
virtual llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate)=0
Launch a process for debugging.
virtual Extension GetSupportedExtensions() const
Get the bitmask of extensions supported by this process plugin.
virtual Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
virtual Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len, std::vector< uint8_t > &tags)
virtual llvm::Expected< TraceSupportedResponse > TraceSupported()
Get the processor tracing type supported for this process.
virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
virtual std::optional< WaitStatus > GetExitStatus()
virtual void SetEnabledExtensions(Extension flags)
Method called in order to propagate the bitmap of protocol extensions supported by the client.
virtual Status RemoveWatchpoint(lldb::addr_t addr)
virtual Status Interrupt()
Tells a process to interrupt all operations as if by a Ctrl-C.
virtual Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len, const std::vector< uint8_t > &tags)
virtual llvm::Expected< std::vector< SVR4LibraryInfo > > GetLoadedSVR4Libraries()
virtual llvm::Expected< std::vector< uint8_t > > TraceGetBinaryData(const TraceGetBinaryDataRequest &request)
Get binary data given a trace technology and a data identifier.
lldb::pid_t GetID() const
virtual llvm::Error TraceStop(const TraceStopRequest &request)
Stop tracing a live process or its threads.
virtual Status IgnoreSignals(llvm::ArrayRef< int > signals)
virtual llvm::Expected< llvm::json::Value > TraceGetState(llvm::StringRef type)
Get the current tracing state of the process and its threads.
virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware)=0
virtual const ArchSpec & GetArchitecture() const =0
virtual llvm::Error DeallocateMemory(lldb::addr_t addr)
lldb::StateType GetState() const
NativeThreadProtocol * GetThreadByID(lldb::tid_t tid)
virtual Status GetFileLoadAddress(const llvm::StringRef &file_name, lldb::addr_t &load_addr)=0
NativeThreadProtocol * GetCurrentThread()
virtual llvm::Expected< std::string > SaveCore(llvm::StringRef path_hint)
Write a core dump (without crashing the program).
void SetCurrentThreadID(lldb::tid_t tid)
virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware=false)
virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written)=0
Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)
virtual Status Resume(const ResumeActionList &resume_actions)=0
virtual Status Signal(int signo)=0
Sends a process a UNIX signal signal.
NativeThreadProtocol * GetThreadAtIndex(uint32_t idx)
lldb::tid_t GetCurrentThreadID() const
virtual llvm::Expected< lldb::addr_t > AllocateMemory(size_t size, uint32_t permissions)
Extension
Extension flag constants, returned by Manager::GetSupportedExtensions() and passed to SetEnabledExten...
virtual llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > GetAuxvData() const =0
virtual std::optional< std::pair< uint32_t, uint32_t > > GetHardwareDebugSupportInfo() const
virtual llvm::Error TraceStart(llvm::StringRef json_params, llvm::StringRef type)
Start tracing a process or its threads.
ThreadIterable Threads() const
uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num) const
virtual uint32_t GetUserRegisterCount() const =0
virtual const RegisterInfo * GetRegisterInfoAtIndex(uint32_t reg) const =0
const char * GetRegisterSetNameForRegisterAtIndex(uint32_t reg_index) const
virtual Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)=0
virtual Status ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value)=0
virtual bool RegisterOffsetIsDynamic() const
virtual Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp)=0
virtual std::vector< uint32_t > GetExpeditedRegisters(ExpeditedRegs expType) const
virtual Status WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value)=0
virtual bool GetStopReason(ThreadStopInfo &stop_info, std::string &description)=0
NativeProcessProtocol & GetProcess()
virtual llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > GetSiginfo() const
virtual std::string GetName()=0
virtual NativeRegisterContext & GetRegisterContext()=0
lldb::tid_t GetID() const
FileSpec & GetExecutableFile()
void SetNameMatchType(NameMatch name_match_type)
ProcessInstanceInfo & GetProcessInfo()
llvm::Error SetUpPtyRedirection()
const FileAction * GetFileActionForFD(int fd) const
void SetLaunchInSeparateProcessGroup(bool separate)
void SetWorkingDirectory(const FileSpec &working_dir)
const FileSpec & GetWorkingDirectory() const
void EnumsToXML(Stream &strm, llvm::StringSet<> &seen) const
Enum types must be defined before use, and GDBRemoteCommunicationServerLLGS view of the register type...
const std::string & GetID() const
void ToXML(Stream &strm) const
Output XML that describes this set of flags.
const void * GetBytes() const
uint32_t GetByteSize() const
const ResumeAction * GetActionForThread(lldb::tid_t tid, bool default_ok) const
void Append(const ResumeAction &action)
bool SetDefaultThreadActionIfNeeded(lldb::StateType action, int signal)
static llvm::Expected< HostAndPort > DecodeHostAndPort(llvm::StringRef host_and_port)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
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.
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
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t size_t PutHex8(uint8_t uvalue)
Append an uint8_t value in the hexadecimal format to the stream.
size_t PutStringAsRawHex8(llvm::StringRef s)
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
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 PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
void IndentMore(unsigned amount=2)
Increment the current indentation level.
virtual FileSpec FindModuleFile(const std::string &module_path, const ArchSpec &arch)
void RegisterMemberFunctionHandler(StringExtractorGDBRemote::ServerPacketType packet_type, PacketResult(T::*handler)(StringExtractorGDBRemote &packet))
static void CreateProcessInfoResponse_DebugServerStyle(const ProcessInstanceInfo &proc_info, StreamString &response)
Status m_process_launch_error
ProcessLaunchInfo m_process_launch_info
virtual std::vector< std::string > HandleFeatures(llvm::ArrayRef< llvm::StringRef > client_features)
PacketResult Handle_QMemTags(StringExtractorGDBRemote &packet)
PacketResult Handle_qVAttachOrWaitSupported(StringExtractorGDBRemote &packet)
PacketResult Handle_vStdio(StringExtractorGDBRemote &packet)
PacketResult HandleNotificationAck(std::deque< std::string > &queue)
PacketResult Handle_QSetDisableASLR(StringExtractorGDBRemote &packet)
void SetLaunchInfo(const ProcessLaunchInfo &info)
PacketResult SendONotification(const char *buffer, uint32_t len)
PacketResult Handle_D(StringExtractorGDBRemote &packet)
NativeProcessProtocol::Extension m_extensions_supported
PacketResult Handle_qMemTags(StringExtractorGDBRemote &packet)
void AddProcessThreads(StreamGDBRemote &response, NativeProcessProtocol &process, bool &had_any)
llvm::StringMap< std::unique_ptr< llvm::MemoryBuffer > > m_xfer_buffer_map
PacketResult SendStopReasonForState(NativeProcessProtocol &process, lldb::StateType process_state, bool force_synchronous)
void EnqueueStopReplyPackets(lldb::tid_t thread_to_skip)
PacketResult Handle_jLLDBTraceGetBinaryData(StringExtractorGDBRemote &packet)
PacketResult Handle_qfThreadInfo(StringExtractorGDBRemote &packet)
StreamString PrepareStopReplyPacketForThread(NativeThreadProtocol &thread)
uint8_t m_reg_bytes[RegisterValue::kMaxRegisterByteSize]
PacketResult Handle__m(StringExtractorGDBRemote &packet)
PacketResult Handle_g(StringExtractorGDBRemote &packet)
uint32_t m_next_saved_registers_id
void RegisterPacketHandlers()
PacketResult Handle_qMemoryRegionInfoSupported(StringExtractorGDBRemote &packet)
PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet)
PacketResult Handle_c(StringExtractorGDBRemote &packet)
PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet)
PacketResult Handle_interrupt(StringExtractorGDBRemote &packet)
PacketResult Handle_vKill(StringExtractorGDBRemote &packet)
std::unordered_map< lldb::pid_t, DebuggedProcess > m_debugged_processes
void InitializeDelegate(NativeProcessProtocol *process) override
FileSpec FindModuleFile(const std::string &module_path, const ArchSpec &arch) override
PacketResult Handle_vAttachOrWait(StringExtractorGDBRemote &packet)
PacketResult Handle_vAttach(StringExtractorGDBRemote &packet)
PacketResult Handle_stop_reason(StringExtractorGDBRemote &packet)
PacketResult Handle_jLLDBTraceSupported(StringExtractorGDBRemote &packet)
std::deque< std::string > m_stop_notification_queue
PacketResult Handle_qsThreadInfo(StringExtractorGDBRemote &packet)
PacketResult Handle_vStopped(StringExtractorGDBRemote &packet)
PacketResult Handle_z(StringExtractorGDBRemote &packet)
bool m_disabling_non_stop
lldb::tid_t GetContinueThreadID() const
PacketResult Handle_H(StringExtractorGDBRemote &packet)
void StopSTDIOForwarding()
PacketResult SendContinueSuccessResponse()
PacketResult Handle_jLLDBTraceGetState(StringExtractorGDBRemote &packet)
std::deque< std::string > m_stdio_notification_queue
bool m_list_threads_in_stop_reply
PacketResult Handle_qFileLoadAddress(StringExtractorGDBRemote &packet)
void NewSubprocess(NativeProcessProtocol *parent_process, std::unique_ptr< NativeProcessProtocol > child_process) override
PacketResult Handle_qC(StringExtractorGDBRemote &packet)
static std::string XMLEncodeAttributeValue(llvm::StringRef value)
NativeThreadProtocol * GetThreadFromSuffix(StringExtractorGDBRemote &packet)
Status SetSTDIOFileDescriptor(int fd)
lldb::tid_t GetCurrentThreadID() const
PacketResult Handle_QNonStop(StringExtractorGDBRemote &packet)
Status AttachToProcess(lldb::pid_t pid)
Attach to a process.
PacketResult SendWResponse(NativeProcessProtocol *process)
PacketResult Handle_s(StringExtractorGDBRemote &packet)
Status InitializeConnection(std::unique_ptr< Connection > connection)
bool m_thread_suffix_supported
void HandleInferiorState_Exited(NativeProcessProtocol *process)
lldb::tid_t m_continue_tid
PacketResult Handle_P(StringExtractorGDBRemote &packet)
PacketResult Handle_qSaveCore(StringExtractorGDBRemote &packet)
NativeProcessProtocol * m_current_process
void HandleInferiorState_Stopped(NativeProcessProtocol *process)
NativeProcessProtocol * m_continue_process
PacketResult Handle_vCont(StringExtractorGDBRemote &packet)
PacketResult Handle_vCont_actions(StringExtractorGDBRemote &packet)
PacketResult Handle_vCtrlC(StringExtractorGDBRemote &packet)
PacketResult Handle_jLLDBTraceStart(StringExtractorGDBRemote &packet)
Status LaunchProcess() override
Launch a process with the current launch settings.
PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet)
void DataAvailableCallback()
PacketResult Handle_jThreadsInfo(StringExtractorGDBRemote &packet)
PacketResult Handle_M(StringExtractorGDBRemote &packet)
void DidExec(NativeProcessProtocol *process) override
PacketResult Handle_memory_read(StringExtractorGDBRemote &packet)
Status AttachWaitProcess(llvm::StringRef process_name, bool include_existing)
Wait to attach to a process with a given name.
PacketResult Handle_vAttachWait(StringExtractorGDBRemote &packet)
PacketResult ResumeProcess(NativeProcessProtocol &process, const ResumeActionList &actions)
PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet)
PacketResult Handle_jLLDBTraceStop(StringExtractorGDBRemote &packet)
PacketResult Handle_T(StringExtractorGDBRemote &packet)
GDBRemoteCommunicationServerLLGS(MainLoop &mainloop, NativeProcessProtocol::Manager &process_manager)
PacketResult Handle_QSetWorkingDir(StringExtractorGDBRemote &packet)
PacketResult Handle_k(StringExtractorGDBRemote &packet)
PacketResult Handle_qXfer(StringExtractorGDBRemote &packet)
PacketResult SendStopReplyPacketForThread(NativeProcessProtocol &process, lldb::tid_t tid, bool force_synchronous)
void StartSTDIOForwarding()
PacketResult Handle_C(StringExtractorGDBRemote &packet)
PacketResult Handle__M(StringExtractorGDBRemote &packet)
void AppendThreadIDToResponse(Stream &response, lldb::pid_t pid, lldb::tid_t tid)
std::vector< std::string > HandleFeatures(const llvm::ArrayRef< llvm::StringRef > client_features) override
void ClearProcessSpecificData()
PacketResult Handle_Z(StringExtractorGDBRemote &packet)
PacketResult Handle_QPassSignals(StringExtractorGDBRemote &packet)
PacketResult Handle_qWatchpointSupportInfo(StringExtractorGDBRemote &packet)
void ProcessStateChanged(NativeProcessProtocol *process, lldb::StateType state) override
lldb::tid_t m_current_tid
void SetEnabledExtensions(NativeProcessProtocol &process)
std::unordered_map< uint32_t, lldb::DataBufferSP > m_saved_registers_map
PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet)
NativeProcessProtocol::Manager & m_process_manager
void SetContinueThreadID(lldb::tid_t tid)
PacketResult Handle_p(StringExtractorGDBRemote &packet)
PacketResult Handle_qRegisterInfo(StringExtractorGDBRemote &packet)
void SetCurrentThreadID(lldb::tid_t tid)
std::mutex m_saved_registers_mutex
PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet)
PacketResult Handle_vRun(StringExtractorGDBRemote &packet)
MainLoop::ReadHandleUP m_stdio_handle_up
void MaybeCloseInferiorTerminalConnection()
MainLoop::ReadHandleUP m_network_handle_up
PacketResult Handle_qMemoryRegionInfo(StringExtractorGDBRemote &packet)
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > ReadXferObject(llvm::StringRef object, llvm::StringRef annex)
PacketResult Handle_QSaveRegisterState(StringExtractorGDBRemote &packet)
std::recursive_mutex m_debugged_process_mutex
uint32_t GetNextSavedRegistersID()
Communication m_stdio_communication
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > BuildTargetXml()
PacketResult Handle_I(StringExtractorGDBRemote &packet)
void RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type, PacketHandler handler)
PacketResult SendErrorResponse(const Status &error)
PacketResult SendIllFormedResponse(const StringExtractorGDBRemote &packet, const char *error_message)
PacketResult GetPacketAndSendResponse(Timeout< std::micro > timeout, Status &error, bool &interrupt, bool &quit)
PacketResult SendJSONResponse(const llvm::json::Value &value)
Serialize and send a JSON object response.
PacketResult SendUnimplementedResponse(const char *packet)
PacketResult SendOKResponse()
PacketResult SendNotificationPacketNoLock(llvm::StringRef notify_type, std::deque< std::string > &queue, llvm::StringRef payload)
PacketResult SendPacketNoLock(llvm::StringRef payload)
#define LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_ARG8
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_THREAD_ID
#define LLDB_REGNUM_GENERIC_ARG6
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_ARG4
#define LLDB_REGNUM_GENERIC_ARG3
#define LLDB_REGNUM_GENERIC_ARG1
#define LLDB_REGNUM_GENERIC_ARG7
#define LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_TP
#define LLDB_INVALID_PROCESS_ID
#define LLDB_REGNUM_GENERIC_ARG2
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
#define LLDB_REGNUM_GENERIC_ARG5
lldb::ByteOrder InlHostByteOrder()
std::string LLGSArgToURL(llvm::StringRef url_arg, bool reverse_connect)
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.
void swap(AdaptedConstIterator< C, E, A > &lhs, AdaptedConstIterator< C, E, A > &rhs)
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
std::shared_ptr< lldb_private::IOObject > IOObjectSP
ConnectionStatus
Connection Status Types.
@ eConnectionStatusError
Check GetError() for details.
@ eConnectionStatusInterrupted
Interrupted read.
@ eConnectionStatusTimedOut
Request timed out.
@ eConnectionStatusEndOfFile
End-of-file encountered.
@ eConnectionStatusSuccess
Success.
@ eConnectionStatusLostConnection
Lost connection while connected to a valid connection.
@ eConnectionStatusNoConnection
No connection.
StateType
Process and Thread States.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ 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.
@ eStateLaunching
Process is in the process of launching.
@ 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.
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
@ eEncodingSint
signed integer
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
StopReason
Thread stop reasons.
@ eStopReasonInstrumentation
@ eStopReasonPlanComplete
@ eStopReasonExec
Program was re-exec'ed.
@ eStopReasonInterrupt
Thread requested interrupt.
@ eStopReasonProcessorTrace
@ eStopReasonThreadExiting
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
BaseType GetRangeBase() const
SizeType GetByteSize() const
Every register is described in detail including its name, alternate name (optional),...
lldb::Encoding encoding
Encoding of the register bits.
const char * alt_name
Alternate name of this register, can be NULL.
uint32_t * value_regs
List of registers (terminated with LLDB_INVALID_REGNUM).
uint32_t byte_offset
The byte offset in the register context data where this register's value is found.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const RegisterFlags * flags_type
If not nullptr, a type defined by XML descriptions.
const char * name
Name of this register, can't be NULL.
lldb::Format format
Default display format.
uint32_t * invalidate_regs
List of registers (terminated with LLDB_INVALID_REGNUM).
struct lldb_private::ThreadStopInfo::@11::@13 fork
struct lldb_private::ThreadStopInfo::@11::@12 exception
union lldb_private::ThreadStopInfo::@11 details
static std::optional< URI > Parse(llvm::StringRef uri)