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 "
381 std::vector<std::string> features = {
"xmlRegisters=i386,arm,mips,arc",
389 for (uint32_t i = 0; i < features.size(); ++i) {
401 for (llvm::StringRef x : llvm::split(response.
GetStringRef(),
';')) {
402 if (x ==
"qXfer:auxv:read+")
404 else if (x ==
"qXfer:libraries-svr4:read+")
406 else if (x ==
"augmented-libraries-svr4-read") {
409 }
else if (x ==
"qXfer:libraries:read+")
411 else if (x ==
"qXfer:features:read+")
413 else if (x ==
"qXfer:memory-map:read+")
415 else if (x ==
"qXfer:siginfo:read+")
417 else if (x ==
"qEcho+")
419 else if (x ==
"QPassSignals+")
421 else if (x ==
"multiprocess+")
423 else if (x ==
"memory-tagging+")
425 else if (x ==
"qSaveCore+")
427 else if (x ==
"native-signals+")
429 else if (x ==
"binary-upload+")
431 else if (x ==
"ReverseContinue+")
433 else if (x ==
"ReverseStep+")
435 else if (x ==
"MultiMemRead+")
440 else if (x.consume_front(
"SupportedCompressions=")) {
441 llvm::SmallVector<llvm::StringRef, 4> compressions;
442 x.split(compressions,
',');
443 if (!compressions.empty())
445 }
else if (x.consume_front(
"SupportedWatchpointTypes=")) {
446 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
447 x.split(watchpoint_types,
',');
449 for (
auto wp_type : watchpoint_types) {
450 if (wp_type ==
"x86_64")
452 if (wp_type ==
"aarch64-mask")
454 if (wp_type ==
"aarch64-bas")
457 }
else if (x.consume_front(
"PacketSize=")) {
464 LLDB_LOGF(log,
"Garbled PacketSize spec in qSupported response");
485 assert(!flavor.empty());
496 for (llvm::StringRef token : llvm::split(response.
GetStringRef(),
';')) {
523 return llvm::StringSwitch<bool>(flavor)
541 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
543 __FUNCTION__, payload.GetData());
548 payload.Printf(
";thread:%4.4" PRIx64
";", tid);
595 }
else if (!response.
Empty()) {
684 packet.
Printf(
"qMemTags:%" PRIx64
",%zx:%" PRIx32, addr, len, type);
692 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s: qMemTags packet failed",
700 if (response.
GetChar() !=
'm') {
702 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
713 if (response.
GetBytesLeft() || (expected_bytes != got_bytes)) {
716 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
726 const std::vector<uint8_t> &tags) {
729 packet.
Printf(
"QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr, len, type);
775 if (response.
GetChar() ==
'Q') {
776 if (response.
GetChar() ==
'C') {
790 bool sequence_mutex_unavailable;
792 if (!ids.empty() && !sequence_mutex_unavailable) {
809 return llvm::createStringError(llvm::inconvertibleErrorCode(),
810 "Nothing to launch");
823 return llvm::createStringError(llvm::inconvertibleErrorCode(),
824 "Sending vRun packet failed");
833 return llvm::Error::success();
841 llvm::ListSeparator LS(
",");
842 for (
const auto &arg : llvm::enumerate(args)) {
844 packet.
Format(
"{0},{1},", arg.value().ref().size() * 2, arg.index());
851 return llvm::createStringError(llvm::inconvertibleErrorCode(),
852 "Sending A packet failed");
859 return llvm::createStringError(llvm::inconvertibleErrorCode(),
860 "Sending qLaunchSuccess packet failed");
863 return llvm::Error::success();
864 if (response.
GetChar() ==
'E') {
865 return llvm::createStringError(llvm::inconvertibleErrorCode(),
868 return llvm::createStringError(llvm::inconvertibleErrorCode(),
869 "unknown error occurred launching process");
873 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
874 for (
const auto &kv : env)
875 vec.emplace_back(kv.first(), kv.second);
876 llvm::sort(vec, llvm::less_first());
877 for (
const auto &[k, v] : vec) {
886 char const *name_equal_value) {
887 if (name_equal_value && name_equal_value[0]) {
888 bool send_hex_encoding =
false;
889 for (
const char *p = name_equal_value; *p !=
'\0' && !send_hex_encoding;
891 if (llvm::isPrint(*p)) {
897 send_hex_encoding =
true;
904 send_hex_encoding =
true;
912 packet.
Printf(
"QEnvironment:%s", name_equal_value);
953 if (arch && arch[0]) {
955 packet.
Printf(
"QLaunchArch:%s", arch);
970 char const *data,
bool *was_supported) {
971 if (data && *data !=
'\0') {
973 packet.
Printf(
"QSetProcessEvent:%s", data);
979 *was_supported =
true;
983 *was_supported =
false;
988 *was_supported =
true;
1012 return std::nullopt;
1015std::optional<std::string>
1021 return std::nullopt;
1049 UUID &uuid,
addr_t &value,
bool &value_is_offset) {
1082 llvm::StringRef name, value;
1083 bool success =
false;
1085 if (name ==
"name") {
1088 }
else if (name ==
"version") {
1089 llvm::StringRef major, minor;
1090 std::tie(major, minor) = value.split(
'.');
1104 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1106 llvm::StringRef avail_name;
1108#if HAVE_LIBCOMPRESSION
1110 for (
auto compression : supported_compressions) {
1111 if (compression ==
"lzfse") {
1113 avail_name = compression;
1119 for (
auto compression : supported_compressions) {
1120 if (compression ==
"zlib-deflate") {
1122 avail_name = compression;
1131 for (
auto compression : supported_compressions) {
1132 if (compression ==
"zlib-deflate") {
1134 avail_name = compression;
1141#if HAVE_LIBCOMPRESSION
1143 for (
auto compression : supported_compressions) {
1144 if (compression ==
"lz4") {
1146 avail_name = compression;
1152 for (
auto compression : supported_compressions) {
1153 if (compression ==
"lzma") {
1155 avail_name = compression;
1164 std::string packet =
"QEnableCompression:type:" + avail_name.str() +
";";
1211 tid = pid_tid->second;
1218 std::string &environment) {
1219 if (value ==
"iossimulator" || value ==
"tvossimulator" ||
1220 value ==
"watchossimulator" || value ==
"xrossimulator" ||
1221 value ==
"visionossimulator") {
1222 environment =
"simulator";
1223 os_name = value.drop_back(environment.size()).str();
1224 }
else if (value ==
"maccatalyst") {
1226 environment =
"macabi";
1228 os_name = value.str();
1244 llvm::StringRef name;
1245 llvm::StringRef value;
1248 std::string arch_name;
1249 std::string os_name;
1250 std::string environment;
1251 std::string vendor_name;
1253 uint32_t pointer_byte_size = 0;
1255 uint32_t num_keys_decoded = 0;
1257 if (name ==
"cputype") {
1259 if (!value.getAsInteger(0, cpu))
1261 }
else if (name ==
"cpusubtype") {
1263 if (!value.getAsInteger(0, sub))
1265 }
else if (name ==
"arch") {
1266 arch_name = std::string(value);
1268 }
else if (name ==
"triple") {
1272 }
else if (name ==
"distribution_id") {
1276 }
else if (name ==
"os_build") {
1280 }
else if (name ==
"hostname") {
1284 }
else if (name ==
"os_kernel") {
1288 }
else if (name ==
"ostype") {
1291 }
else if (name ==
"vendor") {
1292 vendor_name = std::string(value);
1294 }
else if (name ==
"endian") {
1295 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1302 }
else if (name ==
"ptrsize") {
1303 if (!value.getAsInteger(0, pointer_byte_size))
1305 }
else if (name ==
"addressing_bits") {
1309 }
else if (name ==
"high_mem_addressing_bits") {
1312 }
else if (name ==
"low_mem_addressing_bits") {
1315 }
else if (name ==
"os_version" ||
1322 }
else if (name ==
"maccatalyst_version") {
1325 }
else if (name ==
"watchpoint_exceptions_received") {
1327 llvm::StringSwitch<LazyBool>(value)
1333 }
else if (name ==
"default_packet_timeout") {
1334 uint32_t timeout_seconds;
1335 if (!value.getAsInteger(0, timeout_seconds)) {
1340 }
else if (name ==
"vm-page-size") {
1342 if (!value.getAsInteger(0, page_size)) {
1349 if (num_keys_decoded > 0)
1352 if (triple.empty()) {
1353 if (arch_name.empty()) {
1356 if (pointer_byte_size) {
1357 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1363 if (!vendor_name.empty())
1365 llvm::StringRef(vendor_name));
1366 if (!os_name.empty())
1367 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1368 if (!environment.empty())
1369 m_host_arch.GetTriple().setEnvironmentName(environment);
1373 triple += arch_name;
1374 if (!vendor_name.empty() || !os_name.empty()) {
1376 if (vendor_name.empty())
1377 triple +=
"unknown";
1379 triple += vendor_name;
1381 if (os_name.empty())
1382 triple +=
"unknown";
1388 llvm::Triple &host_triple =
m_host_arch.GetTriple();
1389 if (host_triple.getVendor() == llvm::Triple::Apple &&
1390 host_triple.getOS() == llvm::Triple::Darwin) {
1392 case llvm::Triple::aarch64:
1393 case llvm::Triple::aarch64_32:
1394 case llvm::Triple::arm:
1395 case llvm::Triple::thumb:
1396 host_triple.setOS(llvm::Triple::IOS);
1399 host_triple.setOS(llvm::Triple::MacOSX);
1403 if (pointer_byte_size) {
1404 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1412 if (pointer_byte_size) {
1413 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1420 "GDBRemoteCommunicationClient::%s parsed host "
1421 "architecture as %s, triple as %s from triple text %s",
1425 :
"<null-arch-name>",
1465 return addressable_bits;
1475 uint32_t permissions) {
1479 const int packet_len = ::snprintf(
1480 packet,
sizeof(packet),
"_M%" PRIx64
",%s%s%s", (uint64_t)size,
1481 permissions & lldb::ePermissionsReadable ?
"r" :
"",
1482 permissions & lldb::ePermissionsWritable ?
"w" :
"",
1483 permissions & lldb::ePermissionsExecutable ?
"x" :
"");
1484 assert(packet_len < (
int)
sizeof(packet));
1504 const int packet_len =
1505 ::snprintf(packet,
sizeof(packet),
"_m%" PRIx64, (uint64_t)addr);
1506 assert(packet_len < (
int)
sizeof(packet));
1531 const int packet_len =
1532 ::snprintf(packet,
sizeof(packet),
"qSupportsDetachAndStayStopped:");
1533 assert(packet_len < (
int)
sizeof(packet));
1547 "Stays stopped not supported by this target.");
1563 "Multiprocess extension not supported by the server.");
1578 region_info.
Clear();
1583 const int packet_len = ::snprintf(
1584 packet,
sizeof(packet),
"qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1585 assert(packet_len < (
int)
sizeof(packet));
1591 llvm::StringRef name;
1592 llvm::StringRef value;
1594 bool success =
true;
1595 bool saw_permissions =
false;
1597 if (name ==
"start") {
1598 if (!value.getAsInteger(16, addr_value))
1600 }
else if (name ==
"size") {
1601 if (!value.getAsInteger(16, addr_value)) {
1609 }
else if (name ==
"permissions" && region_info.
GetRange().
IsValid()) {
1610 saw_permissions =
true;
1612 if (value.contains(
'r'))
1617 if (value.contains(
'w'))
1622 if (value.contains(
'x'))
1636 }
else if (name ==
"name") {
1640 region_info.
SetName(name.c_str());
1641 }
else if (name ==
"flags") {
1645 llvm::StringRef flags = value;
1646 llvm::StringRef flag;
1647 while (flags.size()) {
1648 flags = flags.ltrim();
1649 std::tie(flag, flags) = flags.split(
' ');
1654 else if (flag ==
"ss")
1658 }
else if (name ==
"type") {
1659 for (llvm::StringRef entry : llvm::split(value,
',')) {
1660 if (entry ==
"stack")
1662 else if (entry ==
"heap")
1665 }
else if (name ==
"error") {
1667 std::string error_string;
1671 }
else if (name ==
"dirty-pages") {
1672 std::vector<addr_t> dirty_page_list;
1673 for (llvm::StringRef x : llvm::split(value,
',')) {
1675 x.consume_front(
"0x");
1676 if (llvm::to_integer(x, page, 16))
1677 dirty_page_list.push_back(page);
1689 if (!saw_permissions) {
1717 region_info = qXfer_region_info;
1720 region_info.
Clear();
1722 }
else if (qXfer_error.
Success()) {
1737 if (!
error.Success())
1740 if (map_region.GetRange().Contains(addr)) {
1741 region = map_region;
1767 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1773 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1789 if (memory_node.
GetName() !=
"memory")
1801 if (type ==
"rom") {
1804 }
else if (type ==
"ram") {
1808 }
else if (type ==
"flash") {
1811 [®ion](
const XMLNode &prop_node) ->
bool {
1814 if (prop_node.
GetName() !=
"property")
1817 if (propname ==
"blocksize") {
1839 std::optional<uint32_t> num;
1845 llvm::StringRef name;
1846 llvm::StringRef value;
1848 if (name ==
"num") {
1864WatchpointHardwareFeature
1883 return std::nullopt;
1888 std::string path{file_spec.
GetPath(
false)};
1908 std::string path{file_spec.
GetPath(
false)};
1928 std::string path{file_spec.
GetPath(
false)};
1957 return !cwd.empty();
1964 std::string path{working_dir.
GetPath(
false)};
1984 const int packet_len =
1985 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
1986 assert(packet_len < (
int)
sizeof(packet));
2001 const int packet_len = ::snprintf(packet,
sizeof(packet),
2002 "QSetDetachOnError:%i", enable ? 1 : 0);
2003 assert(packet_len < (
int)
sizeof(packet));
2019 llvm::StringRef name;
2020 llvm::StringRef value;
2026 std::string os_type;
2029 if (name ==
"pid") {
2031 value.getAsInteger(0, pid);
2033 }
else if (name ==
"ppid") {
2035 value.getAsInteger(0, pid);
2037 }
else if (name ==
"uid") {
2039 value.getAsInteger(0, uid);
2041 }
else if (name ==
"euid") {
2043 value.getAsInteger(0, uid);
2045 }
else if (name ==
"gid") {
2047 value.getAsInteger(0, gid);
2049 }
else if (name ==
"egid") {
2051 value.getAsInteger(0, gid);
2053 }
else if (name ==
"triple") {
2058 }
else if (name ==
"name") {
2065 }
else if (name ==
"args") {
2066 llvm::StringRef encoded_args(value), hex_arg;
2068 bool is_arg0 =
true;
2069 while (!encoded_args.empty()) {
2070 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2085 }
else if (name ==
"cputype") {
2086 value.getAsInteger(0, cpu);
2087 }
else if (name ==
"cpusubtype") {
2088 value.getAsInteger(0, sub);
2089 }
else if (name ==
"vendor") {
2090 vendor = std::string(value);
2091 }
else if (name ==
"ostype") {
2092 os_type = std::string(value);
2097 if (vendor ==
"apple") {
2101 llvm::StringRef(vendor));
2103 llvm::StringRef(os_type));
2115 process_info.
Clear();
2119 const int packet_len =
2120 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2121 assert(packet_len < (
int)
sizeof(packet));
2151 llvm::StringRef name;
2152 llvm::StringRef value;
2155 std::string os_name;
2156 std::string environment;
2157 std::string vendor_name;
2159 std::string elf_abi;
2160 uint32_t pointer_byte_size = 0;
2163 uint32_t num_keys_decoded = 0;
2166 if (name ==
"cputype") {
2167 if (!value.getAsInteger(16, cpu))
2169 }
else if (name ==
"cpusubtype") {
2170 if (!value.getAsInteger(16, sub)) {
2176 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2177 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2184 }
else if (name ==
"triple") {
2188 }
else if (name ==
"ostype") {
2191 }
else if (name ==
"vendor") {
2192 vendor_name = std::string(value);
2194 }
else if (name ==
"endian") {
2195 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2202 }
else if (name ==
"ptrsize") {
2203 if (!value.getAsInteger(16, pointer_byte_size))
2205 }
else if (name ==
"pid") {
2206 if (!value.getAsInteger(16, pid))
2208 }
else if (name ==
"elf_abi") {
2209 elf_abi = std::string(value);
2211 }
else if (name ==
"main-binary-uuid") {
2214 }
else if (name ==
"main-binary-slide") {
2222 }
else if (name ==
"main-binary-address") {
2230 }
else if (name ==
"binary-addresses") {
2233 for (llvm::StringRef x : llvm::split(value,
',')) {
2235 x.consume_front(
"0x");
2236 if (llvm::to_integer(x, vmaddr, 16))
2241 if (num_keys_decoded > 0)
2249 if (!triple.empty()) {
2252 if (pointer_byte_size) {
2253 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2256 !vendor_name.empty()) {
2257 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2258 if (!environment.empty())
2259 triple.setEnvironmentName(environment);
2261 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2262 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2263 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2264 switch (triple.getObjectFormat()) {
2265 case llvm::Triple::MachO:
2268 case llvm::Triple::ELF:
2271 case llvm::Triple::COFF:
2274 case llvm::Triple::GOFF:
2275 case llvm::Triple::SPIRV:
2276 case llvm::Triple::Wasm:
2277 case llvm::Triple::XCOFF:
2278 case llvm::Triple::DXContainer:
2279 LLDB_LOGF(log,
"error: not supported target architecture");
2281 case llvm::Triple::UnknownObjectFormat:
2282 LLDB_LOGF(log,
"error: failed to determine target architecture");
2286 if (pointer_byte_size) {
2287 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2292 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2294 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2308 process_infos.clear();
2316 bool has_name_match =
false;
2317 if (name && name[0]) {
2318 has_name_match =
true;
2320 switch (name_match_type) {
2322 has_name_match =
false;
2334 packet.
PutCString(
"name_match:starts_with;");
2345 if (has_name_match) {
2353 packet.
Printf(
"pid:%" PRIu64
";",
2356 packet.
Printf(
"parent_pid:%" PRIu64
";",
2363 packet.
Printf(
"euid:%u;",
2366 packet.
Printf(
"egid:%u;",
2372 const llvm::Triple &triple = match_arch.
GetTriple();
2388 process_infos.push_back(process_info);
2397 return process_infos.size();
2401 std::string &name) {
2404 const int packet_len =
2405 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2406 assert(packet_len < (
int)
sizeof(packet));
2428 std::string &name) {
2431 const int packet_len =
2432 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2433 assert(packet_len < (
int)
sizeof(packet));
2455 uint32_t recv_size) {
2457 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2458 uint32_t bytes_left = send_size;
2459 while (bytes_left > 0) {
2460 if (bytes_left >= 26) {
2461 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2464 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2465 "abcdefghijklmnopqrstuvwxyz");
2474 return duration<float>::zero();
2475 using Dur = duration<float>;
2476 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2477 Dur mean = sum / v.size();
2480 float delta = (d - mean).count();
2481 accum += delta * delta;
2484 return Dur(sqrtf(accum / (v.size() - 1)));
2490 uint64_t recv_amount,
2491 bool json,
Stream &strm) {
2496 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2500 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2504 uint32_t result_idx = 0;
2506 std::vector<duration<float>> packet_times;
2508 for (send_size = 0; send_size <= max_send;
2509 send_size ? send_size *= 2 : send_size = 4) {
2510 for (uint32_t recv_size = 0; recv_size <= max_recv;
2511 recv_size ? recv_size *= 2 : recv_size = 4) {
2514 packet_times.clear();
2516 const auto start_time = steady_clock::now();
2517 for (uint32_t i = 0; i < num_packets; ++i) {
2518 const auto packet_start_time = steady_clock::now();
2521 const auto packet_end_time = steady_clock::now();
2522 packet_times.push_back(packet_end_time - packet_start_time);
2524 const auto end_time = steady_clock::now();
2525 const auto total_time = end_time - start_time;
2527 float packets_per_second =
2528 ((float)num_packets) / duration<float>(total_time).count();
2529 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2530 : duration<float>::zero();
2531 const duration<float> standard_deviation =
2534 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2535 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2536 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2537 result_idx > 0 ?
"," :
"", send_size, recv_size,
2538 total_time, standard_deviation);
2541 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2542 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2543 "standard deviation of {5,10:ms+f6}\n",
2544 send_size, recv_size, duration<float>(total_time),
2545 packets_per_second, duration<float>(average_per_packet),
2546 standard_deviation);
2552 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2554 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2555 ": %" PRIu64
",\n \"results\" : [",
2558 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2564 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2569 if (recv_size > 0) {
2570 const auto start_time = steady_clock::now();
2571 uint32_t bytes_read = 0;
2572 uint32_t packet_count = 0;
2573 while (bytes_read < recv_amount) {
2576 bytes_read += recv_size;
2579 const auto end_time = steady_clock::now();
2580 const auto total_time = end_time - start_time;
2581 float mb_second = ((float)recv_amount) /
2582 duration<float>(total_time).count() /
2584 float packets_per_second =
2585 ((float)packet_count) / duration<float>(total_time).count();
2586 const auto average_per_packet = packet_count > 0
2587 ? total_time / packet_count
2588 : duration<float>::zero();
2591 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2592 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2593 result_idx > 0 ?
"," :
"", send_size, recv_size,
2597 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2598 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2599 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2600 send_size, recv_size, packet_count, k_recv_amount_mb,
2601 duration<float>(total_time), mb_second,
2602 packets_per_second, duration<float>(average_per_packet));
2608 strm.
Printf(
"\n ]\n }\n}\n");
2615 uint32_t recv_size) {
2617 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2618 uint32_t bytes_left = send_size;
2619 while (bytes_left > 0) {
2620 if (bytes_left >= 26) {
2621 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2624 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2625 "abcdefghijklmnopqrstuvwxyz");
2636 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2637 std::string &socket_name) {
2640 socket_name.clear();
2645 std::string hostname;
2646 if (remote_accept_hostname && remote_accept_hostname[0])
2647 hostname = remote_accept_hostname;
2649 if (HostInfo::GetHostname(hostname)) {
2651 stream.
Printf(
"host:%s;", hostname.c_str());
2655 stream.
Printf(
"host:*;");
2666 llvm::StringRef name;
2667 llvm::StringRef value;
2670 value.getAsInteger(0, port);
2671 else if (name ==
"pid")
2672 value.getAsInteger(0, pid);
2673 else if (name.compare(
"socket_name") == 0) {
2684 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2685 connection_urls.clear();
2701 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2702 std::optional<StructuredData::Dictionary *> maybe_element =
2711 port = port_osp->GetUnsignedIntegerValue(0);
2713 std::string socket_name;
2716 socket_name = std::string(socket_name_osp->GetStringValue());
2718 if (port != 0 || !socket_name.empty())
2719 connection_urls.emplace_back(port, socket_name);
2721 return connection_urls.size();
2726 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2738 uint64_t tid, uint64_t pid,
char op) {
2744 packet.
Printf(
"p%" PRIx64
".", pid);
2749 packet.
Printf(
"%" PRIx64, tid);
2755 return {{pid, tid}};
2767 return std::nullopt;
2782 return ret.has_value();
2797 return ret.has_value();
2812 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2813 assert(packet_len < (
int)
sizeof(packet));
2832 std::chrono::seconds timeout) {
2834 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2835 __FUNCTION__, insert ?
"add" :
"remove", addr);
2842 const int packet_len =
2843 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2844 insert ?
'Z' :
'z', type, addr, length);
2846 assert(packet_len + 1 < (
int)
sizeof(packet));
2891std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2893 bool &sequence_mutex_unavailable) {
2894 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2898 sequence_mutex_unavailable =
false;
2902 for (packet_result =
2920 ids.push_back(*pid_tid);
2922 }
while (ch ==
',');
2936 ids.emplace_back(1, 1);
2940 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
2941 "packet 'qfThreadInfo'");
2942 sequence_mutex_unavailable =
true;
2949 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
2954 if (ids.empty() || sequence_mutex_unavailable)
2957 for (
auto id : ids) {
2963 thread_ids.push_back(
id.second);
2966 return thread_ids.size();
2979 llvm::StringRef command,
2987 std::string *separated_error_output,
2997 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3001 std::string path{working_dir.
GetPath(
false)};
3008 if (response.
GetChar() !=
'F')
3010 if (response.
GetChar() !=
',')
3015 else if (status_ptr)
3016 *status_ptr = exitcode;
3017 if (response.
GetChar() !=
',')
3022 if (response.
GetChar() !=
',')
3027 command_output->assign(output);
3034 uint32_t file_permissions) {
3035 std::string path{file_spec.
GetPath(
false)};
3041 llvm::StringRef packet = stream.
GetString();
3046 packet.str().c_str());
3048 if (response.
GetChar() !=
'F')
3050 packet.str().c_str());
3057 uint32_t file_permissions) {
3058 std::string path{file_spec.
GetPath(
false)};
3064 llvm::StringRef packet = stream.
GetString();
3071 if (response.
GetChar() !=
'F')
3080#define HANDLE_ERRNO(name, value) \
3083#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3092 if (response.
GetChar() !=
'F')
3094 int32_t result = response.
GetS32(-2, 16);
3097 if (response.
GetChar() ==
',') {
3099 if (result_errno != -1)
3111 std::string path(file_spec.
GetPath(
false));
3132 stream.
Printf(
"vFile:close:%x", (
int)fd);
3141std::optional<GDBRemoteFStatData>
3144 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3148 if (response.
GetChar() !=
'F')
3149 return std::nullopt;
3150 int64_t size = response.
GetS64(-1, 16);
3151 if (size > 0 && response.
GetChar() ==
';') {
3155 if (buffer.size() !=
sizeof(out))
3156 return std::nullopt;
3157 memcpy(&out, buffer.data(),
sizeof(out));
3162 return std::nullopt;
3165std::optional<GDBRemoteFStatData>
3170 return std::nullopt;
3171 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3180 std::string path(file_spec.
GetPath(
false));
3190 if (response.
GetChar() !=
'F')
3199 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3217 while (response.
Peek()) {
3219 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3222 if (response.
GetChar() !=
',')
3230 uint32_t &file_permissions) {
3232 std::string path{file_spec.
GetPath(
false)};
3245 if (response.
GetChar() !=
'F') {
3247 "invalid response to '%s' packet", stream.
GetData());
3249 const uint32_t mode = response.
GetS32(-1, 16);
3250 if (
static_cast<int32_t
>(mode) == -1) {
3251 if (response.
GetChar() ==
',') {
3253 if (response_errno > 0)
3270 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3278 uint64_t offset,
void *dst,
3282 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3287 if (response.
GetChar() !=
'F')
3289 int64_t retcode = response.
GetS64(-1, 16);
3290 if (retcode == -1) {
3292 if (response.
GetChar() ==
',') {
3294 if (response_errno > 0)
3299 const char next = (response.
Peek() ? *response.
Peek() : 0);
3306 const uint64_t data_to_write =
3307 std::min<uint64_t>(dst_len, buffer.size());
3308 if (data_to_write > 0)
3309 memcpy(dst, &buffer[0], data_to_write);
3310 return data_to_write;
3323 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3328 if (response.
GetChar() !=
'F') {
3332 int64_t bytes_written = response.
GetS64(-1, 16);
3333 if (bytes_written == -1) {
3335 if (response.
GetChar() ==
',') {
3337 if (response_errno > 0)
3342 return bytes_written;
3351 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3363 if (response.
GetChar() ==
'F') {
3367 if (response.
GetChar() ==
',') {
3369 if (response_errno > 0)
3384 std::string path{file_spec.
GetPath(
false)};
3394 if (response.
GetChar() ==
'F') {
3398 if (response.
GetChar() ==
',') {
3400 if (response_errno > 0)
3418 std::string path(file_spec.
GetPath(
false));
3427 if (response.
GetChar() !=
'F')
3429 if (response.
GetChar() !=
',')
3431 bool retcode = (response.
GetChar() !=
'0');
3448 std::string path(file_spec.
GetPath(
false));
3455 if (response.
GetChar() !=
'F')
3456 return std::make_error_code(std::errc::illegal_byte_sequence);
3457 if (response.
GetChar() !=
',')
3458 return std::make_error_code(std::errc::illegal_byte_sequence);
3459 if (response.
Peek() && *response.
Peek() ==
'x')
3460 return std::make_error_code(std::errc::no_such_file_or_directory);
3477 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3482 if (part.size() != MD5_HALF_LENGTH)
3483 return std::make_error_code(std::errc::illegal_byte_sequence);
3487 if (part.getAsInteger(16, low))
3488 return std::make_error_code(std::errc::illegal_byte_sequence);
3493 if (part.size() != MD5_HALF_LENGTH)
3494 return std::make_error_code(std::errc::illegal_byte_sequence);
3498 if (part.getAsInteger(16, high))
3499 return std::make_error_code(std::errc::illegal_byte_sequence);
3501 llvm::MD5::MD5Result result;
3502 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3503 result.data(), low);
3504 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3505 result.data() + 8, high);
3509 return std::make_error_code(std::errc::operation_canceled);
3519 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3520 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3521 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3522 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3525 if (gdb_server_version != 0) {
3527 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3528 if (gdb_server_version >= 310)
3541 payload.
Printf(
"p%x", reg);
3550 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3565 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3571 llvm::ArrayRef<uint8_t> data) {
3573 payload.
Printf(
"P%x=", reg_num);
3597 uint32_t &save_id) {
3613 const uint32_t response_save_id = response.
GetU32(0);
3614 if (response_save_id == 0)
3617 save_id = response_save_id;
3630 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3650 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3656llvm::Expected<TraceSupportedResponse>
3661 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3670 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3671 "jLLDBTraceSupported is unsupported");
3673 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3674 "TraceSupportedResponse");
3676 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3677 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3678 "failed to send packet: jLLDBTraceSupported");
3683 std::chrono::seconds timeout) {
3687 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3689 std::string json_string;
3690 llvm::raw_string_ostream os(json_string);
3693 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3702 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3703 "jLLDBTraceStop is unsupported");
3705 return llvm::Error::success();
3706 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3707 "Invalid jLLDBTraceStart response");
3709 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3710 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3711 "failed to send packet: jLLDBTraceStop '%s'",
3717 std::chrono::seconds timeout) {
3721 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3723 std::string json_string;
3724 llvm::raw_string_ostream os(json_string);
3727 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3736 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3737 "jLLDBTraceStart is unsupported");
3739 return llvm::Error::success();
3740 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3741 "Invalid jLLDBTraceStart response");
3743 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3744 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3745 "failed to send packet: jLLDBTraceStart '%s'",
3749llvm::Expected<std::string>
3751 std::chrono::seconds timeout) {
3755 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3757 std::string json_string;
3758 llvm::raw_string_ostream os(json_string);
3761 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3770 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3771 "jLLDBTraceGetState is unsupported");
3772 return std::string(response.
Peek());
3775 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3776 return llvm::createStringError(
3777 llvm::inconvertibleErrorCode(),
3778 "failed to send packet: jLLDBTraceGetState '%s'",
3782llvm::Expected<std::vector<uint8_t>>
3788 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3790 std::string json_string;
3791 llvm::raw_string_ostream os(json_string);
3794 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3804 return std::vector<uint8_t>(data.begin(), data.end());
3806 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3807 return llvm::createStringError(
3808 llvm::inconvertibleErrorCode(),
3809 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3817 return std::nullopt;
3819 return std::nullopt;
3823 const auto &GetOffset = [&] {
3825 if (ref.consumeInteger(16, offset))
3827 result.
offsets.push_back(offset);
3831 if (ref.consume_front(
"Text=")) {
3834 return std::nullopt;
3835 if (!ref.consume_front(
";Data=") || !GetOffset())
3836 return std::nullopt;
3839 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3841 }
else if (ref.consume_front(
"TextSeg=")) {
3844 return std::nullopt;
3847 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3850 return std::nullopt;
3859 std::string module_path = module_file_spec.
GetPath(
false);
3860 if (module_path.empty())
3867 const auto &triple = arch_spec.
GetTriple().getTriple();
3883 llvm::StringRef name;
3884 llvm::StringRef value;
3886 module_spec.
Clear();
3890 if (name ==
"uuid" || name ==
"md5") {
3895 }
else if (name ==
"triple") {
3900 }
else if (name ==
"file_offset") {
3902 if (!value.getAsInteger(16, ival))
3904 }
else if (name ==
"file_size") {
3906 if (!value.getAsInteger(16, ival))
3908 }
else if (name ==
"file_path") {
3919static std::optional<ModuleSpec>
3923 return std::nullopt;
3925 llvm::StringRef string;
3929 return std::nullopt;
3931 return std::nullopt;
3934 return std::nullopt;
3938 return std::nullopt;
3942 return std::nullopt;
3946 return std::nullopt;
3952std::optional<std::vector<ModuleSpec>>
3954 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
3958 return std::nullopt;
3960 json::Array module_array;
3961 for (
const FileSpec &module_file_spec : module_file_specs) {
3962 module_array.push_back(
3963 json::Object{{
"file", module_file_spec.GetPath(
false)},
3964 {
"triple", triple.getTriple()}});
3967 unescaped_payload.
PutCString(
"jModulesInfo:");
3968 unescaped_payload.
AsRawOstream() << std::move(module_array);
3981 return std::nullopt;
3985 return std::nullopt;
3990 if (!response_object_sp)
3991 return std::nullopt;
3994 if (!response_array)
3995 return std::nullopt;
3997 std::vector<ModuleSpec> result;
3998 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
4001 result.push_back(*module_spec);
4011llvm::Expected<std::string>
4013 llvm::StringRef annex) {
4016 llvm::raw_string_ostream output_stream(output);
4030 std::string packet =
4031 (
"qXfer:" +
object +
":read:" + annex +
":" +
4032 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4040 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4041 "Error sending $qXfer packet");
4059 return llvm::createStringError(
4060 llvm::inconvertibleErrorCode(),
4061 "Invalid continuation code from $qXfer packet");
4111 bool symbol_response_provided =
false;
4114 bool first_qsymbol_query =
true;
4125 if (symbol_response_provided || first_qsymbol_query) {
4132 first_qsymbol_query =
false;
4141 if (response_str.starts_with(
"qSymbol:")) {
4143 std::string symbol_name;
4145 if (symbol_name.empty())
4156 switch (sc.symbol->GetType()) {
4189 sc.symbol->GetLoadAddress(&process->
GetTarget());
4202 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4203 symbol_response_provided =
true;
4205 symbol_response_provided =
false;
4221 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4246 "GDBRemoteCommunicationClient::%s(): "
4247 "QSupportedAsyncJSONPackets returned invalid "
4254 "GDBRemoteCommunicationClient::%s(): "
4255 "QSupportedAsyncJSONPackets unsupported",
4263 "GDBRemoteCommunicationClient::%s(): supported async "
4265 __FUNCTION__, stream.
GetData());
4275 llvm::ArrayRef<int32_t> signals) {
4278 auto range = llvm::make_range(signals.begin(), signals.end());
4279 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4291 "Unknown error happened during sending QPassSignals packet.");
4299 if (type_name.empty()) {
4312 config_sp->Dump(unescaped_stream);
4313 unescaped_stream.
Flush();
4331 "configuring StructuredData feature {0} failed with error {1}",
4337 "configuring StructuredData feature {0} failed when sending packet: "
4339 type_name, (
int)result);
4368 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4369 "failed to send k packet");
4371 char packet_cmd = response.
GetChar(0);
4372 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4375 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4376 "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 SetFlash(OptionalBool val)
void SetMapped(OptionalBool val)
void SetBlocksize(lldb::offset_t blocksize)
void SetMemoryTagged(OptionalBool val)
void SetReadable(OptionalBool val)
void SetExecutable(OptionalBool val)
void SetIsStackMemory(OptionalBool val)
void SetPageSize(int pagesize)
void SetName(const char *name)
void SetWritable(OptionalBool val)
lldb::offset_t GetBlocksize() const
void SetDirtyPageList(std::vector< lldb::addr_t > pagelist)
OptionalBool GetFlash() const
void SetIsShadowStack(OptionalBool 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)
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_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()
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.