36#include "lldb/Host/Config.h"
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/StringSwitch.h"
41#include "llvm/Config/llvm-config.h"
42#include "llvm/Support/JSON.h"
44#if HAVE_LIBCOMPRESSION
45#include <compression.h>
51using namespace std::chrono;
55 return os << llvm::formatv(
56 "QOffsets({0}, [{1:@[x]}])", offsets.
segments,
91 std::chrono::steady_clock::time_point start_of_handshake =
92 std::chrono::steady_clock::now();
101 std::chrono::steady_clock::time_point end_of_handshake =
102 std::chrono::steady_clock::now();
103 auto handshake_timeout =
104 std::chrono::duration<double>(end_of_handshake - start_of_handshake)
110 "while waiting for reply to initial "
114 "failed to get reply to handshake packet within timeout of "
389 std::vector<std::string> features = {
"xmlRegisters=i386,arm,mips,arc",
397 for (uint32_t i = 0; i < features.size(); ++i) {
409 for (llvm::StringRef x : llvm::split(response.
GetStringRef(),
';')) {
410 if (x ==
"qXfer:auxv:read+")
412 else if (x ==
"qXfer:libraries-svr4:read+")
414 else if (x ==
"augmented-libraries-svr4-read") {
417 }
else if (x ==
"qXfer:libraries:read+")
419 else if (x ==
"qXfer:features:read+")
421 else if (x ==
"qXfer:memory-map:read+")
423 else if (x ==
"qXfer:siginfo:read+")
425 else if (x ==
"qEcho+")
427 else if (x ==
"QPassSignals+")
429 else if (x ==
"multiprocess+")
431 else if (x ==
"memory-tagging+")
433 else if (x ==
"qSaveCore+")
435 else if (x ==
"native-signals+")
437 else if (x ==
"binary-upload+")
439 else if (x ==
"ReverseContinue+")
441 else if (x ==
"ReverseStep+")
443 else if (x ==
"MultiMemRead+")
445 else if (x ==
"jMultiBreakpoint+")
450 else if (x.consume_front(
"SupportedCompressions=")) {
451 llvm::SmallVector<llvm::StringRef, 4> compressions;
452 x.split(compressions,
',');
453 if (!compressions.empty())
455 }
else if (x.consume_front(
"SupportedWatchpointTypes=")) {
456 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
457 x.split(watchpoint_types,
',');
459 for (
auto wp_type : watchpoint_types) {
460 if (wp_type ==
"x86_64")
462 if (wp_type ==
"aarch64-mask")
464 if (wp_type ==
"aarch64-bas")
467 }
else if (x.consume_front(
"PacketSize=")) {
474 LLDB_LOGF(log,
"Garbled PacketSize spec in qSupported response");
495 assert(!flavor.empty());
506 for (llvm::StringRef token : llvm::split(response.
GetStringRef(),
';')) {
533 return llvm::StringSwitch<bool>(flavor)
551 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
553 __FUNCTION__, payload.GetData());
558 payload.Printf(
";thread:%4.4" PRIx64
";", tid);
605 }
else if (!response.
Empty()) {
694 packet.
Printf(
"qMemTags:%" PRIx64
",%zx:%" PRIx32, addr, len, type);
702 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s: qMemTags packet failed",
710 if (response.
GetChar() !=
'm') {
712 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
723 if (response.
GetBytesLeft() || (expected_bytes != got_bytes)) {
726 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
736 const std::vector<uint8_t> &tags) {
739 packet.
Printf(
"QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr, len, type);
785 if (response.
GetChar() ==
'Q') {
786 if (response.
GetChar() ==
'C') {
800 bool sequence_mutex_unavailable;
802 if (!ids.empty() && !sequence_mutex_unavailable) {
819 return llvm::createStringError(llvm::inconvertibleErrorCode(),
820 "Nothing to launch");
833 return llvm::createStringError(llvm::inconvertibleErrorCode(),
834 "Sending vRun packet failed");
843 return llvm::Error::success();
851 llvm::ListSeparator LS(
",");
852 for (
const auto &arg : llvm::enumerate(args)) {
854 packet.
Format(
"{0},{1},", arg.value().ref().size() * 2, arg.index());
861 return llvm::createStringError(llvm::inconvertibleErrorCode(),
862 "Sending A packet failed");
869 return llvm::createStringError(llvm::inconvertibleErrorCode(),
870 "Sending qLaunchSuccess packet failed");
873 return llvm::Error::success();
874 if (response.
GetChar() ==
'E') {
875 return llvm::createStringError(llvm::inconvertibleErrorCode(),
878 return llvm::createStringError(llvm::inconvertibleErrorCode(),
879 "unknown error occurred launching process");
883 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
884 for (
const auto &kv : env)
885 vec.emplace_back(kv.first(), kv.second);
886 llvm::sort(vec, llvm::less_first());
887 for (
const auto &[k, v] : vec) {
896 char const *name_equal_value) {
897 if (name_equal_value && name_equal_value[0]) {
898 bool send_hex_encoding =
false;
899 for (
const char *p = name_equal_value; *p !=
'\0' && !send_hex_encoding;
901 if (llvm::isPrint(*p)) {
907 send_hex_encoding =
true;
914 send_hex_encoding =
true;
922 packet.
Printf(
"QEnvironment:%s", name_equal_value);
963 if (arch && arch[0]) {
965 packet.
Printf(
"QLaunchArch:%s", arch);
980 char const *data,
bool *was_supported) {
981 if (data && *data !=
'\0') {
983 packet.
Printf(
"QSetProcessEvent:%s", data);
989 *was_supported =
true;
993 *was_supported =
false;
998 *was_supported =
true;
1022 return std::nullopt;
1025std::optional<std::string>
1031 return std::nullopt;
1059 UUID &uuid,
addr_t &value,
bool &value_is_offset) {
1092 llvm::StringRef name, value;
1093 bool success =
false;
1095 if (name ==
"name") {
1098 }
else if (name ==
"version") {
1099 llvm::StringRef major, minor;
1100 std::tie(major, minor) = value.split(
'.');
1114 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1116 llvm::StringRef avail_name;
1118#if HAVE_LIBCOMPRESSION
1120 for (
auto compression : supported_compressions) {
1121 if (compression ==
"lzfse") {
1123 avail_name = compression;
1129 for (
auto compression : supported_compressions) {
1130 if (compression ==
"zlib-deflate") {
1132 avail_name = compression;
1141 for (
auto compression : supported_compressions) {
1142 if (compression ==
"zlib-deflate") {
1144 avail_name = compression;
1151#if HAVE_LIBCOMPRESSION
1153 for (
auto compression : supported_compressions) {
1154 if (compression ==
"lz4") {
1156 avail_name = compression;
1162 for (
auto compression : supported_compressions) {
1163 if (compression ==
"lzma") {
1165 avail_name = compression;
1174 std::string packet =
"QEnableCompression:type:" + avail_name.str() +
";";
1221 tid = pid_tid->second;
1228 std::string &environment) {
1229 if (value ==
"iossimulator" || value ==
"tvossimulator" ||
1230 value ==
"watchossimulator" || value ==
"xrossimulator" ||
1231 value ==
"visionossimulator") {
1232 environment =
"simulator";
1233 os_name = value.drop_back(environment.size()).str();
1234 }
else if (value ==
"maccatalyst") {
1236 environment =
"macabi";
1238 os_name = value.str();
1254 llvm::StringRef name;
1255 llvm::StringRef value;
1258 std::string arch_name;
1259 std::string os_name;
1260 std::string environment;
1261 std::string vendor_name;
1263 uint32_t pointer_byte_size = 0;
1265 uint32_t num_keys_decoded = 0;
1267 if (name ==
"cputype") {
1269 if (!value.getAsInteger(0, cpu))
1271 }
else if (name ==
"cpusubtype") {
1273 if (!value.getAsInteger(0, sub))
1275 }
else if (name ==
"arch") {
1276 arch_name = std::string(value);
1278 }
else if (name ==
"triple") {
1282 }
else if (name ==
"distribution_id") {
1286 }
else if (name ==
"os_build") {
1290 }
else if (name ==
"hostname") {
1294 }
else if (name ==
"os_kernel") {
1298 }
else if (name ==
"ostype") {
1301 }
else if (name ==
"vendor") {
1302 vendor_name = std::string(value);
1304 }
else if (name ==
"endian") {
1305 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1312 }
else if (name ==
"ptrsize") {
1313 if (!value.getAsInteger(0, pointer_byte_size))
1315 }
else if (name ==
"addressing_bits") {
1319 }
else if (name ==
"high_mem_addressing_bits") {
1322 }
else if (name ==
"low_mem_addressing_bits") {
1325 }
else if (name ==
"os_version" ||
1332 }
else if (name ==
"maccatalyst_version") {
1335 }
else if (name ==
"watchpoint_exceptions_received") {
1337 llvm::StringSwitch<LazyBool>(value)
1343 }
else if (name ==
"default_packet_timeout") {
1344 uint32_t timeout_seconds;
1345 if (!value.getAsInteger(0, timeout_seconds)) {
1350 }
else if (name ==
"vm-page-size") {
1352 if (!value.getAsInteger(0, page_size)) {
1359 if (num_keys_decoded > 0)
1362 if (triple.empty()) {
1363 if (arch_name.empty()) {
1366 if (pointer_byte_size) {
1367 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1373 if (!vendor_name.empty())
1375 llvm::StringRef(vendor_name));
1376 if (!os_name.empty())
1377 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1378 if (!environment.empty())
1379 m_host_arch.GetTriple().setEnvironmentName(environment);
1383 triple += arch_name;
1384 if (!vendor_name.empty() || !os_name.empty()) {
1386 if (vendor_name.empty())
1387 triple +=
"unknown";
1389 triple += vendor_name;
1391 if (os_name.empty())
1392 triple +=
"unknown";
1398 llvm::Triple &host_triple =
m_host_arch.GetTriple();
1399 if (host_triple.getVendor() == llvm::Triple::Apple &&
1400 host_triple.getOS() == llvm::Triple::Darwin) {
1402 case llvm::Triple::aarch64:
1403 case llvm::Triple::aarch64_32:
1404 case llvm::Triple::arm:
1405 case llvm::Triple::thumb:
1406 host_triple.setOS(llvm::Triple::IOS);
1409 host_triple.setOS(llvm::Triple::MacOSX);
1413 if (pointer_byte_size) {
1414 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1422 if (pointer_byte_size) {
1423 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1430 "GDBRemoteCommunicationClient::%s parsed host "
1431 "architecture as %s, triple as %s from triple text %s",
1435 :
"<null-arch-name>",
1475 return addressable_bits;
1485 uint32_t permissions) {
1489 const int packet_len = ::snprintf(
1490 packet,
sizeof(packet),
"_M%" PRIx64
",%s%s%s", (uint64_t)size,
1491 permissions & lldb::ePermissionsReadable ?
"r" :
"",
1492 permissions & lldb::ePermissionsWritable ?
"w" :
"",
1493 permissions & lldb::ePermissionsExecutable ?
"x" :
"");
1494 assert(packet_len < (
int)
sizeof(packet));
1514 const int packet_len =
1515 ::snprintf(packet,
sizeof(packet),
"_m%" PRIx64, (uint64_t)addr);
1516 assert(packet_len < (
int)
sizeof(packet));
1541 const int packet_len =
1542 ::snprintf(packet,
sizeof(packet),
"qSupportsDetachAndStayStopped:");
1543 assert(packet_len < (
int)
sizeof(packet));
1557 "Stays stopped not supported by this target.");
1573 "Multiprocess extension not supported by the server.");
1588 region_info.
Clear();
1593 const int packet_len = ::snprintf(
1594 packet,
sizeof(packet),
"qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1595 assert(packet_len < (
int)
sizeof(packet));
1601 llvm::StringRef name;
1602 llvm::StringRef value;
1604 bool success =
true;
1605 bool saw_permissions =
false;
1607 if (name ==
"start") {
1608 if (!value.getAsInteger(16, addr_value))
1610 }
else if (name ==
"size") {
1611 if (!value.getAsInteger(16, addr_value)) {
1619 }
else if (name ==
"permissions" && region_info.
GetRange().
IsValid()) {
1620 saw_permissions =
true;
1622 if (value.contains(
'r'))
1627 if (value.contains(
'w'))
1632 if (value.contains(
'x'))
1646 }
else if (name ==
"name") {
1650 region_info.
SetName(name.c_str());
1651 }
else if (name ==
"flags") {
1655 llvm::StringRef flags = value;
1656 llvm::StringRef flag;
1657 while (flags.size()) {
1658 flags = flags.ltrim();
1659 std::tie(flag, flags) = flags.split(
' ');
1664 else if (flag ==
"ss")
1668 }
else if (name ==
"type") {
1669 for (llvm::StringRef entry : llvm::split(value,
',')) {
1670 if (entry ==
"stack")
1672 else if (entry ==
"heap")
1675 }
else if (name ==
"error") {
1677 std::string error_string;
1681 }
else if (name ==
"dirty-pages") {
1682 std::vector<addr_t> dirty_page_list;
1683 for (llvm::StringRef x : llvm::split(value,
',')) {
1685 x.consume_front(
"0x");
1686 if (llvm::to_integer(x, page, 16))
1687 dirty_page_list.push_back(page);
1690 }
else if (name ==
"protection-key") {
1691 unsigned protection_key = 0;
1692 if (!value.getAsInteger(10, protection_key))
1703 if (!saw_permissions) {
1731 region_info = qXfer_region_info;
1734 region_info.
Clear();
1736 }
else if (qXfer_error.
Success()) {
1751 if (!
error.Success())
1754 if (map_region.GetRange().Contains(addr)) {
1755 region = map_region;
1781 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1787 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1803 if (memory_node.
GetName() !=
"memory")
1815 if (type ==
"rom") {
1818 }
else if (type ==
"ram") {
1822 }
else if (type ==
"flash") {
1825 [®ion](
const XMLNode &prop_node) ->
bool {
1828 if (prop_node.
GetName() !=
"property")
1831 if (propname ==
"blocksize") {
1853 std::optional<uint32_t> num;
1859 llvm::StringRef name;
1860 llvm::StringRef value;
1862 if (name ==
"num") {
1878WatchpointHardwareFeature
1897 return std::nullopt;
1902 std::string path{file_spec.
GetPath(
false)};
1922 std::string path{file_spec.
GetPath(
false)};
1942 std::string path{file_spec.
GetPath(
false)};
1971 return !cwd.empty();
1978 std::string path{working_dir.
GetPath(
false)};
1998 const int packet_len =
1999 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
2000 assert(packet_len < (
int)
sizeof(packet));
2015 const int packet_len = ::snprintf(packet,
sizeof(packet),
2016 "QSetDetachOnError:%i", enable ? 1 : 0);
2017 assert(packet_len < (
int)
sizeof(packet));
2033 llvm::StringRef name;
2034 llvm::StringRef value;
2040 std::string os_type;
2043 if (name ==
"pid") {
2045 value.getAsInteger(0, pid);
2047 }
else if (name ==
"ppid") {
2049 value.getAsInteger(0, pid);
2051 }
else if (name ==
"uid") {
2053 value.getAsInteger(0, uid);
2055 }
else if (name ==
"euid") {
2057 value.getAsInteger(0, uid);
2059 }
else if (name ==
"gid") {
2061 value.getAsInteger(0, gid);
2063 }
else if (name ==
"egid") {
2065 value.getAsInteger(0, gid);
2067 }
else if (name ==
"triple") {
2072 }
else if (name ==
"name") {
2079 }
else if (name ==
"args") {
2080 llvm::StringRef encoded_args(value), hex_arg;
2082 bool is_arg0 =
true;
2083 while (!encoded_args.empty()) {
2084 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2099 }
else if (name ==
"cputype") {
2100 value.getAsInteger(0, cpu);
2101 }
else if (name ==
"cpusubtype") {
2102 value.getAsInteger(0, sub);
2103 }
else if (name ==
"vendor") {
2104 vendor = std::string(value);
2105 }
else if (name ==
"ostype") {
2106 os_type = std::string(value);
2111 if (vendor ==
"apple") {
2115 llvm::StringRef(vendor));
2117 llvm::StringRef(os_type));
2129 process_info.
Clear();
2133 const int packet_len =
2134 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2135 assert(packet_len < (
int)
sizeof(packet));
2165 llvm::StringRef name;
2166 llvm::StringRef value;
2169 std::string os_name;
2170 std::string environment;
2171 std::string vendor_name;
2173 std::string elf_abi;
2174 uint32_t pointer_byte_size = 0;
2177 uint32_t num_keys_decoded = 0;
2180 if (name ==
"cputype") {
2181 if (!value.getAsInteger(16, cpu))
2183 }
else if (name ==
"cpusubtype") {
2184 if (!value.getAsInteger(16, sub)) {
2190 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2191 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2198 }
else if (name ==
"triple") {
2202 }
else if (name ==
"ostype") {
2205 }
else if (name ==
"vendor") {
2206 vendor_name = std::string(value);
2208 }
else if (name ==
"endian") {
2209 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2216 }
else if (name ==
"ptrsize") {
2217 if (!value.getAsInteger(16, pointer_byte_size))
2219 }
else if (name ==
"pid") {
2220 if (!value.getAsInteger(16, pid))
2222 }
else if (name ==
"elf_abi") {
2223 elf_abi = std::string(value);
2225 }
else if (name ==
"main-binary-uuid") {
2228 }
else if (name ==
"main-binary-slide") {
2236 }
else if (name ==
"main-binary-address") {
2244 }
else if (name ==
"binary-addresses") {
2247 for (llvm::StringRef x : llvm::split(value,
',')) {
2249 x.consume_front(
"0x");
2250 if (llvm::to_integer(x, vmaddr, 16))
2255 if (num_keys_decoded > 0)
2263 if (!triple.empty()) {
2266 if (pointer_byte_size) {
2267 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2270 !vendor_name.empty()) {
2271 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2272 if (!environment.empty())
2273 triple.setEnvironmentName(environment);
2275 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2276 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2277 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2278 switch (triple.getObjectFormat()) {
2279 case llvm::Triple::MachO:
2282 case llvm::Triple::ELF:
2285 case llvm::Triple::COFF:
2288 case llvm::Triple::GOFF:
2289 case llvm::Triple::SPIRV:
2290 case llvm::Triple::Wasm:
2291 case llvm::Triple::XCOFF:
2292 case llvm::Triple::DXContainer:
2293 LLDB_LOGF(log,
"error: not supported target architecture");
2295 case llvm::Triple::UnknownObjectFormat:
2296 LLDB_LOGF(log,
"error: failed to determine target architecture");
2300 if (pointer_byte_size) {
2301 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2306 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2308 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2322 process_infos.clear();
2330 bool has_name_match =
false;
2331 if (name && name[0]) {
2332 has_name_match =
true;
2334 switch (name_match_type) {
2336 has_name_match =
false;
2348 packet.
PutCString(
"name_match:starts_with;");
2359 if (has_name_match) {
2367 packet.
Printf(
"pid:%" PRIu64
";",
2370 packet.
Printf(
"parent_pid:%" PRIu64
";",
2377 packet.
Printf(
"euid:%u;",
2380 packet.
Printf(
"egid:%u;",
2386 const llvm::Triple &triple = match_arch.
GetTriple();
2402 process_infos.push_back(process_info);
2411 return process_infos.size();
2415 std::string &name) {
2418 const int packet_len =
2419 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2420 assert(packet_len < (
int)
sizeof(packet));
2442 std::string &name) {
2445 const int packet_len =
2446 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2447 assert(packet_len < (
int)
sizeof(packet));
2469 uint32_t recv_size) {
2471 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2472 uint32_t bytes_left = send_size;
2473 while (bytes_left > 0) {
2474 if (bytes_left >= 26) {
2475 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2478 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2479 "abcdefghijklmnopqrstuvwxyz");
2488 return duration<float>::zero();
2489 using Dur = duration<float>;
2490 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2491 Dur mean = sum / v.size();
2494 float delta = (d - mean).count();
2495 accum += delta * delta;
2498 return Dur(sqrtf(accum / (v.size() - 1)));
2504 uint64_t recv_amount,
2505 bool json,
Stream &strm) {
2510 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2514 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2518 uint32_t result_idx = 0;
2520 std::vector<duration<float>> packet_times;
2522 for (send_size = 0; send_size <= max_send;
2523 send_size ? send_size *= 2 : send_size = 4) {
2524 for (uint32_t recv_size = 0; recv_size <= max_recv;
2525 recv_size ? recv_size *= 2 : recv_size = 4) {
2528 packet_times.clear();
2530 const auto start_time = steady_clock::now();
2531 for (uint32_t i = 0; i < num_packets; ++i) {
2532 const auto packet_start_time = steady_clock::now();
2535 const auto packet_end_time = steady_clock::now();
2536 packet_times.push_back(packet_end_time - packet_start_time);
2538 const auto end_time = steady_clock::now();
2539 const auto total_time = end_time - start_time;
2541 float packets_per_second =
2542 ((float)num_packets) / duration<float>(total_time).count();
2543 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2544 : duration<float>::zero();
2545 const duration<float> standard_deviation =
2548 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2549 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2550 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2551 result_idx > 0 ?
"," :
"", send_size, recv_size,
2552 total_time, standard_deviation);
2555 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2556 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2557 "standard deviation of {5,10:ms+f6}\n",
2558 send_size, recv_size, duration<float>(total_time),
2559 packets_per_second, duration<float>(average_per_packet),
2560 standard_deviation);
2566 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2568 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2569 ": %" PRIu64
",\n \"results\" : [",
2572 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2578 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2583 if (recv_size > 0) {
2584 const auto start_time = steady_clock::now();
2585 uint32_t bytes_read = 0;
2586 uint32_t packet_count = 0;
2587 while (bytes_read < recv_amount) {
2590 bytes_read += recv_size;
2593 const auto end_time = steady_clock::now();
2594 const auto total_time = end_time - start_time;
2595 float mb_second = ((float)recv_amount) /
2596 duration<float>(total_time).count() /
2598 float packets_per_second =
2599 ((float)packet_count) / duration<float>(total_time).count();
2600 const auto average_per_packet = packet_count > 0
2601 ? total_time / packet_count
2602 : duration<float>::zero();
2605 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2606 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2607 result_idx > 0 ?
"," :
"", send_size, recv_size,
2611 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2612 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2613 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2614 send_size, recv_size, packet_count, k_recv_amount_mb,
2615 duration<float>(total_time), mb_second,
2616 packets_per_second, duration<float>(average_per_packet));
2622 strm.
Printf(
"\n ]\n }\n}\n");
2629 uint32_t recv_size) {
2631 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2632 uint32_t bytes_left = send_size;
2633 while (bytes_left > 0) {
2634 if (bytes_left >= 26) {
2635 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2638 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2639 "abcdefghijklmnopqrstuvwxyz");
2650 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2651 std::string &socket_name) {
2654 socket_name.clear();
2659 std::string hostname;
2660 if (remote_accept_hostname && remote_accept_hostname[0])
2661 hostname = remote_accept_hostname;
2663 if (HostInfo::GetHostname(hostname)) {
2665 stream.
Printf(
"host:%s;", hostname.c_str());
2669 stream.
Printf(
"host:*;");
2680 llvm::StringRef name;
2681 llvm::StringRef value;
2684 value.getAsInteger(0, port);
2685 else if (name ==
"pid")
2686 value.getAsInteger(0, pid);
2687 else if (name.compare(
"socket_name") == 0) {
2698 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2699 connection_urls.clear();
2715 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2716 std::optional<StructuredData::Dictionary *> maybe_element =
2725 port = port_osp->GetUnsignedIntegerValue(0);
2727 std::string socket_name;
2730 socket_name = std::string(socket_name_osp->GetStringValue());
2732 if (port != 0 || !socket_name.empty())
2733 connection_urls.emplace_back(port, socket_name);
2735 return connection_urls.size();
2740 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2752 uint64_t tid, uint64_t pid,
char op) {
2758 packet.
Printf(
"p%" PRIx64
".", pid);
2763 packet.
Printf(
"%" PRIx64, tid);
2769 return {{pid, tid}};
2781 return std::nullopt;
2796 return ret.has_value();
2811 return ret.has_value();
2826 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2827 assert(packet_len < (
int)
sizeof(packet));
2846 std::chrono::seconds timeout) {
2848 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2849 __FUNCTION__, insert ?
"add" :
"remove", addr);
2856 const int packet_len =
2857 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2858 insert ?
'Z' :
'z', type, addr, length);
2860 assert(packet_len + 1 < (
int)
sizeof(packet));
2905std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2907 bool &sequence_mutex_unavailable) {
2908 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2912 sequence_mutex_unavailable =
false;
2916 for (packet_result =
2934 ids.push_back(*pid_tid);
2936 }
while (ch ==
',');
2950 ids.emplace_back(1, 1);
2954 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
2955 "packet 'qfThreadInfo'");
2956 sequence_mutex_unavailable =
true;
2963 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
2968 if (ids.empty() || sequence_mutex_unavailable)
2971 for (
auto id : ids) {
2977 thread_ids.push_back(
id.second);
2980 return thread_ids.size();
2993 llvm::StringRef command,
3001 std::string *separated_error_output,
3011 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3015 std::string path{working_dir.
GetPath(
false)};
3022 if (response.
GetChar() !=
'F')
3024 if (response.
GetChar() !=
',')
3029 else if (status_ptr)
3030 *status_ptr = exitcode;
3031 if (response.
GetChar() !=
',')
3036 if (response.
GetChar() !=
',')
3041 command_output->assign(output);
3048 uint32_t file_permissions) {
3049 std::string path{file_spec.
GetPath(
false)};
3055 llvm::StringRef packet = stream.
GetString();
3060 packet.str().c_str());
3062 if (response.
GetChar() !=
'F')
3064 packet.str().c_str());
3071 uint32_t file_permissions) {
3072 std::string path{file_spec.
GetPath(
false)};
3078 llvm::StringRef packet = stream.
GetString();
3085 if (response.
GetChar() !=
'F')
3094#define HANDLE_ERRNO(name, value) \
3097#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3106 if (response.
GetChar() !=
'F')
3108 int32_t result = response.
GetS32(-2, 16);
3111 if (response.
GetChar() ==
',') {
3113 if (result_errno != -1)
3125 std::string path(file_spec.
GetPath(
false));
3146 stream.
Printf(
"vFile:close:%x", (
int)fd);
3155std::optional<GDBRemoteFStatData>
3158 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3162 if (response.
GetChar() !=
'F')
3163 return std::nullopt;
3164 int64_t size = response.
GetS64(-1, 16);
3165 if (size > 0 && response.
GetChar() ==
';') {
3169 if (buffer.size() !=
sizeof(out))
3170 return std::nullopt;
3171 memcpy(&out, buffer.data(),
sizeof(out));
3176 return std::nullopt;
3179std::optional<GDBRemoteFStatData>
3184 return std::nullopt;
3185 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3194 std::string path(file_spec.
GetPath(
false));
3204 if (response.
GetChar() !=
'F')
3213 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3231 while (response.
Peek()) {
3233 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3236 if (response.
GetChar() !=
',')
3244 uint32_t &file_permissions) {
3246 std::string path{file_spec.
GetPath(
false)};
3259 if (response.
GetChar() !=
'F') {
3261 "invalid response to '%s' packet", stream.
GetData());
3263 const uint32_t mode = response.
GetS32(-1, 16);
3264 if (
static_cast<int32_t
>(mode) == -1) {
3265 if (response.
GetChar() ==
',') {
3267 if (response_errno > 0)
3284 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3292 uint64_t offset,
void *dst,
3296 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3301 if (response.
GetChar() !=
'F')
3303 int64_t retcode = response.
GetS64(-1, 16);
3304 if (retcode == -1) {
3306 if (response.
GetChar() ==
',') {
3308 if (response_errno > 0)
3313 const char next = (response.
Peek() ? *response.
Peek() : 0);
3320 const uint64_t data_to_write =
3321 std::min<uint64_t>(dst_len, buffer.size());
3322 if (data_to_write > 0)
3323 memcpy(dst, &buffer[0], data_to_write);
3324 return data_to_write;
3337 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3342 if (response.
GetChar() !=
'F') {
3346 int64_t bytes_written = response.
GetS64(-1, 16);
3347 if (bytes_written == -1) {
3349 if (response.
GetChar() ==
',') {
3351 if (response_errno > 0)
3356 return bytes_written;
3365 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3377 if (response.
GetChar() ==
'F') {
3381 if (response.
GetChar() ==
',') {
3383 if (response_errno > 0)
3398 std::string path{file_spec.
GetPath(
false)};
3408 if (response.
GetChar() ==
'F') {
3412 if (response.
GetChar() ==
',') {
3414 if (response_errno > 0)
3432 std::string path(file_spec.
GetPath(
false));
3441 if (response.
GetChar() !=
'F')
3443 if (response.
GetChar() !=
',')
3445 bool retcode = (response.
GetChar() !=
'0');
3462 std::string path(file_spec.
GetPath(
false));
3469 if (response.
GetChar() !=
'F')
3470 return std::make_error_code(std::errc::illegal_byte_sequence);
3471 if (response.
GetChar() !=
',')
3472 return std::make_error_code(std::errc::illegal_byte_sequence);
3473 if (response.
Peek() && *response.
Peek() ==
'x')
3474 return std::make_error_code(std::errc::no_such_file_or_directory);
3491 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3496 if (part.size() != MD5_HALF_LENGTH)
3497 return std::make_error_code(std::errc::illegal_byte_sequence);
3501 if (part.getAsInteger(16, low))
3502 return std::make_error_code(std::errc::illegal_byte_sequence);
3507 if (part.size() != MD5_HALF_LENGTH)
3508 return std::make_error_code(std::errc::illegal_byte_sequence);
3512 if (part.getAsInteger(16, high))
3513 return std::make_error_code(std::errc::illegal_byte_sequence);
3515 llvm::MD5::MD5Result result;
3516 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3517 result.data(), low);
3518 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3519 result.data() + 8, high);
3523 return std::make_error_code(std::errc::operation_canceled);
3533 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3534 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3535 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3536 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3539 if (gdb_server_version != 0) {
3541 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3542 if (gdb_server_version >= 310)
3555 payload.
Printf(
"p%x", reg);
3564 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3579 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3585 llvm::ArrayRef<uint8_t> data) {
3587 payload.
Printf(
"P%x=", reg_num);
3611 uint32_t &save_id) {
3627 const uint32_t response_save_id = response.
GetU32(0);
3628 if (response_save_id == 0)
3631 save_id = response_save_id;
3644 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3664 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3670llvm::Expected<TraceSupportedResponse>
3675 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3684 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3685 "jLLDBTraceSupported is unsupported");
3687 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3688 "TraceSupportedResponse");
3690 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3691 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3692 "failed to send packet: jLLDBTraceSupported");
3697 std::chrono::seconds timeout) {
3701 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3703 std::string json_string;
3704 llvm::raw_string_ostream os(json_string);
3707 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3716 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3717 "jLLDBTraceStop is unsupported");
3719 return llvm::Error::success();
3720 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3721 "Invalid jLLDBTraceStart response");
3723 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3724 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3725 "failed to send packet: jLLDBTraceStop '%s'",
3731 std::chrono::seconds timeout) {
3735 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3737 std::string json_string;
3738 llvm::raw_string_ostream os(json_string);
3741 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3750 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3751 "jLLDBTraceStart is unsupported");
3753 return llvm::Error::success();
3754 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3755 "Invalid jLLDBTraceStart response");
3757 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3758 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3759 "failed to send packet: jLLDBTraceStart '%s'",
3763llvm::Expected<std::string>
3765 std::chrono::seconds timeout) {
3769 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3771 std::string json_string;
3772 llvm::raw_string_ostream os(json_string);
3775 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3784 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3785 "jLLDBTraceGetState is unsupported");
3786 return std::string(response.
Peek());
3789 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3790 return llvm::createStringError(
3791 llvm::inconvertibleErrorCode(),
3792 "failed to send packet: jLLDBTraceGetState '%s'",
3796llvm::Expected<std::vector<uint8_t>>
3802 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3804 std::string json_string;
3805 llvm::raw_string_ostream os(json_string);
3808 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3818 return std::vector<uint8_t>(data.begin(), data.end());
3820 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3821 return llvm::createStringError(
3822 llvm::inconvertibleErrorCode(),
3823 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3831 return std::nullopt;
3833 return std::nullopt;
3837 const auto &GetOffset = [&] {
3839 if (ref.consumeInteger(16, offset))
3841 result.
offsets.push_back(offset);
3845 if (ref.consume_front(
"Text=")) {
3848 return std::nullopt;
3849 if (!ref.consume_front(
";Data=") || !GetOffset())
3850 return std::nullopt;
3853 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3855 }
else if (ref.consume_front(
"TextSeg=")) {
3858 return std::nullopt;
3861 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3864 return std::nullopt;
3873 std::string module_path = module_file_spec.
GetPath(
false);
3874 if (module_path.empty())
3881 const auto &triple = arch_spec.
GetTriple().getTriple();
3897 llvm::StringRef name;
3898 llvm::StringRef value;
3900 module_spec.
Clear();
3904 if (name ==
"uuid" || name ==
"md5") {
3909 }
else if (name ==
"triple") {
3914 }
else if (name ==
"file_offset") {
3916 if (!value.getAsInteger(16, ival))
3918 }
else if (name ==
"file_size") {
3920 if (!value.getAsInteger(16, ival))
3922 }
else if (name ==
"file_path") {
3933static std::optional<ModuleSpec>
3937 return std::nullopt;
3939 llvm::StringRef string;
3943 return std::nullopt;
3945 return std::nullopt;
3948 return std::nullopt;
3952 return std::nullopt;
3956 return std::nullopt;
3960 return std::nullopt;
3966std::optional<std::vector<ModuleSpec>>
3968 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
3972 return std::nullopt;
3974 json::Array module_array;
3975 for (
const FileSpec &module_file_spec : module_file_specs) {
3976 module_array.push_back(
3977 json::Object{{
"file", module_file_spec.GetPath(
false)},
3978 {
"triple", triple.getTriple()}});
3981 unescaped_payload.
PutCString(
"jModulesInfo:");
3982 unescaped_payload.
AsRawOstream() << std::move(module_array);
3995 return std::nullopt;
3999 return std::nullopt;
4004 if (!response_object_sp)
4005 return std::nullopt;
4008 if (!response_array)
4009 return std::nullopt;
4011 std::vector<ModuleSpec> result;
4012 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
4015 result.push_back(*module_spec);
4025llvm::Expected<std::string>
4027 llvm::StringRef annex) {
4030 llvm::raw_string_ostream output_stream(output);
4044 std::string packet =
4045 (
"qXfer:" +
object +
":read:" + annex +
":" +
4046 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4054 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4055 "Error sending $qXfer packet");
4073 return llvm::createStringError(
4074 llvm::inconvertibleErrorCode(),
4075 "Invalid continuation code from $qXfer packet");
4125 bool symbol_response_provided =
false;
4128 bool first_qsymbol_query =
true;
4139 if (symbol_response_provided || first_qsymbol_query) {
4146 first_qsymbol_query =
false;
4155 if (response_str.starts_with(
"qSymbol:")) {
4157 std::string symbol_name;
4159 if (symbol_name.empty())
4170 switch (sc.symbol->GetType()) {
4203 sc.symbol->GetLoadAddress(&process->
GetTarget());
4216 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4217 symbol_response_provided =
true;
4219 symbol_response_provided =
false;
4235 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4260 "GDBRemoteCommunicationClient::%s(): "
4261 "QSupportedAsyncJSONPackets returned invalid "
4268 "GDBRemoteCommunicationClient::%s(): "
4269 "QSupportedAsyncJSONPackets unsupported",
4277 "GDBRemoteCommunicationClient::%s(): supported async "
4279 __FUNCTION__, stream.
GetData());
4289 llvm::ArrayRef<int32_t> signals) {
4292 auto range = llvm::make_range(signals.begin(), signals.end());
4293 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4305 "Unknown error happened during sending QPassSignals packet.");
4313 if (type_name.empty()) {
4326 config_sp->Dump(unescaped_stream);
4327 unescaped_stream.
Flush();
4345 "configuring StructuredData feature {0} failed with error {1}",
4351 "configuring StructuredData feature {0} failed when sending packet: "
4353 type_name, (
int)result);
4382 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4383 "failed to send k packet");
4385 char packet_cmd = response.
GetChar(0);
4386 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4389 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4390 "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)
const char * GetName() const
lldb::pid_t GetProcessID() const
void SetProcessID(lldb::pid_t pid)
FileSpec & GetExecutableFile()
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 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 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 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)
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
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()
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()
int SendStdinNotification(const char *data, size_t data_len)
Sends a GDB remote protocol 'I' packet that delivers stdin data to the remote process.
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
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.
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
llvm::json::Value toJSON(const TraceSupportedResponse &packet)
@ 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
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.