37#include "lldb/Host/Config.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
42#include "llvm/Config/llvm-config.h"
43#include "llvm/Support/ErrorExtras.h"
44#include "llvm/Support/JSON.h"
46#if HAVE_LIBCOMPRESSION
47#include <compression.h>
53using namespace std::chrono;
57 return os << llvm::formatv(
58 "QOffsets({0}, [{1:@[x]}])", offsets.
segments,
93 std::chrono::steady_clock::time_point start_of_handshake =
94 std::chrono::steady_clock::now();
103 std::chrono::steady_clock::time_point end_of_handshake =
104 std::chrono::steady_clock::now();
105 auto handshake_timeout =
106 std::chrono::duration<double>(end_of_handshake - start_of_handshake)
112 "while waiting for reply to initial "
116 "failed to get reply to handshake packet within timeout of "
234llvm::Expected<std::vector<AcceleratorActions>>
242 return std::vector<AcceleratorActions>();
248 return llvm::createStringError(
249 "failed to send jAcceleratorPluginInitialize packet");
252 return std::vector<AcceleratorActions>();
257 llvm::Expected<std::vector<AcceleratorActions>> actions =
258 llvm::json::parse<std::vector<AcceleratorActions>>(response.
Peek(),
259 "AcceleratorActions");
266 return llvm::createStringErrorV(
267 "malformed jAcceleratorPluginInitialize response '{0}': {1}",
268 response.
GetStringRef(), llvm::toString(actions.takeError()));
271llvm::Expected<AcceleratorBreakpointHitResponse>
275 packet.
PutCString(
"jAcceleratorPluginBreakpointHit:");
281 return llvm::createStringError(
282 "failed to send jAcceleratorPluginBreakpointHit packet");
287 llvm::Expected<AcceleratorBreakpointHitResponse> hit_response =
288 llvm::json::parse<AcceleratorBreakpointHitResponse>(
289 response.
Peek(),
"AcceleratorBreakpointHitResponse");
296 return llvm::createStringErrorV(
297 "malformed jAcceleratorPluginBreakpointHit response '{0}': {1}",
298 response.
GetStringRef(), llvm::toString(hit_response.takeError()));
466 std::vector<std::string> features = {
"xmlRegisters=i386,arm,mips,arc",
474 for (uint32_t i = 0; i < features.size(); ++i) {
486 for (llvm::StringRef x : llvm::split(response.
GetStringRef(),
';')) {
487 if (x ==
"qXfer:auxv:read+")
489 else if (x ==
"qXfer:libraries-svr4:read+")
491 else if (x ==
"augmented-libraries-svr4-read") {
494 }
else if (x ==
"qXfer:libraries:read+")
496 else if (x ==
"qXfer:features:read+")
498 else if (x ==
"qXfer:memory-map:read+")
500 else if (x ==
"qXfer:siginfo:read+")
502 else if (x ==
"qEcho+")
504 else if (x ==
"QPassSignals+")
506 else if (x ==
"multiprocess+")
508 else if (x ==
"memory-tagging+")
510 else if (x ==
"qSaveCore+")
512 else if (x ==
"native-signals+")
514 else if (x ==
"binary-upload+")
516 else if (x ==
"ReverseContinue+")
518 else if (x ==
"ReverseStep+")
520 else if (x ==
"MultiMemRead+")
522 else if (x ==
"jMultiBreakpoint+")
524 else if (x ==
"accelerator-plugins+")
529 else if (x.consume_front(
"SupportedCompressions=")) {
530 llvm::SmallVector<llvm::StringRef, 4> compressions;
531 x.split(compressions,
',');
532 if (!compressions.empty())
534 }
else if (x.consume_front(
"SupportedWatchpointTypes=")) {
535 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
536 x.split(watchpoint_types,
',');
538 for (
auto wp_type : watchpoint_types) {
539 if (wp_type ==
"x86_64")
541 if (wp_type ==
"aarch64-mask")
543 if (wp_type ==
"aarch64-bas")
546 }
else if (x.consume_front(
"PacketSize=")) {
553 LLDB_LOGF(log,
"Garbled PacketSize spec in qSupported response");
574 assert(!flavor.empty());
585 for (llvm::StringRef token : llvm::split(response.
GetStringRef(),
';')) {
612 return llvm::StringSwitch<bool>(flavor)
630 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
632 __FUNCTION__, payload.GetData());
637 payload.Printf(
";thread:%4.4" PRIx64
";", tid);
684 }
else if (!response.
Empty()) {
773 packet.
Printf(
"qMemTags:%" PRIx64
",%zx:%" PRIx32, addr, len, type);
781 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s: qMemTags packet failed",
789 if (response.
GetChar() !=
'm') {
791 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
802 if (response.
GetBytesLeft() || (expected_bytes != got_bytes)) {
805 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
815 const std::vector<uint8_t> &tags) {
818 packet.
Printf(
"QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr, len, type);
864 if (response.
GetChar() ==
'Q') {
865 if (response.
GetChar() ==
'C') {
879 bool sequence_mutex_unavailable;
881 if (!ids.empty() && !sequence_mutex_unavailable) {
898 return llvm::createStringError(llvm::inconvertibleErrorCode(),
899 "Nothing to launch");
912 return llvm::createStringError(llvm::inconvertibleErrorCode(),
913 "Sending vRun packet failed");
922 return llvm::Error::success();
930 llvm::ListSeparator LS(
",");
931 for (
const auto &arg : llvm::enumerate(args)) {
933 packet.
Format(
"{0},{1},", arg.value().ref().size() * 2, arg.index());
940 return llvm::createStringError(llvm::inconvertibleErrorCode(),
941 "Sending A packet failed");
948 return llvm::createStringError(llvm::inconvertibleErrorCode(),
949 "Sending qLaunchSuccess packet failed");
952 return llvm::Error::success();
953 if (response.
GetChar() ==
'E') {
954 return llvm::createStringError(llvm::inconvertibleErrorCode(),
957 return llvm::createStringError(llvm::inconvertibleErrorCode(),
958 "unknown error occurred launching process");
962 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
963 for (
const auto &kv : env)
964 vec.emplace_back(kv.first(), kv.second);
965 llvm::sort(vec, llvm::less_first());
966 for (
const auto &[k, v] : vec) {
975 char const *name_equal_value) {
976 if (name_equal_value && name_equal_value[0]) {
977 bool send_hex_encoding =
false;
978 for (
const char *p = name_equal_value; *p !=
'\0' && !send_hex_encoding;
980 if (llvm::isPrint(*p)) {
986 send_hex_encoding =
true;
993 send_hex_encoding =
true;
1001 packet.
Printf(
"QEnvironment:%s", name_equal_value);
1020 packet.
PutCString(
"QEnvironmentHexEncoded:");
1042 if (arch && arch[0]) {
1044 packet.
Printf(
"QLaunchArch:%s", arch);
1059 char const *data,
bool *was_supported) {
1060 if (data && *data !=
'\0') {
1062 packet.
Printf(
"QSetProcessEvent:%s", data);
1068 *was_supported =
true;
1072 *was_supported =
false;
1077 *was_supported =
true;
1101 return std::nullopt;
1104std::optional<std::string>
1110 return std::nullopt;
1138 UUID &uuid,
addr_t &value,
bool &value_is_offset) {
1171 llvm::StringRef name, value;
1172 bool success =
false;
1174 if (name ==
"name") {
1177 }
else if (name ==
"version") {
1178 llvm::StringRef major, minor;
1179 std::tie(major, minor) = value.split(
'.');
1193 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1195 llvm::StringRef avail_name;
1197#if HAVE_LIBCOMPRESSION
1199 for (
auto compression : supported_compressions) {
1200 if (compression ==
"lzfse") {
1202 avail_name = compression;
1208 for (
auto compression : supported_compressions) {
1209 if (compression ==
"zlib-deflate") {
1211 avail_name = compression;
1220 for (
auto compression : supported_compressions) {
1221 if (compression ==
"zlib-deflate") {
1223 avail_name = compression;
1230#if HAVE_LIBCOMPRESSION
1232 for (
auto compression : supported_compressions) {
1233 if (compression ==
"lz4") {
1235 avail_name = compression;
1241 for (
auto compression : supported_compressions) {
1242 if (compression ==
"lzma") {
1244 avail_name = compression;
1253 std::string packet =
"QEnableCompression:type:" + avail_name.str() +
";";
1300 tid = pid_tid->second;
1307 std::string &environment) {
1308 if (value ==
"iossimulator" || value ==
"tvossimulator" ||
1309 value ==
"watchossimulator" || value ==
"xrossimulator" ||
1310 value ==
"visionossimulator") {
1311 environment =
"simulator";
1312 os_name = value.drop_back(environment.size()).str();
1313 }
else if (value ==
"maccatalyst") {
1315 environment =
"macabi";
1317 os_name = value.str();
1333 llvm::StringRef name;
1334 llvm::StringRef value;
1337 std::string arch_name;
1338 std::string os_name;
1339 std::string environment;
1340 std::string vendor_name;
1342 uint32_t pointer_byte_size = 0;
1344 uint32_t num_keys_decoded = 0;
1346 if (name ==
"cputype") {
1348 if (!value.getAsInteger(0, cpu))
1350 }
else if (name ==
"cpusubtype") {
1352 if (!value.getAsInteger(0, sub))
1354 }
else if (name ==
"arch") {
1355 arch_name = std::string(value);
1357 }
else if (name ==
"triple") {
1361 }
else if (name ==
"distribution_id") {
1365 }
else if (name ==
"os_build") {
1369 }
else if (name ==
"hostname") {
1373 }
else if (name ==
"os_kernel") {
1377 }
else if (name ==
"ostype") {
1380 }
else if (name ==
"vendor") {
1381 vendor_name = std::string(value);
1383 }
else if (name ==
"endian") {
1384 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1391 }
else if (name ==
"ptrsize") {
1392 if (!value.getAsInteger(0, pointer_byte_size))
1394 }
else if (name ==
"addressing_bits") {
1398 }
else if (name ==
"high_mem_addressing_bits") {
1401 }
else if (name ==
"low_mem_addressing_bits") {
1404 }
else if (name ==
"os_version" ||
1411 }
else if (name ==
"maccatalyst_version") {
1414 }
else if (name ==
"watchpoint_exceptions_received") {
1416 llvm::StringSwitch<LazyBool>(value)
1422 }
else if (name ==
"default_packet_timeout") {
1423 uint32_t timeout_seconds;
1424 if (!value.getAsInteger(0, timeout_seconds)) {
1429 }
else if (name ==
"vm-page-size") {
1431 if (!value.getAsInteger(0, page_size)) {
1438 if (num_keys_decoded > 0)
1441 if (triple.empty()) {
1442 if (arch_name.empty()) {
1445 if (pointer_byte_size) {
1446 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1452 if (!vendor_name.empty())
1454 llvm::StringRef(vendor_name));
1455 if (!os_name.empty())
1456 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1457 if (!environment.empty())
1458 m_host_arch.GetTriple().setEnvironmentName(environment);
1462 triple += arch_name;
1463 if (!vendor_name.empty() || !os_name.empty()) {
1465 if (vendor_name.empty())
1466 triple +=
"unknown";
1468 triple += vendor_name;
1470 if (os_name.empty())
1471 triple +=
"unknown";
1477 llvm::Triple &host_triple =
m_host_arch.GetTriple();
1478 if (host_triple.getVendor() == llvm::Triple::Apple &&
1479 host_triple.getOS() == llvm::Triple::Darwin) {
1481 case llvm::Triple::aarch64:
1482 case llvm::Triple::aarch64_32:
1483 case llvm::Triple::arm:
1484 case llvm::Triple::thumb:
1485 host_triple.setOS(llvm::Triple::IOS);
1488 host_triple.setOS(llvm::Triple::MacOSX);
1492 if (pointer_byte_size) {
1493 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1501 if (pointer_byte_size) {
1502 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1509 "GDBRemoteCommunicationClient::%s parsed host "
1510 "architecture as %s, triple as %s from triple text %s",
1514 :
"<null-arch-name>",
1525 const char *data,
size_t data_len, std::chrono::seconds interrupt_timeout) {
1531 interrupt_timeout) ==
1555 return addressable_bits;
1565 uint32_t permissions) {
1569 const int packet_len = ::snprintf(
1570 packet,
sizeof(packet),
"_M%" PRIx64
",%s%s%s", (uint64_t)size,
1571 permissions & lldb::ePermissionsReadable ?
"r" :
"",
1572 permissions & lldb::ePermissionsWritable ?
"w" :
"",
1573 permissions & lldb::ePermissionsExecutable ?
"x" :
"");
1574 assert(packet_len < (
int)
sizeof(packet));
1594 const int packet_len =
1595 ::snprintf(packet,
sizeof(packet),
"_m%" PRIx64, (uint64_t)addr);
1596 assert(packet_len < (
int)
sizeof(packet));
1621 const int packet_len =
1622 ::snprintf(packet,
sizeof(packet),
"qSupportsDetachAndStayStopped:");
1623 assert(packet_len < (
int)
sizeof(packet));
1637 "Stays stopped not supported by this target.");
1653 "Multiprocess extension not supported by the server.");
1668 region_info.
Clear();
1673 const int packet_len = ::snprintf(
1674 packet,
sizeof(packet),
"qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1675 assert(packet_len < (
int)
sizeof(packet));
1681 llvm::StringRef name;
1682 llvm::StringRef value;
1684 bool success =
true;
1685 bool saw_permissions =
false;
1687 if (name ==
"start") {
1688 if (!value.getAsInteger(16, addr_value))
1690 }
else if (name ==
"size") {
1691 if (!value.getAsInteger(16, addr_value)) {
1699 }
else if (name ==
"permissions" && region_info.
GetRange().
IsValid()) {
1700 saw_permissions =
true;
1702 if (value.contains(
'r'))
1707 if (value.contains(
'w'))
1712 if (value.contains(
'x'))
1726 }
else if (name ==
"name") {
1730 region_info.
SetName(name.c_str());
1731 }
else if (name ==
"flags") {
1735 llvm::StringRef flags = value;
1736 llvm::StringRef flag;
1737 while (flags.size()) {
1738 flags = flags.ltrim();
1739 std::tie(flag, flags) = flags.split(
' ');
1744 else if (flag ==
"ss")
1748 }
else if (name ==
"type") {
1749 for (llvm::StringRef entry : llvm::split(value,
',')) {
1750 if (entry ==
"stack")
1752 else if (entry ==
"heap")
1755 }
else if (name ==
"error") {
1757 std::string error_string;
1761 }
else if (name ==
"dirty-pages") {
1762 std::vector<addr_t> dirty_page_list;
1763 for (llvm::StringRef x : llvm::split(value,
',')) {
1765 x.consume_front(
"0x");
1766 if (llvm::to_integer(x, page, 16))
1767 dirty_page_list.push_back(page);
1770 }
else if (name ==
"protection-key") {
1771 unsigned protection_key = 0;
1772 if (!value.getAsInteger(10, protection_key))
1783 if (!saw_permissions) {
1811 region_info = qXfer_region_info;
1814 region_info.
Clear();
1816 }
else if (qXfer_error.
Success()) {
1831 if (!
error.Success())
1834 if (map_region.GetRange().Contains(addr)) {
1835 region = map_region;
1861 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1867 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1883 if (memory_node.
GetName() !=
"memory")
1895 if (type ==
"rom") {
1898 }
else if (type ==
"ram") {
1902 }
else if (type ==
"flash") {
1905 [®ion](
const XMLNode &prop_node) ->
bool {
1908 if (prop_node.
GetName() !=
"property")
1911 if (propname ==
"blocksize") {
1933 std::optional<uint32_t> num;
1939 llvm::StringRef name;
1940 llvm::StringRef value;
1942 if (name ==
"num") {
1958WatchpointHardwareFeature
1977 return std::nullopt;
1982 std::string path{file_spec.
GetPath(
false)};
2002 std::string path{file_spec.
GetPath(
false)};
2022 std::string path{file_spec.
GetPath(
false)};
2043 if ((cols == 0) != (rows == 0))
2046 packet.
Printf(
"QSetSTDIOWindowSize:cols=%u;rows=%u",
2047 static_cast<unsigned>(cols),
static_cast<unsigned>(rows));
2071 return !cwd.empty();
2078 std::string path{working_dir.
GetPath(
false)};
2098 const int packet_len =
2099 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
2100 assert(packet_len < (
int)
sizeof(packet));
2115 const int packet_len = ::snprintf(packet,
sizeof(packet),
2116 "QSetDetachOnError:%i", enable ? 1 : 0);
2117 assert(packet_len < (
int)
sizeof(packet));
2133 llvm::StringRef name;
2134 llvm::StringRef value;
2140 std::string os_type;
2143 if (name ==
"pid") {
2145 value.getAsInteger(0, pid);
2147 }
else if (name ==
"ppid") {
2149 value.getAsInteger(0, pid);
2151 }
else if (name ==
"uid") {
2153 value.getAsInteger(0, uid);
2155 }
else if (name ==
"euid") {
2157 value.getAsInteger(0, uid);
2159 }
else if (name ==
"gid") {
2161 value.getAsInteger(0, gid);
2163 }
else if (name ==
"egid") {
2165 value.getAsInteger(0, gid);
2167 }
else if (name ==
"triple") {
2172 }
else if (name ==
"name") {
2179 }
else if (name ==
"args") {
2180 llvm::StringRef encoded_args(value), hex_arg;
2182 bool is_arg0 =
true;
2183 while (!encoded_args.empty()) {
2184 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2199 }
else if (name ==
"cputype") {
2200 value.getAsInteger(0, cpu);
2201 }
else if (name ==
"cpusubtype") {
2202 value.getAsInteger(0, sub);
2203 }
else if (name ==
"vendor") {
2204 vendor = std::string(value);
2205 }
else if (name ==
"ostype") {
2206 os_type = std::string(value);
2211 if (vendor ==
"apple") {
2215 llvm::StringRef(vendor));
2217 llvm::StringRef(os_type));
2229 process_info.
Clear();
2233 const int packet_len =
2234 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2235 assert(packet_len < (
int)
sizeof(packet));
2265 llvm::StringRef name;
2266 llvm::StringRef value;
2269 std::string os_name;
2270 std::string environment;
2271 std::string vendor_name;
2273 std::string elf_abi;
2274 uint32_t pointer_byte_size = 0;
2277 uint32_t num_keys_decoded = 0;
2280 if (name ==
"cputype") {
2281 if (!value.getAsInteger(16, cpu))
2283 }
else if (name ==
"cpusubtype") {
2284 if (!value.getAsInteger(16, sub)) {
2290 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2291 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2298 }
else if (name ==
"triple") {
2302 }
else if (name ==
"ostype") {
2305 }
else if (name ==
"vendor") {
2306 vendor_name = std::string(value);
2308 }
else if (name ==
"endian") {
2309 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2316 }
else if (name ==
"ptrsize") {
2317 if (!value.getAsInteger(16, pointer_byte_size))
2319 }
else if (name ==
"pid") {
2320 if (!value.getAsInteger(16, pid))
2322 }
else if (name ==
"elf_abi") {
2323 elf_abi = std::string(value);
2325 }
else if (name ==
"main-binary-uuid") {
2328 }
else if (name ==
"main-binary-slide") {
2336 }
else if (name ==
"main-binary-address") {
2344 }
else if (name ==
"binary-addresses") {
2347 for (llvm::StringRef x : llvm::split(value,
',')) {
2349 x.consume_front(
"0x");
2350 if (llvm::to_integer(x, vmaddr, 16))
2355 if (num_keys_decoded > 0)
2363 if (!triple.empty()) {
2366 if (pointer_byte_size) {
2367 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2370 !vendor_name.empty()) {
2371 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2372 if (!environment.empty())
2373 triple.setEnvironmentName(environment);
2375 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2376 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2377 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2378 switch (triple.getObjectFormat()) {
2379 case llvm::Triple::MachO:
2382 case llvm::Triple::ELF:
2385 case llvm::Triple::COFF:
2388 case llvm::Triple::GOFF:
2389 case llvm::Triple::SPIRV:
2390 case llvm::Triple::Wasm:
2391 case llvm::Triple::XCOFF:
2392 case llvm::Triple::DXContainer:
2393 LLDB_LOGF(log,
"error: not supported target architecture");
2395 case llvm::Triple::UnknownObjectFormat:
2396 LLDB_LOGF(log,
"error: failed to determine target architecture");
2400 if (pointer_byte_size) {
2401 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2406 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2408 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2422 process_infos.clear();
2430 bool has_name_match =
false;
2431 if (!name.empty()) {
2432 has_name_match =
true;
2434 switch (name_match_type) {
2436 has_name_match =
false;
2448 packet.
PutCString(
"name_match:starts_with;");
2459 if (has_name_match) {
2467 packet.
Printf(
"pid:%" PRIu64
";",
2470 packet.
Printf(
"parent_pid:%" PRIu64
";",
2477 packet.
Printf(
"euid:%u;",
2480 packet.
Printf(
"egid:%u;",
2486 const llvm::Triple &triple = match_arch.
GetTriple();
2502 process_infos.push_back(process_info);
2511 return process_infos.size();
2515 std::string &name) {
2518 const int packet_len =
2519 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2520 assert(packet_len < (
int)
sizeof(packet));
2542 std::string &name) {
2545 const int packet_len =
2546 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2547 assert(packet_len < (
int)
sizeof(packet));
2569 uint32_t recv_size) {
2571 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2572 uint32_t bytes_left = send_size;
2573 while (bytes_left > 0) {
2574 if (bytes_left >= 26) {
2575 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2578 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2579 "abcdefghijklmnopqrstuvwxyz");
2588 return duration<float>::zero();
2589 using Dur = duration<float>;
2590 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2591 Dur mean = sum / v.size();
2594 float delta = (d - mean).count();
2595 accum += delta * delta;
2598 return Dur(sqrtf(accum / (v.size() - 1)));
2604 uint64_t recv_amount,
2605 bool json,
Stream &strm) {
2610 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2614 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2618 uint32_t result_idx = 0;
2620 std::vector<duration<float>> packet_times;
2622 for (send_size = 0; send_size <= max_send;
2623 send_size ? send_size *= 2 : send_size = 4) {
2624 for (uint32_t recv_size = 0; recv_size <= max_recv;
2625 recv_size ? recv_size *= 2 : recv_size = 4) {
2628 packet_times.clear();
2630 const auto start_time = steady_clock::now();
2631 for (uint32_t i = 0; i < num_packets; ++i) {
2632 const auto packet_start_time = steady_clock::now();
2635 const auto packet_end_time = steady_clock::now();
2636 packet_times.push_back(packet_end_time - packet_start_time);
2638 const auto end_time = steady_clock::now();
2639 const auto total_time = end_time - start_time;
2641 float packets_per_second =
2642 ((float)num_packets) / duration<float>(total_time).count();
2643 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2644 : duration<float>::zero();
2645 const duration<float> standard_deviation =
2648 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2649 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2650 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2651 result_idx > 0 ?
"," :
"", send_size, recv_size,
2652 total_time, standard_deviation);
2655 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2656 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2657 "standard deviation of {5,10:ms+f6}\n",
2658 send_size, recv_size, duration<float>(total_time),
2659 packets_per_second, duration<float>(average_per_packet),
2660 standard_deviation);
2666 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2668 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2669 ": %" PRIu64
",\n \"results\" : [",
2672 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2678 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2683 if (recv_size > 0) {
2684 const auto start_time = steady_clock::now();
2685 uint32_t bytes_read = 0;
2686 uint32_t packet_count = 0;
2687 while (bytes_read < recv_amount) {
2690 bytes_read += recv_size;
2693 const auto end_time = steady_clock::now();
2694 const auto total_time = end_time - start_time;
2695 float mb_second = ((float)recv_amount) /
2696 duration<float>(total_time).count() /
2698 float packets_per_second =
2699 ((float)packet_count) / duration<float>(total_time).count();
2700 const auto average_per_packet = packet_count > 0
2701 ? total_time / packet_count
2702 : duration<float>::zero();
2705 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2706 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2707 result_idx > 0 ?
"," :
"", send_size, recv_size,
2711 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2712 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2713 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2714 send_size, recv_size, packet_count, k_recv_amount_mb,
2715 duration<float>(total_time), mb_second,
2716 packets_per_second, duration<float>(average_per_packet));
2722 strm.
Printf(
"\n ]\n }\n}\n");
2729 uint32_t recv_size) {
2739 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2740 std::string &socket_name) {
2743 socket_name.clear();
2748 std::string hostname;
2749 if (remote_accept_hostname && remote_accept_hostname[0])
2750 hostname = remote_accept_hostname;
2752 if (HostInfo::GetHostname(hostname)) {
2754 stream.
Printf(
"host:%s;", hostname.c_str());
2758 stream.
Printf(
"host:*;");
2769 llvm::StringRef name;
2770 llvm::StringRef value;
2773 value.getAsInteger(0, port);
2774 else if (name ==
"pid")
2775 value.getAsInteger(0, pid);
2776 else if (name.compare(
"socket_name") == 0) {
2787 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2788 connection_urls.clear();
2804 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2805 std::optional<StructuredData::Dictionary *> maybe_element =
2814 port = port_osp->GetUnsignedIntegerValue(0);
2816 std::string socket_name;
2819 socket_name = std::string(socket_name_osp->GetStringValue());
2821 if (port != 0 || !socket_name.empty())
2822 connection_urls.emplace_back(port, socket_name);
2824 return connection_urls.size();
2829 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2841 uint64_t tid, uint64_t pid,
char op) {
2847 packet.
Printf(
"p%" PRIx64
".", pid);
2852 packet.
Printf(
"%" PRIx64, tid);
2858 return {{pid, tid}};
2870 return std::nullopt;
2885 return ret.has_value();
2900 return ret.has_value();
2915 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2916 assert(packet_len < (
int)
sizeof(packet));
2935 std::chrono::seconds timeout) {
2937 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2938 __FUNCTION__, insert ?
"add" :
"remove", addr);
2945 const int packet_len =
2946 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2947 insert ?
'Z' :
'z', type, addr, length);
2949 assert(packet_len + 1 < (
int)
sizeof(packet));
2994std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2996 bool &sequence_mutex_unavailable) {
2997 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
3001 sequence_mutex_unavailable =
false;
3005 for (packet_result =
3023 ids.push_back(*pid_tid);
3025 }
while (ch ==
',');
3039 ids.emplace_back(1, 1);
3043 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
3044 "packet 'qfThreadInfo'");
3045 sequence_mutex_unavailable =
true;
3052 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
3057 if (ids.empty() || sequence_mutex_unavailable)
3060 for (
auto id : ids) {
3066 thread_ids.push_back(
id.second);
3069 return thread_ids.size();
3082 llvm::StringRef command,
3090 std::string *separated_error_output,
3100 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3104 std::string path{working_dir.
GetPath(
false)};
3111 if (response.
GetChar() !=
'F')
3113 if (response.
GetChar() !=
',')
3118 else if (status_ptr)
3119 *status_ptr = exitcode;
3120 if (response.
GetChar() !=
',')
3125 if (response.
GetChar() !=
',')
3130 command_output->assign(output);
3137 uint32_t file_permissions) {
3138 std::string path{file_spec.
GetPath(
false)};
3144 llvm::StringRef packet = stream.
GetString();
3149 packet.str().c_str());
3151 if (response.
GetChar() !=
'F')
3153 packet.str().c_str());
3160 uint32_t file_permissions) {
3161 std::string path{file_spec.
GetPath(
false)};
3167 llvm::StringRef packet = stream.
GetString();
3174 if (response.
GetChar() !=
'F')
3183#define HANDLE_ERRNO(name, value) \
3186#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3195 if (response.
GetChar() !=
'F')
3197 int32_t result = response.
GetS32(-2, 16);
3200 if (response.
GetChar() ==
',') {
3202 if (result_errno != -1)
3214 std::string path(file_spec.
GetPath(
false));
3235 stream.
Printf(
"vFile:close:%x", (
int)fd);
3244std::optional<GDBRemoteFStatData>
3247 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3251 if (response.
GetChar() !=
'F')
3252 return std::nullopt;
3253 int64_t size = response.
GetS64(-1, 16);
3254 if (size > 0 && response.
GetChar() ==
';') {
3258 if (buffer.size() !=
sizeof(out))
3259 return std::nullopt;
3260 memcpy(&out, buffer.data(),
sizeof(out));
3265 return std::nullopt;
3268std::optional<GDBRemoteFStatData>
3273 return std::nullopt;
3274 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3283 std::string path(file_spec.
GetPath(
false));
3293 if (response.
GetChar() !=
'F')
3302 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3320 while (response.
Peek()) {
3322 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3325 if (response.
GetChar() !=
',')
3333 uint32_t &file_permissions) {
3335 std::string path{file_spec.
GetPath(
false)};
3348 if (response.
GetChar() !=
'F') {
3350 "invalid response to '%s' packet", stream.
GetData());
3352 const uint32_t mode = response.
GetS32(-1, 16);
3353 if (
static_cast<int32_t
>(mode) == -1) {
3354 if (response.
GetChar() ==
',') {
3356 if (response_errno > 0)
3373 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3381 uint64_t offset,
void *dst,
3385 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3390 if (response.
GetChar() !=
'F')
3392 int64_t retcode = response.
GetS64(-1, 16);
3393 if (retcode == -1) {
3395 if (response.
GetChar() ==
',') {
3397 if (response_errno > 0)
3402 const char next = (response.
Peek() ? *response.
Peek() : 0);
3409 const uint64_t data_to_write =
3410 std::min<uint64_t>(dst_len, buffer.size());
3411 if (data_to_write > 0)
3412 memcpy(dst, &buffer[0], data_to_write);
3413 return data_to_write;
3426 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3431 if (response.
GetChar() !=
'F') {
3435 int64_t bytes_written = response.
GetS64(-1, 16);
3436 if (bytes_written == -1) {
3438 if (response.
GetChar() ==
',') {
3440 if (response_errno > 0)
3445 return bytes_written;
3454 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3466 if (response.
GetChar() ==
'F') {
3470 if (response.
GetChar() ==
',') {
3472 if (response_errno > 0)
3487 std::string path{file_spec.
GetPath(
false)};
3497 if (response.
GetChar() ==
'F') {
3501 if (response.
GetChar() ==
',') {
3503 if (response_errno > 0)
3521 std::string path(file_spec.
GetPath(
false));
3530 if (response.
GetChar() !=
'F')
3532 if (response.
GetChar() !=
',')
3534 bool retcode = (response.
GetChar() !=
'0');
3551 std::string path(file_spec.
GetPath(
false));
3558 if (response.
GetChar() !=
'F')
3559 return std::make_error_code(std::errc::illegal_byte_sequence);
3560 if (response.
GetChar() !=
',')
3561 return std::make_error_code(std::errc::illegal_byte_sequence);
3562 if (response.
Peek() && *response.
Peek() ==
'x')
3563 return std::make_error_code(std::errc::no_such_file_or_directory);
3580 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3585 if (part.size() != MD5_HALF_LENGTH)
3586 return std::make_error_code(std::errc::illegal_byte_sequence);
3590 if (part.getAsInteger(16, low))
3591 return std::make_error_code(std::errc::illegal_byte_sequence);
3596 if (part.size() != MD5_HALF_LENGTH)
3597 return std::make_error_code(std::errc::illegal_byte_sequence);
3601 if (part.getAsInteger(16, high))
3602 return std::make_error_code(std::errc::illegal_byte_sequence);
3604 llvm::MD5::MD5Result result;
3605 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3606 result.data(), low);
3607 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3608 result.data() + 8, high);
3612 return std::make_error_code(std::errc::operation_canceled);
3622 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3623 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3624 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3625 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3628 if (gdb_server_version != 0) {
3630 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3631 if (gdb_server_version >= 310)
3644 payload.
Printf(
"p%x", reg);
3653 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3668 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3674 llvm::ArrayRef<uint8_t> data) {
3676 payload.
Printf(
"P%x=", reg_num);
3700 uint32_t &save_id) {
3716 const uint32_t response_save_id = response.
GetU32(0);
3717 if (response_save_id == 0)
3720 save_id = response_save_id;
3733 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3753 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3759llvm::Expected<TraceSupportedResponse>
3764 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3773 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3774 "jLLDBTraceSupported is unsupported");
3776 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3777 "TraceSupportedResponse");
3779 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3780 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3781 "failed to send packet: jLLDBTraceSupported");
3786 std::chrono::seconds timeout) {
3790 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3792 std::string json_string;
3793 llvm::raw_string_ostream os(json_string);
3796 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3805 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3806 "jLLDBTraceStop is unsupported");
3808 return llvm::Error::success();
3809 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3810 "Invalid jLLDBTraceStart response");
3812 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3813 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3814 "failed to send packet: jLLDBTraceStop '%s'",
3820 std::chrono::seconds timeout) {
3824 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3826 std::string json_string;
3827 llvm::raw_string_ostream os(json_string);
3830 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3839 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3840 "jLLDBTraceStart is unsupported");
3842 return llvm::Error::success();
3843 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3844 "Invalid jLLDBTraceStart response");
3846 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3847 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3848 "failed to send packet: jLLDBTraceStart '%s'",
3852llvm::Expected<std::string>
3854 std::chrono::seconds timeout) {
3858 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3860 std::string json_string;
3861 llvm::raw_string_ostream os(json_string);
3864 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3873 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3874 "jLLDBTraceGetState is unsupported");
3875 return std::string(response.
Peek());
3878 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3879 return llvm::createStringError(
3880 llvm::inconvertibleErrorCode(),
3881 "failed to send packet: jLLDBTraceGetState '%s'",
3885llvm::Expected<std::vector<uint8_t>>
3891 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3893 std::string json_string;
3894 llvm::raw_string_ostream os(json_string);
3897 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3907 return std::vector<uint8_t>(data.begin(), data.end());
3909 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3910 return llvm::createStringError(
3911 llvm::inconvertibleErrorCode(),
3912 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3920 return std::nullopt;
3922 return std::nullopt;
3926 const auto &GetOffset = [&] {
3928 if (ref.consumeInteger(16, offset))
3930 result.
offsets.push_back(offset);
3934 if (ref.consume_front(
"Text=")) {
3937 return std::nullopt;
3938 if (!ref.consume_front(
";Data=") || !GetOffset())
3939 return std::nullopt;
3942 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3944 }
else if (ref.consume_front(
"TextSeg=")) {
3947 return std::nullopt;
3950 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3953 return std::nullopt;
3962 std::string module_path = module_file_spec.
GetPath(
false);
3963 if (module_path.empty())
3970 const auto &triple = arch_spec.
GetTriple().getTriple();
3986 llvm::StringRef name;
3987 llvm::StringRef value;
3989 module_spec.
Clear();
3993 if (name ==
"uuid" || name ==
"md5") {
3998 }
else if (name ==
"triple") {
4003 }
else if (name ==
"file_offset") {
4005 if (!value.getAsInteger(16, ival))
4007 }
else if (name ==
"file_size") {
4009 if (!value.getAsInteger(16, ival))
4011 }
else if (name ==
"file_path") {
4022static std::optional<ModuleSpec>
4026 return std::nullopt;
4028 llvm::StringRef string;
4032 return std::nullopt;
4034 return std::nullopt;
4037 return std::nullopt;
4041 return std::nullopt;
4045 return std::nullopt;
4049 return std::nullopt;
4055std::optional<std::vector<ModuleSpec>>
4057 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4061 return std::nullopt;
4063 json::Array module_array;
4064 for (
const FileSpec &module_file_spec : module_file_specs) {
4065 module_array.push_back(
4066 json::Object{{
"file", module_file_spec.GetPath(
false)},
4067 {
"triple", triple.getTriple()}});
4070 unescaped_payload.
PutCString(
"jModulesInfo:");
4071 unescaped_payload.
AsRawOstream() << std::move(module_array);
4084 return std::nullopt;
4088 return std::nullopt;
4093 if (!response_object_sp)
4094 return std::nullopt;
4097 if (!response_array)
4098 return std::nullopt;
4100 std::vector<ModuleSpec> result;
4101 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
4104 result.push_back(*module_spec);
4114llvm::Expected<std::string>
4116 llvm::StringRef annex) {
4119 llvm::raw_string_ostream output_stream(output);
4133 std::string packet =
4134 (
"qXfer:" +
object +
":read:" + annex +
":" +
4135 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4143 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4144 "Error sending $qXfer packet");
4162 return llvm::createStringError(
4163 llvm::inconvertibleErrorCode(),
4164 "Invalid continuation code from $qXfer packet");
4214 bool symbol_response_provided =
false;
4217 bool first_qsymbol_query =
true;
4228 if (symbol_response_provided || first_qsymbol_query) {
4235 first_qsymbol_query =
false;
4244 if (response_str.starts_with(
"qSymbol:")) {
4246 std::string symbol_name;
4248 if (symbol_name.empty())
4259 switch (sc.symbol->GetType()) {
4292 sc.symbol->GetLoadAddress(&process->
GetTarget());
4305 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4306 symbol_response_provided =
true;
4308 symbol_response_provided =
false;
4324 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4349 "GDBRemoteCommunicationClient::%s(): "
4350 "QSupportedAsyncJSONPackets returned invalid "
4357 "GDBRemoteCommunicationClient::%s(): "
4358 "QSupportedAsyncJSONPackets unsupported",
4366 "GDBRemoteCommunicationClient::%s(): supported async "
4368 __FUNCTION__, stream.
GetData());
4378 llvm::ArrayRef<int32_t> signals) {
4381 auto range = llvm::make_range(signals.begin(), signals.end());
4382 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4394 "Unknown error happened during sending QPassSignals packet.");
4402 if (type_name.empty()) {
4415 config_sp->Dump(unescaped_stream);
4416 unescaped_stream.
Flush();
4434 "configuring StructuredData feature {0} failed with error {1}",
4440 "configuring StructuredData feature {0} failed when sending packet: "
4442 type_name, (
int)result);
4471 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4472 "failed to send k packet");
4474 char packet_cmd = response.
GetChar(0);
4475 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4478 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4479 "unexpected response to k packet: %s",
static llvm::raw_ostream & error(Stream &strm)
duration< float > calculate_standard_deviation(const std::vector< duration< float > > &v)
static std::optional< ModuleSpec > ParseModuleSpec(StructuredData::Dictionary *dict)
static int gdb_errno_to_system(int err)
static void ParseOSType(llvm::StringRef value, std::string &os_name, std::string &environment)
static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response, uint64_t fail_result, Status &error)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
A command line argument class.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
void Clear()
Clear the arguments.
bool IsConnected() const
Check if the connection is valid.
virtual lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr)
Disconnect the communications connection if one is currently connected.
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
llvm::StringRef GetCursorArgumentPrefix() const
A uniqued constant string class.
A subclass of DataBuffer that stores a data buffer on the heap.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void SetReadable(LazyBool val)
LazyBool GetFlash() const
MemoryRegionInfo & SetMemoryTagged(LazyBool val)
void SetBlocksize(lldb::offset_t blocksize)
void SetFlash(LazyBool val)
void SetPageSize(int pagesize)
void SetName(const char *name)
MemoryRegionInfo & SetIsShadowStack(LazyBool val)
lldb::offset_t GetBlocksize() const
void SetDirtyPageList(std::vector< lldb::addr_t > pagelist)
MemoryRegionInfo & SetProtectionKey(std::optional< unsigned > key)
void SetIsStackMemory(LazyBool val)
void SetMapped(LazyBool val)
void SetExecutable(LazyBool val)
void SetWritable(LazyBool val)
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
void SetObjectSize(uint64_t object_size)
ArchSpec & GetArchitecture()
void SetObjectOffset(uint64_t object_offset)
void SetGroupID(uint32_t gid)
bool ProcessIDIsValid() const
void SetArg0(llvm::StringRef arg)
lldb::pid_t GetProcessID() const
void SetProcessID(lldb::pid_t pid)
FileSpec & GetExecutableFile()
llvm::StringRef GetName() const
bool UserIDIsValid() const
uint32_t GetUserID() const
uint32_t GetGroupID() const
void SetUserID(uint32_t uid)
bool GroupIDIsValid() const
ArchSpec & GetArchitecture()
bool MatchAllProcesses() const
NameMatch GetNameMatchType() const
bool GetMatchAllUsers() const
ProcessInstanceInfo & GetProcessInfo()
uint32_t GetEffectiveUserID() const
void SetEffectiveGroupID(uint32_t gid)
lldb::pid_t GetParentProcessID() const
bool ParentProcessIDIsValid() const
uint32_t GetEffectiveGroupID() const
bool EffectiveUserIDIsValid() const
bool EffectiveGroupIDIsValid() const
void SetParentProcessID(lldb::pid_t pid)
void SetEffectiveUserID(uint32_t uid)
A plug-in interface definition class for debugging a process.
Target & GetTarget()
Get the target object pointer for this module.
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
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.
int PutAsJSON(const T &obj, bool hex_ascii)
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.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
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)
virtual void Flush()=0
Flush the stream.
size_t EOL()
Output and End of Line character 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
std::optional< Dictionary * > GetItemAtIndexAsDictionary(size_t idx) const
Retrieves the element at index idx from a StructuredData::Array if it is a Dictionary.
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
ObjectSP GetValueForKey(llvm::StringRef key) const
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
Defines a list of symbol context objects.
Defines a symbol context baton that can be handed other debug core functions.
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
Represents UUID's of various sizes.
bool SetFromStringRef(llvm::StringRef str)
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
std::string GetAttributeValue(const char *name, const char *fail_value=nullptr) const
bool GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value=0, int base=0) const
bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value, uint64_t fail_value=0, int base=0) const
GDBRemoteClientBase(const char *comm_name)
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0), bool sync_on_timeout=true)
PacketResult SendPacketAndWaitForResponseNoLock(llvm::StringRef payload, StringExtractorGDBRemote &response, bool sync_on_timeout=true)
virtual void OnRunPacketSent(bool first)
lldb::DataBufferSP ReadRegister(lldb::tid_t tid, uint32_t reg_num)
std::chrono::seconds m_default_packet_timeout
LazyBool m_supports_vCont_S
LazyBool m_supports_detach_stay_stopped
LazyBool m_supports_alloc_dealloc_memory
bool SupportsGDBStoppointPacket(GDBStoppointType type)
ArchSpec GetSystemArchitecture()
bool RestoreRegisterState(lldb::tid_t tid, uint32_t save_id)
const ArchSpec & GetHostArchitecture()
int SendLaunchArchPacket(const char *arch)
lldb::pid_t GetCurrentProcessID(bool allow_lazy=true)
bool AvoidGPackets(ProcessGDBRemote *process)
llvm::VersionTuple GetMacCatalystVersion()
Status CreateSymlink(const FileSpec &src, const FileSpec &dst)
PacketResult SendThreadSpecificPacketAndWaitForResponse(lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response)
LazyBool m_qGDBServerVersion_is_valid
bool GetLoadedDynamicLibrariesInfosSupported()
bool GetHostInfo(bool force=false)
LazyBool m_supports_memory_region_info
LazyBool m_qHostInfo_is_valid
bool KillSpawnedProcess(lldb::pid_t pid)
bool m_supports_jModulesInfo
lldb_private::AddressableBits GetAddressableBits()
LazyBool m_supports_jGetSharedCacheInfo
bool GetReverseContinueSupported()
bool GetGroupName(uint32_t gid, std::string &name)
bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
std::optional< std::string > GetOSKernelDescription()
int SendEnvironment(const Environment &env)
LazyBool m_supports_augmented_libraries_svr4_read
uint32_t m_high_mem_addressing_bits
llvm::VersionTuple GetOSVersion()
std::optional< uint32_t > GetWatchpointSlotCount()
bool HandshakeWithServer(Status *error_ptr)
bool GetAugmentedLibrariesSVR4ReadSupported()
lldb_private::StructuredData::Array * GetSupportedStructuredDataPlugins()
Return the array of async JSON packet types supported by the remote.
bool m_supports_vFileSize
uint64_t GetRemoteMaxPacketSize()
bool QueryNoAckModeSupported()
lldb::tid_t m_curr_tid_run
Current gdb remote protocol thread identifier for continue, step, etc.
int SetSTDIOWindowSize(uint16_t cols, uint16_t rows)
Send the dimensions of the user's stdio terminal window to the server.
int SendLaunchEventDataPacket(const char *data, bool *was_supported=nullptr)
bool m_qSymbol_requests_done
bool GetCurrentProcessInfo(bool allow_lazy_pid=true)
Status Unlink(const FileSpec &file_spec)
bool GetVAttachOrWaitSupported()
std::optional< std::vector< ModuleSpec > > GetModulesInfo(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple)
llvm::Expected< std::string > ReadExtFeature(llvm::StringRef object, llvm::StringRef annex)
LazyBool m_supports_qXfer_features_read
bool GetAcceleratorPluginsSupported()
bool m_supports_vFileMode
bool GetMultiprocessSupported()
LazyBool m_qProcessInfo_is_valid
LazyBool m_supports_vCont_c
std::optional< GDBRemoteFStatData > Stat(const FileSpec &file_spec)
std::optional< QOffsets > GetQOffsets()
Use qOffsets to query the offset used when relocating the target executable.
size_t QueryGDBServer(std::vector< std::pair< uint16_t, std::string > > &connection_urls)
int m_target_vm_page_size
llvm::Error SendTraceStop(const TraceStopRequest &request, std::chrono::seconds interrupt_timeout)
uint32_t m_num_supported_hardware_watchpoints
std::optional< xPacketState > m_x_packet_state
void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm)
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions)
std::string m_host_distribution_id
GDBRemoteCommunicationClient()
std::optional< std::string > GetOSBuildString()
bool LaunchGDBServer(const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port, std::string &socket_name)
int SetSTDOUT(const FileSpec &file_spec)
LazyBool m_prepare_for_reg_writing_reply
bool m_supports_qThreadStopInfo
bool SetCurrentThreadForRun(uint64_t tid, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
uint8_t SendGDBStoppointTypePacket(GDBStoppointType type, bool insert, lldb::addr_t addr, uint32_t length, std::chrono::seconds interrupt_timeout)
bool GetpPacketSupported(lldb::tid_t tid)
Status MakeDirectory(const FileSpec &file_spec, uint32_t mode)
uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error)
LazyBool m_supports_vCont_any
bool GetWorkingDir(FileSpec &working_dir)
Gets the current working directory of a remote platform GDB server.
lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, mode_t mode, Status &error)
LazyBool m_supports_error_string_reply
LazyBool m_supports_qXfer_siginfo_read
WatchpointHardwareFeature GetSupportedWatchpointTypes()
std::optional< GDBRemoteFStatData > FStat(lldb::user_id_t fd)
int SetSTDERR(const FileSpec &file_spec)
bool GetThreadSuffixSupported()
lldb::addr_t m_process_standalone_value
Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, std::string *separated_error_output, const Timeout< std::micro > &timeout)
LazyBool m_supports_memory_tagging
llvm::Expected< std::string > SendTraceGetState(llvm::StringRef type, std::chrono::seconds interrupt_timeout)
void ResetDiscoverableSettings(bool did_exec)
llvm::Error LaunchProcess(const Args &args)
Launch the process using the provided arguments.
LazyBool m_supports_qXfer_libraries_svr4_read
bool m_process_standalone_value_is_offset
lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp
LazyBool m_attach_or_wait_reply
bool m_supports_jThreadsInfo
bool GetGDBServerVersion()
lldb::user_id_t GetFileSize(const FileSpec &file_spec)
bool GetQXferFeaturesReadSupported()
LazyBool m_watchpoints_trigger_after_instruction
LazyBool m_supports_threads_in_stop_reply
std::vector< lldb::addr_t > m_binary_addresses
void GetRemoteQSupported()
bool GetQPassSignalsSupported()
Status ConfigureRemoteStructuredData(llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp)
Configure a StructuredData feature on the remote end.
bool CloseFile(lldb::user_id_t fd, Status &error)
~GDBRemoteCommunicationClient() override
bool GetReverseStepSupported()
uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error)
llvm::Expected< std::vector< AcceleratorActions > > GetAcceleratorInitializeActions()
Send the "jAcceleratorPluginInitialize" packet and return the actions requested by each accelerator p...
LazyBool m_supports_vCont_s
bool m_supports_qGroupName
bool SetCurrentThread(uint64_t tid, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
bool m_supports_vFileExists
bool GetDefaultThreadId(lldb::tid_t &tid)
void ServeSymbolLookups(lldb_private::Process *process)
LazyBool m_uses_native_signals
int SendStdinNotification(const char *data, size_t data_len, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0))
Sends a GDB remote protocol 'I' packet that delivers stdin data to the remote process.
uint32_t m_low_mem_addressing_bits
lldb::tid_t m_curr_tid
Current gdb remote protocol thread identifier for all other operations.
LazyBool m_supports_multi_breakpoint
LazyBool m_supports_qXfer_memory_map_read
bool GetHostname(std::string &s)
llvm::Expected< int > KillProcess(lldb::pid_t pid)
bool m_supported_async_json_packets_is_valid
bool GetSyncThreadStateSupported()
bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef< uint8_t > data)
bool m_supports_QEnvironmentHexEncoded
bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info)
Status SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
LazyBool m_curr_pid_is_valid
Status GetQXferMemoryMapRegionInfo(lldb::addr_t addr, MemoryRegionInfo ®ion)
int SetDetachOnError(bool enable)
Sets the DetachOnError flag to enable for the process controlled by the stub.
void OnRunPacketSent(bool first) override
bool m_supports_QEnvironment
lldb::addr_t GetShlibInfoAddr()
Status SendSignalsToIgnore(llvm::ArrayRef< int32_t > signals)
LazyBool m_supports_jThreadExtendedInfo
LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr)
UUID m_process_standalone_uuid
LazyBool m_supports_not_sending_acks
LazyBool m_supports_watchpoint_support_info
bool WriteRegister(lldb::tid_t tid, uint32_t reg_num, llvm::ArrayRef< uint8_t > data)
uint64_t m_max_packet_size
void EnableErrorStringInPacket()
LazyBool m_supports_accelerator_plugins
llvm::Expected< std::vector< uint8_t > > SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request, std::chrono::seconds interrupt_timeout)
LazyBool m_supports_qXfer_libraries_read
bool GetSaveCoreSupported() const
LazyBool m_supports_jLoadedDynamicLibrariesInfos
Status LoadQXferMemoryMap()
LazyBool m_supports_thread_suffix
int SetSTDIN(const FileSpec &file_spec)
Sets the path to use for stdin/out/err for a process that will be launched with the 'A' packet.
LazyBool m_supports_vCont_C
lldb::pid_t m_curr_pid
Current gdb remote protocol process identifier for all other operations.
Status WriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, const std::vector< uint8_t > &tags)
LazyBool m_supports_qSaveCore
LazyBool m_supports_reverse_step
bool GetQXferLibrariesSVR4ReadSupported()
size_t GetCurrentThreadIDs(std::vector< lldb::tid_t > &thread_ids, bool &sequence_mutex_unavailable)
Status Detach(bool keep_stopped, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
std::optional< bool > GetWatchpointReportedAfter()
std::string m_gdb_server_name
std::vector< lldb::addr_t > GetProcessStandaloneBinaries()
bool m_supports_qProcessInfoPID
llvm::VersionTuple m_os_version
bool GetQXferLibrariesReadSupported()
llvm::VersionTuple m_maccatalyst_version
int SetDisableASLR(bool enable)
Sets the disable ASLR flag to enable for a process that will be launched with the 'A' packet.
bool GetUserName(uint32_t uid, std::string &name)
Status GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info)
std::vector< MemoryRegionInfo > m_qXfer_memory_map
bool SyncThreadState(lldb::tid_t tid)
bool m_supports_qfProcessInfo
std::chrono::seconds GetHostDefaultPacketTimeout()
bool GetThreadExtendedInfoSupported()
lldb::DataBufferSP ReadAllRegisters(lldb::tid_t tid)
bool GetMemoryTaggingSupported()
void AutoCompleteDiskFileOrDirectory(CompletionRequest &request, bool only_dir)
lldb::pid_t m_curr_pid_run
Current gdb remote protocol process identifier for continue, step, etc.
LazyBool m_supports_multiprocess
void MaybeEnableCompression(llvm::ArrayRef< llvm::StringRef > supported_compressions)
bool GetDynamicLoaderProcessStateSupported()
const ArchSpec & GetProcessArchitecture()
bool DeallocateMemory(lldb::addr_t addr)
llvm::Expected< TraceSupportedResponse > SendTraceSupported(std::chrono::seconds interrupt_timeout)
bool GetQXferAuxvReadSupported()
bool GetMultiBreakpointSupported()
xPacketState GetxPacketState()
llvm::ErrorOr< llvm::MD5::MD5Result > CalculateMD5(const FileSpec &file_spec)
bool GetVContSupported(llvm::StringRef flavor)
uint32_t GetGDBServerProgramVersion()
LazyBool m_supports_reverse_continue
llvm::Error SendTraceStart(const llvm::json::Value &request, std::chrono::seconds interrupt_timeout)
bool GetStopReply(StringExtractorGDBRemote &response)
bool m_supports_qUserName
bool GetQXferMemoryMapReadSupported()
bool m_qXfer_memory_map_loaded
llvm::Expected< AcceleratorBreakpointHitResponse > AcceleratorBreakpointHit(const AcceleratorBreakpointHitArgs &args)
Send the "jAcceleratorPluginBreakpointHit" packet to notify the accelerator plugin that one of its re...
bool GetModuleInfo(const FileSpec &module_file_spec, const ArchSpec &arch_spec, ModuleSpec &module_spec)
LazyBool m_supports_vCont_all
std::optional< PidTid > SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid, char op)
bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size)
LazyBool m_supports_multi_mem_read
LazyBool m_supports_QPassSignals
bool GetFileExists(const FileSpec &file_spec)
Status GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
uint32_t FindProcesses(const ProcessInstanceInfoMatch &process_match_info, ProcessInstanceInfoList &process_infos)
lldb::DataBufferSP ReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type)
bool GetMultiMemReadSupported()
bool GetQXferSigInfoReadSupported()
uint32_t m_gdb_server_version
int SetWorkingDir(const FileSpec &working_dir)
Sets the working directory to path for a process that will be launched with the 'A' packet for non pl...
LazyBool m_avoid_g_packets
std::vector< std::pair< lldb::pid_t, lldb::tid_t > > GetCurrentProcessAndThreadIDs(bool &sequence_mutex_unavailable)
bool GetThreadStopInfo(lldb::tid_t tid, StringExtractorGDBRemote &response)
bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id)
bool GetProcessStandaloneBinary(UUID &uuid, lldb::addr_t &value, bool &value_is_offset)
LazyBool m_supports_QSaveRegisterState
WatchpointHardwareFeature m_watchpoint_types
void GetListThreadsInStopReplySupported()
StructuredData::ObjectSP GetThreadsInfo()
std::string m_qSupported_response
bool GetSharedCacheInfoSupported()
LazyBool m_supports_qXfer_auxv_read
bool m_supports_qModuleInfo
const char * GetGDBServerProgramName()
LazyBool m_supports_jGetDyldProcessState
int SendEnvironmentPacket(char const *name_equal_value)
Sends a "QEnvironment:NAME=VALUE" packet that will build up the environment that will get used when l...
std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout)
LazyBool m_supports_qEcho
CompressionType m_compression_type
std::chrono::seconds GetPacketTimeout() const
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_CPUTYPE
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
lldb::ByteOrder InlHostByteOrder()
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const QOffsets &offsets)
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.
llvm::json::Value toJSON(const SymbolValue &data)
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
@ eErrorTypeGeneric
Generic errors that can be any value.
@ eErrorTypePOSIX
POSIX error codes.
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
Sent by the client when a plugin-requested breakpoint is hit.
bool Contains(BaseType r) const
BaseType GetRangeBase() const
void SetRangeEnd(BaseType end)
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
The offsets used by the target when relocating the executable.
bool segments
If true, the offsets field describes segments.
std::vector< uint64_t > offsets
The individual offsets.