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) {
2639 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2640 std::string &socket_name) {
2643 socket_name.clear();
2648 std::string hostname;
2649 if (remote_accept_hostname && remote_accept_hostname[0])
2650 hostname = remote_accept_hostname;
2652 if (HostInfo::GetHostname(hostname)) {
2654 stream.
Printf(
"host:%s;", hostname.c_str());
2658 stream.
Printf(
"host:*;");
2669 llvm::StringRef name;
2670 llvm::StringRef value;
2673 value.getAsInteger(0, port);
2674 else if (name ==
"pid")
2675 value.getAsInteger(0, pid);
2676 else if (name.compare(
"socket_name") == 0) {
2687 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2688 connection_urls.clear();
2704 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2705 std::optional<StructuredData::Dictionary *> maybe_element =
2714 port = port_osp->GetUnsignedIntegerValue(0);
2716 std::string socket_name;
2719 socket_name = std::string(socket_name_osp->GetStringValue());
2721 if (port != 0 || !socket_name.empty())
2722 connection_urls.emplace_back(port, socket_name);
2724 return connection_urls.size();
2729 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2741 uint64_t tid, uint64_t pid,
char op) {
2747 packet.
Printf(
"p%" PRIx64
".", pid);
2752 packet.
Printf(
"%" PRIx64, tid);
2758 return {{pid, tid}};
2770 return std::nullopt;
2785 return ret.has_value();
2800 return ret.has_value();
2815 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2816 assert(packet_len < (
int)
sizeof(packet));
2835 std::chrono::seconds timeout) {
2837 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2838 __FUNCTION__, insert ?
"add" :
"remove", addr);
2845 const int packet_len =
2846 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2847 insert ?
'Z' :
'z', type, addr, length);
2849 assert(packet_len + 1 < (
int)
sizeof(packet));
2894std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2896 bool &sequence_mutex_unavailable) {
2897 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2901 sequence_mutex_unavailable =
false;
2905 for (packet_result =
2923 ids.push_back(*pid_tid);
2925 }
while (ch ==
',');
2939 ids.emplace_back(1, 1);
2943 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
2944 "packet 'qfThreadInfo'");
2945 sequence_mutex_unavailable =
true;
2952 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
2957 if (ids.empty() || sequence_mutex_unavailable)
2960 for (
auto id : ids) {
2966 thread_ids.push_back(
id.second);
2969 return thread_ids.size();
2982 llvm::StringRef command,
2990 std::string *separated_error_output,
3000 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3004 std::string path{working_dir.
GetPath(
false)};
3011 if (response.
GetChar() !=
'F')
3013 if (response.
GetChar() !=
',')
3018 else if (status_ptr)
3019 *status_ptr = exitcode;
3020 if (response.
GetChar() !=
',')
3025 if (response.
GetChar() !=
',')
3030 command_output->assign(output);
3037 uint32_t file_permissions) {
3038 std::string path{file_spec.
GetPath(
false)};
3044 llvm::StringRef packet = stream.
GetString();
3049 packet.str().c_str());
3051 if (response.
GetChar() !=
'F')
3053 packet.str().c_str());
3060 uint32_t file_permissions) {
3061 std::string path{file_spec.
GetPath(
false)};
3067 llvm::StringRef packet = stream.
GetString();
3074 if (response.
GetChar() !=
'F')
3083#define HANDLE_ERRNO(name, value) \
3086#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3095 if (response.
GetChar() !=
'F')
3097 int32_t result = response.
GetS32(-2, 16);
3100 if (response.
GetChar() ==
',') {
3102 if (result_errno != -1)
3114 std::string path(file_spec.
GetPath(
false));
3135 stream.
Printf(
"vFile:close:%x", (
int)fd);
3144std::optional<GDBRemoteFStatData>
3147 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3151 if (response.
GetChar() !=
'F')
3152 return std::nullopt;
3153 int64_t size = response.
GetS64(-1, 16);
3154 if (size > 0 && response.
GetChar() ==
';') {
3158 if (buffer.size() !=
sizeof(out))
3159 return std::nullopt;
3160 memcpy(&out, buffer.data(),
sizeof(out));
3165 return std::nullopt;
3168std::optional<GDBRemoteFStatData>
3173 return std::nullopt;
3174 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3183 std::string path(file_spec.
GetPath(
false));
3193 if (response.
GetChar() !=
'F')
3202 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3220 while (response.
Peek()) {
3222 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3225 if (response.
GetChar() !=
',')
3233 uint32_t &file_permissions) {
3235 std::string path{file_spec.
GetPath(
false)};
3248 if (response.
GetChar() !=
'F') {
3250 "invalid response to '%s' packet", stream.
GetData());
3252 const uint32_t mode = response.
GetS32(-1, 16);
3253 if (
static_cast<int32_t
>(mode) == -1) {
3254 if (response.
GetChar() ==
',') {
3256 if (response_errno > 0)
3273 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3281 uint64_t offset,
void *dst,
3285 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3290 if (response.
GetChar() !=
'F')
3292 int64_t retcode = response.
GetS64(-1, 16);
3293 if (retcode == -1) {
3295 if (response.
GetChar() ==
',') {
3297 if (response_errno > 0)
3302 const char next = (response.
Peek() ? *response.
Peek() : 0);
3309 const uint64_t data_to_write =
3310 std::min<uint64_t>(dst_len, buffer.size());
3311 if (data_to_write > 0)
3312 memcpy(dst, &buffer[0], data_to_write);
3313 return data_to_write;
3326 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3331 if (response.
GetChar() !=
'F') {
3335 int64_t bytes_written = response.
GetS64(-1, 16);
3336 if (bytes_written == -1) {
3338 if (response.
GetChar() ==
',') {
3340 if (response_errno > 0)
3345 return bytes_written;
3354 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3366 if (response.
GetChar() ==
'F') {
3370 if (response.
GetChar() ==
',') {
3372 if (response_errno > 0)
3387 std::string path{file_spec.
GetPath(
false)};
3397 if (response.
GetChar() ==
'F') {
3401 if (response.
GetChar() ==
',') {
3403 if (response_errno > 0)
3421 std::string path(file_spec.
GetPath(
false));
3430 if (response.
GetChar() !=
'F')
3432 if (response.
GetChar() !=
',')
3434 bool retcode = (response.
GetChar() !=
'0');
3451 std::string path(file_spec.
GetPath(
false));
3458 if (response.
GetChar() !=
'F')
3459 return std::make_error_code(std::errc::illegal_byte_sequence);
3460 if (response.
GetChar() !=
',')
3461 return std::make_error_code(std::errc::illegal_byte_sequence);
3462 if (response.
Peek() && *response.
Peek() ==
'x')
3463 return std::make_error_code(std::errc::no_such_file_or_directory);
3480 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3485 if (part.size() != MD5_HALF_LENGTH)
3486 return std::make_error_code(std::errc::illegal_byte_sequence);
3490 if (part.getAsInteger(16, low))
3491 return std::make_error_code(std::errc::illegal_byte_sequence);
3496 if (part.size() != MD5_HALF_LENGTH)
3497 return std::make_error_code(std::errc::illegal_byte_sequence);
3501 if (part.getAsInteger(16, high))
3502 return std::make_error_code(std::errc::illegal_byte_sequence);
3504 llvm::MD5::MD5Result result;
3505 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3506 result.data(), low);
3507 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3508 result.data() + 8, high);
3512 return std::make_error_code(std::errc::operation_canceled);
3522 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3523 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3524 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3525 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3528 if (gdb_server_version != 0) {
3530 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3531 if (gdb_server_version >= 310)
3544 payload.
Printf(
"p%x", reg);
3553 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3568 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3574 llvm::ArrayRef<uint8_t> data) {
3576 payload.
Printf(
"P%x=", reg_num);
3600 uint32_t &save_id) {
3616 const uint32_t response_save_id = response.
GetU32(0);
3617 if (response_save_id == 0)
3620 save_id = response_save_id;
3633 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3653 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3659llvm::Expected<TraceSupportedResponse>
3664 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3673 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3674 "jLLDBTraceSupported is unsupported");
3676 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3677 "TraceSupportedResponse");
3679 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3680 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3681 "failed to send packet: jLLDBTraceSupported");
3686 std::chrono::seconds timeout) {
3690 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3692 std::string json_string;
3693 llvm::raw_string_ostream os(json_string);
3696 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3705 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3706 "jLLDBTraceStop is unsupported");
3708 return llvm::Error::success();
3709 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3710 "Invalid jLLDBTraceStart response");
3712 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3713 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3714 "failed to send packet: jLLDBTraceStop '%s'",
3720 std::chrono::seconds timeout) {
3724 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3726 std::string json_string;
3727 llvm::raw_string_ostream os(json_string);
3730 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3739 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3740 "jLLDBTraceStart is unsupported");
3742 return llvm::Error::success();
3743 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3744 "Invalid jLLDBTraceStart response");
3746 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3747 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3748 "failed to send packet: jLLDBTraceStart '%s'",
3752llvm::Expected<std::string>
3754 std::chrono::seconds timeout) {
3758 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3760 std::string json_string;
3761 llvm::raw_string_ostream os(json_string);
3764 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3773 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3774 "jLLDBTraceGetState is unsupported");
3775 return std::string(response.
Peek());
3778 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3779 return llvm::createStringError(
3780 llvm::inconvertibleErrorCode(),
3781 "failed to send packet: jLLDBTraceGetState '%s'",
3785llvm::Expected<std::vector<uint8_t>>
3791 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3793 std::string json_string;
3794 llvm::raw_string_ostream os(json_string);
3797 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3807 return std::vector<uint8_t>(data.begin(), data.end());
3809 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3810 return llvm::createStringError(
3811 llvm::inconvertibleErrorCode(),
3812 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3820 return std::nullopt;
3822 return std::nullopt;
3826 const auto &GetOffset = [&] {
3828 if (ref.consumeInteger(16, offset))
3830 result.
offsets.push_back(offset);
3834 if (ref.consume_front(
"Text=")) {
3837 return std::nullopt;
3838 if (!ref.consume_front(
";Data=") || !GetOffset())
3839 return std::nullopt;
3842 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3844 }
else if (ref.consume_front(
"TextSeg=")) {
3847 return std::nullopt;
3850 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3853 return std::nullopt;
3862 std::string module_path = module_file_spec.
GetPath(
false);
3863 if (module_path.empty())
3870 const auto &triple = arch_spec.
GetTriple().getTriple();
3886 llvm::StringRef name;
3887 llvm::StringRef value;
3889 module_spec.
Clear();
3893 if (name ==
"uuid" || name ==
"md5") {
3898 }
else if (name ==
"triple") {
3903 }
else if (name ==
"file_offset") {
3905 if (!value.getAsInteger(16, ival))
3907 }
else if (name ==
"file_size") {
3909 if (!value.getAsInteger(16, ival))
3911 }
else if (name ==
"file_path") {
3922static std::optional<ModuleSpec>
3926 return std::nullopt;
3928 llvm::StringRef string;
3932 return std::nullopt;
3934 return std::nullopt;
3937 return std::nullopt;
3941 return std::nullopt;
3945 return std::nullopt;
3949 return std::nullopt;
3955std::optional<std::vector<ModuleSpec>>
3957 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
3961 return std::nullopt;
3963 json::Array module_array;
3964 for (
const FileSpec &module_file_spec : module_file_specs) {
3965 module_array.push_back(
3966 json::Object{{
"file", module_file_spec.GetPath(
false)},
3967 {
"triple", triple.getTriple()}});
3970 unescaped_payload.
PutCString(
"jModulesInfo:");
3971 unescaped_payload.
AsRawOstream() << std::move(module_array);
3984 return std::nullopt;
3988 return std::nullopt;
3993 if (!response_object_sp)
3994 return std::nullopt;
3997 if (!response_array)
3998 return std::nullopt;
4000 std::vector<ModuleSpec> result;
4001 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
4004 result.push_back(*module_spec);
4014llvm::Expected<std::string>
4016 llvm::StringRef annex) {
4019 llvm::raw_string_ostream output_stream(output);
4033 std::string packet =
4034 (
"qXfer:" +
object +
":read:" + annex +
":" +
4035 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4043 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4044 "Error sending $qXfer packet");
4062 return llvm::createStringError(
4063 llvm::inconvertibleErrorCode(),
4064 "Invalid continuation code from $qXfer packet");
4114 bool symbol_response_provided =
false;
4117 bool first_qsymbol_query =
true;
4128 if (symbol_response_provided || first_qsymbol_query) {
4135 first_qsymbol_query =
false;
4144 if (response_str.starts_with(
"qSymbol:")) {
4146 std::string symbol_name;
4148 if (symbol_name.empty())
4159 switch (sc.symbol->GetType()) {
4192 sc.symbol->GetLoadAddress(&process->
GetTarget());
4205 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4206 symbol_response_provided =
true;
4208 symbol_response_provided =
false;
4224 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4249 "GDBRemoteCommunicationClient::%s(): "
4250 "QSupportedAsyncJSONPackets returned invalid "
4257 "GDBRemoteCommunicationClient::%s(): "
4258 "QSupportedAsyncJSONPackets unsupported",
4266 "GDBRemoteCommunicationClient::%s(): supported async "
4268 __FUNCTION__, stream.
GetData());
4278 llvm::ArrayRef<int32_t> signals) {
4281 auto range = llvm::make_range(signals.begin(), signals.end());
4282 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4294 "Unknown error happened during sending QPassSignals packet.");
4302 if (type_name.empty()) {
4315 config_sp->Dump(unescaped_stream);
4316 unescaped_stream.
Flush();
4334 "configuring StructuredData feature {0} failed with error {1}",
4340 "configuring StructuredData feature {0} failed when sending packet: "
4342 type_name, (
int)result);
4371 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4372 "failed to send k packet");
4374 char packet_cmd = response.
GetChar(0);
4375 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4378 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4379 "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.
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
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.