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);
1680 }
else if (name ==
"protection-key") {
1681 unsigned protection_key = 0;
1682 if (!value.getAsInteger(10, protection_key))
1693 if (!saw_permissions) {
1721 region_info = qXfer_region_info;
1724 region_info.
Clear();
1726 }
else if (qXfer_error.
Success()) {
1741 if (!
error.Success())
1744 if (map_region.GetRange().Contains(addr)) {
1745 region = map_region;
1771 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1777 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1793 if (memory_node.
GetName() !=
"memory")
1805 if (type ==
"rom") {
1808 }
else if (type ==
"ram") {
1812 }
else if (type ==
"flash") {
1815 [®ion](
const XMLNode &prop_node) ->
bool {
1818 if (prop_node.
GetName() !=
"property")
1821 if (propname ==
"blocksize") {
1843 std::optional<uint32_t> num;
1849 llvm::StringRef name;
1850 llvm::StringRef value;
1852 if (name ==
"num") {
1868WatchpointHardwareFeature
1887 return std::nullopt;
1892 std::string path{file_spec.
GetPath(
false)};
1912 std::string path{file_spec.
GetPath(
false)};
1932 std::string path{file_spec.
GetPath(
false)};
1961 return !cwd.empty();
1968 std::string path{working_dir.
GetPath(
false)};
1988 const int packet_len =
1989 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
1990 assert(packet_len < (
int)
sizeof(packet));
2005 const int packet_len = ::snprintf(packet,
sizeof(packet),
2006 "QSetDetachOnError:%i", enable ? 1 : 0);
2007 assert(packet_len < (
int)
sizeof(packet));
2023 llvm::StringRef name;
2024 llvm::StringRef value;
2030 std::string os_type;
2033 if (name ==
"pid") {
2035 value.getAsInteger(0, pid);
2037 }
else if (name ==
"ppid") {
2039 value.getAsInteger(0, pid);
2041 }
else if (name ==
"uid") {
2043 value.getAsInteger(0, uid);
2045 }
else if (name ==
"euid") {
2047 value.getAsInteger(0, uid);
2049 }
else if (name ==
"gid") {
2051 value.getAsInteger(0, gid);
2053 }
else if (name ==
"egid") {
2055 value.getAsInteger(0, gid);
2057 }
else if (name ==
"triple") {
2062 }
else if (name ==
"name") {
2069 }
else if (name ==
"args") {
2070 llvm::StringRef encoded_args(value), hex_arg;
2072 bool is_arg0 =
true;
2073 while (!encoded_args.empty()) {
2074 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2089 }
else if (name ==
"cputype") {
2090 value.getAsInteger(0, cpu);
2091 }
else if (name ==
"cpusubtype") {
2092 value.getAsInteger(0, sub);
2093 }
else if (name ==
"vendor") {
2094 vendor = std::string(value);
2095 }
else if (name ==
"ostype") {
2096 os_type = std::string(value);
2101 if (vendor ==
"apple") {
2105 llvm::StringRef(vendor));
2107 llvm::StringRef(os_type));
2119 process_info.
Clear();
2123 const int packet_len =
2124 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2125 assert(packet_len < (
int)
sizeof(packet));
2155 llvm::StringRef name;
2156 llvm::StringRef value;
2159 std::string os_name;
2160 std::string environment;
2161 std::string vendor_name;
2163 std::string elf_abi;
2164 uint32_t pointer_byte_size = 0;
2167 uint32_t num_keys_decoded = 0;
2170 if (name ==
"cputype") {
2171 if (!value.getAsInteger(16, cpu))
2173 }
else if (name ==
"cpusubtype") {
2174 if (!value.getAsInteger(16, sub)) {
2180 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2181 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2188 }
else if (name ==
"triple") {
2192 }
else if (name ==
"ostype") {
2195 }
else if (name ==
"vendor") {
2196 vendor_name = std::string(value);
2198 }
else if (name ==
"endian") {
2199 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2206 }
else if (name ==
"ptrsize") {
2207 if (!value.getAsInteger(16, pointer_byte_size))
2209 }
else if (name ==
"pid") {
2210 if (!value.getAsInteger(16, pid))
2212 }
else if (name ==
"elf_abi") {
2213 elf_abi = std::string(value);
2215 }
else if (name ==
"main-binary-uuid") {
2218 }
else if (name ==
"main-binary-slide") {
2226 }
else if (name ==
"main-binary-address") {
2234 }
else if (name ==
"binary-addresses") {
2237 for (llvm::StringRef x : llvm::split(value,
',')) {
2239 x.consume_front(
"0x");
2240 if (llvm::to_integer(x, vmaddr, 16))
2245 if (num_keys_decoded > 0)
2253 if (!triple.empty()) {
2256 if (pointer_byte_size) {
2257 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2260 !vendor_name.empty()) {
2261 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2262 if (!environment.empty())
2263 triple.setEnvironmentName(environment);
2265 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2266 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2267 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2268 switch (triple.getObjectFormat()) {
2269 case llvm::Triple::MachO:
2272 case llvm::Triple::ELF:
2275 case llvm::Triple::COFF:
2278 case llvm::Triple::GOFF:
2279 case llvm::Triple::SPIRV:
2280 case llvm::Triple::Wasm:
2281 case llvm::Triple::XCOFF:
2282 case llvm::Triple::DXContainer:
2283 LLDB_LOGF(log,
"error: not supported target architecture");
2285 case llvm::Triple::UnknownObjectFormat:
2286 LLDB_LOGF(log,
"error: failed to determine target architecture");
2290 if (pointer_byte_size) {
2291 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2296 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2298 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2312 process_infos.clear();
2320 bool has_name_match =
false;
2321 if (name && name[0]) {
2322 has_name_match =
true;
2324 switch (name_match_type) {
2326 has_name_match =
false;
2338 packet.
PutCString(
"name_match:starts_with;");
2349 if (has_name_match) {
2357 packet.
Printf(
"pid:%" PRIu64
";",
2360 packet.
Printf(
"parent_pid:%" PRIu64
";",
2367 packet.
Printf(
"euid:%u;",
2370 packet.
Printf(
"egid:%u;",
2376 const llvm::Triple &triple = match_arch.
GetTriple();
2392 process_infos.push_back(process_info);
2401 return process_infos.size();
2405 std::string &name) {
2408 const int packet_len =
2409 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2410 assert(packet_len < (
int)
sizeof(packet));
2432 std::string &name) {
2435 const int packet_len =
2436 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2437 assert(packet_len < (
int)
sizeof(packet));
2459 uint32_t recv_size) {
2461 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2462 uint32_t bytes_left = send_size;
2463 while (bytes_left > 0) {
2464 if (bytes_left >= 26) {
2465 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2468 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2469 "abcdefghijklmnopqrstuvwxyz");
2478 return duration<float>::zero();
2479 using Dur = duration<float>;
2480 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2481 Dur mean = sum / v.size();
2484 float delta = (d - mean).count();
2485 accum += delta * delta;
2488 return Dur(sqrtf(accum / (v.size() - 1)));
2494 uint64_t recv_amount,
2495 bool json,
Stream &strm) {
2500 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2504 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2508 uint32_t result_idx = 0;
2510 std::vector<duration<float>> packet_times;
2512 for (send_size = 0; send_size <= max_send;
2513 send_size ? send_size *= 2 : send_size = 4) {
2514 for (uint32_t recv_size = 0; recv_size <= max_recv;
2515 recv_size ? recv_size *= 2 : recv_size = 4) {
2518 packet_times.clear();
2520 const auto start_time = steady_clock::now();
2521 for (uint32_t i = 0; i < num_packets; ++i) {
2522 const auto packet_start_time = steady_clock::now();
2525 const auto packet_end_time = steady_clock::now();
2526 packet_times.push_back(packet_end_time - packet_start_time);
2528 const auto end_time = steady_clock::now();
2529 const auto total_time = end_time - start_time;
2531 float packets_per_second =
2532 ((float)num_packets) / duration<float>(total_time).count();
2533 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2534 : duration<float>::zero();
2535 const duration<float> standard_deviation =
2538 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2539 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2540 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2541 result_idx > 0 ?
"," :
"", send_size, recv_size,
2542 total_time, standard_deviation);
2545 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2546 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2547 "standard deviation of {5,10:ms+f6}\n",
2548 send_size, recv_size, duration<float>(total_time),
2549 packets_per_second, duration<float>(average_per_packet),
2550 standard_deviation);
2556 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2558 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2559 ": %" PRIu64
",\n \"results\" : [",
2562 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2568 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2573 if (recv_size > 0) {
2574 const auto start_time = steady_clock::now();
2575 uint32_t bytes_read = 0;
2576 uint32_t packet_count = 0;
2577 while (bytes_read < recv_amount) {
2580 bytes_read += recv_size;
2583 const auto end_time = steady_clock::now();
2584 const auto total_time = end_time - start_time;
2585 float mb_second = ((float)recv_amount) /
2586 duration<float>(total_time).count() /
2588 float packets_per_second =
2589 ((float)packet_count) / duration<float>(total_time).count();
2590 const auto average_per_packet = packet_count > 0
2591 ? total_time / packet_count
2592 : duration<float>::zero();
2595 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2596 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2597 result_idx > 0 ?
"," :
"", send_size, recv_size,
2601 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2602 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2603 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2604 send_size, recv_size, packet_count, k_recv_amount_mb,
2605 duration<float>(total_time), mb_second,
2606 packets_per_second, duration<float>(average_per_packet));
2612 strm.
Printf(
"\n ]\n }\n}\n");
2619 uint32_t recv_size) {
2621 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2622 uint32_t bytes_left = send_size;
2623 while (bytes_left > 0) {
2624 if (bytes_left >= 26) {
2625 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2628 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2629 "abcdefghijklmnopqrstuvwxyz");
2640 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2641 std::string &socket_name) {
2644 socket_name.clear();
2649 std::string hostname;
2650 if (remote_accept_hostname && remote_accept_hostname[0])
2651 hostname = remote_accept_hostname;
2653 if (HostInfo::GetHostname(hostname)) {
2655 stream.
Printf(
"host:%s;", hostname.c_str());
2659 stream.
Printf(
"host:*;");
2670 llvm::StringRef name;
2671 llvm::StringRef value;
2674 value.getAsInteger(0, port);
2675 else if (name ==
"pid")
2676 value.getAsInteger(0, pid);
2677 else if (name.compare(
"socket_name") == 0) {
2688 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2689 connection_urls.clear();
2705 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2706 std::optional<StructuredData::Dictionary *> maybe_element =
2715 port = port_osp->GetUnsignedIntegerValue(0);
2717 std::string socket_name;
2720 socket_name = std::string(socket_name_osp->GetStringValue());
2722 if (port != 0 || !socket_name.empty())
2723 connection_urls.emplace_back(port, socket_name);
2725 return connection_urls.size();
2730 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2742 uint64_t tid, uint64_t pid,
char op) {
2748 packet.
Printf(
"p%" PRIx64
".", pid);
2753 packet.
Printf(
"%" PRIx64, tid);
2759 return {{pid, tid}};
2771 return std::nullopt;
2786 return ret.has_value();
2801 return ret.has_value();
2816 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2817 assert(packet_len < (
int)
sizeof(packet));
2836 std::chrono::seconds timeout) {
2838 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2839 __FUNCTION__, insert ?
"add" :
"remove", addr);
2846 const int packet_len =
2847 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2848 insert ?
'Z' :
'z', type, addr, length);
2850 assert(packet_len + 1 < (
int)
sizeof(packet));
2895std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2897 bool &sequence_mutex_unavailable) {
2898 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2902 sequence_mutex_unavailable =
false;
2906 for (packet_result =
2924 ids.push_back(*pid_tid);
2926 }
while (ch ==
',');
2940 ids.emplace_back(1, 1);
2944 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
2945 "packet 'qfThreadInfo'");
2946 sequence_mutex_unavailable =
true;
2953 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
2958 if (ids.empty() || sequence_mutex_unavailable)
2961 for (
auto id : ids) {
2967 thread_ids.push_back(
id.second);
2970 return thread_ids.size();
2983 llvm::StringRef command,
2991 std::string *separated_error_output,
3001 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3005 std::string path{working_dir.
GetPath(
false)};
3012 if (response.
GetChar() !=
'F')
3014 if (response.
GetChar() !=
',')
3019 else if (status_ptr)
3020 *status_ptr = exitcode;
3021 if (response.
GetChar() !=
',')
3026 if (response.
GetChar() !=
',')
3031 command_output->assign(output);
3038 uint32_t file_permissions) {
3039 std::string path{file_spec.
GetPath(
false)};
3045 llvm::StringRef packet = stream.
GetString();
3050 packet.str().c_str());
3052 if (response.
GetChar() !=
'F')
3054 packet.str().c_str());
3061 uint32_t file_permissions) {
3062 std::string path{file_spec.
GetPath(
false)};
3068 llvm::StringRef packet = stream.
GetString();
3075 if (response.
GetChar() !=
'F')
3084#define HANDLE_ERRNO(name, value) \
3087#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3096 if (response.
GetChar() !=
'F')
3098 int32_t result = response.
GetS32(-2, 16);
3101 if (response.
GetChar() ==
',') {
3103 if (result_errno != -1)
3115 std::string path(file_spec.
GetPath(
false));
3136 stream.
Printf(
"vFile:close:%x", (
int)fd);
3145std::optional<GDBRemoteFStatData>
3148 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3152 if (response.
GetChar() !=
'F')
3153 return std::nullopt;
3154 int64_t size = response.
GetS64(-1, 16);
3155 if (size > 0 && response.
GetChar() ==
';') {
3159 if (buffer.size() !=
sizeof(out))
3160 return std::nullopt;
3161 memcpy(&out, buffer.data(),
sizeof(out));
3166 return std::nullopt;
3169std::optional<GDBRemoteFStatData>
3174 return std::nullopt;
3175 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3184 std::string path(file_spec.
GetPath(
false));
3194 if (response.
GetChar() !=
'F')
3203 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3221 while (response.
Peek()) {
3223 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3226 if (response.
GetChar() !=
',')
3234 uint32_t &file_permissions) {
3236 std::string path{file_spec.
GetPath(
false)};
3249 if (response.
GetChar() !=
'F') {
3251 "invalid response to '%s' packet", stream.
GetData());
3253 const uint32_t mode = response.
GetS32(-1, 16);
3254 if (
static_cast<int32_t
>(mode) == -1) {
3255 if (response.
GetChar() ==
',') {
3257 if (response_errno > 0)
3274 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3282 uint64_t offset,
void *dst,
3286 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3291 if (response.
GetChar() !=
'F')
3293 int64_t retcode = response.
GetS64(-1, 16);
3294 if (retcode == -1) {
3296 if (response.
GetChar() ==
',') {
3298 if (response_errno > 0)
3303 const char next = (response.
Peek() ? *response.
Peek() : 0);
3310 const uint64_t data_to_write =
3311 std::min<uint64_t>(dst_len, buffer.size());
3312 if (data_to_write > 0)
3313 memcpy(dst, &buffer[0], data_to_write);
3314 return data_to_write;
3327 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3332 if (response.
GetChar() !=
'F') {
3336 int64_t bytes_written = response.
GetS64(-1, 16);
3337 if (bytes_written == -1) {
3339 if (response.
GetChar() ==
',') {
3341 if (response_errno > 0)
3346 return bytes_written;
3355 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3367 if (response.
GetChar() ==
'F') {
3371 if (response.
GetChar() ==
',') {
3373 if (response_errno > 0)
3388 std::string path{file_spec.
GetPath(
false)};
3398 if (response.
GetChar() ==
'F') {
3402 if (response.
GetChar() ==
',') {
3404 if (response_errno > 0)
3422 std::string path(file_spec.
GetPath(
false));
3431 if (response.
GetChar() !=
'F')
3433 if (response.
GetChar() !=
',')
3435 bool retcode = (response.
GetChar() !=
'0');
3452 std::string path(file_spec.
GetPath(
false));
3459 if (response.
GetChar() !=
'F')
3460 return std::make_error_code(std::errc::illegal_byte_sequence);
3461 if (response.
GetChar() !=
',')
3462 return std::make_error_code(std::errc::illegal_byte_sequence);
3463 if (response.
Peek() && *response.
Peek() ==
'x')
3464 return std::make_error_code(std::errc::no_such_file_or_directory);
3481 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3486 if (part.size() != MD5_HALF_LENGTH)
3487 return std::make_error_code(std::errc::illegal_byte_sequence);
3491 if (part.getAsInteger(16, low))
3492 return std::make_error_code(std::errc::illegal_byte_sequence);
3497 if (part.size() != MD5_HALF_LENGTH)
3498 return std::make_error_code(std::errc::illegal_byte_sequence);
3502 if (part.getAsInteger(16, high))
3503 return std::make_error_code(std::errc::illegal_byte_sequence);
3505 llvm::MD5::MD5Result result;
3506 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3507 result.data(), low);
3508 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3509 result.data() + 8, high);
3513 return std::make_error_code(std::errc::operation_canceled);
3523 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3524 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3525 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3526 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3529 if (gdb_server_version != 0) {
3531 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3532 if (gdb_server_version >= 310)
3545 payload.
Printf(
"p%x", reg);
3554 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3569 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3575 llvm::ArrayRef<uint8_t> data) {
3577 payload.
Printf(
"P%x=", reg_num);
3601 uint32_t &save_id) {
3617 const uint32_t response_save_id = response.
GetU32(0);
3618 if (response_save_id == 0)
3621 save_id = response_save_id;
3634 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3654 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3660llvm::Expected<TraceSupportedResponse>
3665 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3674 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3675 "jLLDBTraceSupported is unsupported");
3677 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3678 "TraceSupportedResponse");
3680 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3681 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3682 "failed to send packet: jLLDBTraceSupported");
3687 std::chrono::seconds timeout) {
3691 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3693 std::string json_string;
3694 llvm::raw_string_ostream os(json_string);
3697 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3706 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3707 "jLLDBTraceStop is unsupported");
3709 return llvm::Error::success();
3710 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3711 "Invalid jLLDBTraceStart response");
3713 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3714 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3715 "failed to send packet: jLLDBTraceStop '%s'",
3721 std::chrono::seconds timeout) {
3725 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3727 std::string json_string;
3728 llvm::raw_string_ostream os(json_string);
3731 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3740 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3741 "jLLDBTraceStart is unsupported");
3743 return llvm::Error::success();
3744 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3745 "Invalid jLLDBTraceStart response");
3747 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3748 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3749 "failed to send packet: jLLDBTraceStart '%s'",
3753llvm::Expected<std::string>
3755 std::chrono::seconds timeout) {
3759 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3761 std::string json_string;
3762 llvm::raw_string_ostream os(json_string);
3765 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3774 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3775 "jLLDBTraceGetState is unsupported");
3776 return std::string(response.
Peek());
3779 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3780 return llvm::createStringError(
3781 llvm::inconvertibleErrorCode(),
3782 "failed to send packet: jLLDBTraceGetState '%s'",
3786llvm::Expected<std::vector<uint8_t>>
3792 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3794 std::string json_string;
3795 llvm::raw_string_ostream os(json_string);
3798 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3808 return std::vector<uint8_t>(data.begin(), data.end());
3810 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3811 return llvm::createStringError(
3812 llvm::inconvertibleErrorCode(),
3813 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3821 return std::nullopt;
3823 return std::nullopt;
3827 const auto &GetOffset = [&] {
3829 if (ref.consumeInteger(16, offset))
3831 result.
offsets.push_back(offset);
3835 if (ref.consume_front(
"Text=")) {
3838 return std::nullopt;
3839 if (!ref.consume_front(
";Data=") || !GetOffset())
3840 return std::nullopt;
3843 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3845 }
else if (ref.consume_front(
"TextSeg=")) {
3848 return std::nullopt;
3851 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3854 return std::nullopt;
3863 std::string module_path = module_file_spec.
GetPath(
false);
3864 if (module_path.empty())
3871 const auto &triple = arch_spec.
GetTriple().getTriple();
3887 llvm::StringRef name;
3888 llvm::StringRef value;
3890 module_spec.
Clear();
3894 if (name ==
"uuid" || name ==
"md5") {
3899 }
else if (name ==
"triple") {
3904 }
else if (name ==
"file_offset") {
3906 if (!value.getAsInteger(16, ival))
3908 }
else if (name ==
"file_size") {
3910 if (!value.getAsInteger(16, ival))
3912 }
else if (name ==
"file_path") {
3923static std::optional<ModuleSpec>
3927 return std::nullopt;
3929 llvm::StringRef string;
3933 return std::nullopt;
3935 return std::nullopt;
3938 return std::nullopt;
3942 return std::nullopt;
3946 return std::nullopt;
3950 return std::nullopt;
3956std::optional<std::vector<ModuleSpec>>
3958 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
3962 return std::nullopt;
3964 json::Array module_array;
3965 for (
const FileSpec &module_file_spec : module_file_specs) {
3966 module_array.push_back(
3967 json::Object{{
"file", module_file_spec.GetPath(
false)},
3968 {
"triple", triple.getTriple()}});
3971 unescaped_payload.
PutCString(
"jModulesInfo:");
3972 unescaped_payload.
AsRawOstream() << std::move(module_array);
3985 return std::nullopt;
3989 return std::nullopt;
3994 if (!response_object_sp)
3995 return std::nullopt;
3998 if (!response_array)
3999 return std::nullopt;
4001 std::vector<ModuleSpec> result;
4002 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
4005 result.push_back(*module_spec);
4015llvm::Expected<std::string>
4017 llvm::StringRef annex) {
4020 llvm::raw_string_ostream output_stream(output);
4034 std::string packet =
4035 (
"qXfer:" +
object +
":read:" + annex +
":" +
4036 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4044 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4045 "Error sending $qXfer packet");
4063 return llvm::createStringError(
4064 llvm::inconvertibleErrorCode(),
4065 "Invalid continuation code from $qXfer packet");
4115 bool symbol_response_provided =
false;
4118 bool first_qsymbol_query =
true;
4129 if (symbol_response_provided || first_qsymbol_query) {
4136 first_qsymbol_query =
false;
4145 if (response_str.starts_with(
"qSymbol:")) {
4147 std::string symbol_name;
4149 if (symbol_name.empty())
4160 switch (sc.symbol->GetType()) {
4193 sc.symbol->GetLoadAddress(&process->
GetTarget());
4206 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4207 symbol_response_provided =
true;
4209 symbol_response_provided =
false;
4225 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4250 "GDBRemoteCommunicationClient::%s(): "
4251 "QSupportedAsyncJSONPackets returned invalid "
4258 "GDBRemoteCommunicationClient::%s(): "
4259 "QSupportedAsyncJSONPackets unsupported",
4267 "GDBRemoteCommunicationClient::%s(): supported async "
4269 __FUNCTION__, stream.
GetData());
4279 llvm::ArrayRef<int32_t> signals) {
4282 auto range = llvm::make_range(signals.begin(), signals.end());
4283 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4295 "Unknown error happened during sending QPassSignals packet.");
4303 if (type_name.empty()) {
4316 config_sp->Dump(unescaped_stream);
4317 unescaped_stream.
Flush();
4335 "configuring StructuredData feature {0} failed with error {1}",
4341 "configuring StructuredData feature {0} failed when sending packet: "
4343 type_name, (
int)result);
4372 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4373 "failed to send k packet");
4375 char packet_cmd = response.
GetChar(0);
4376 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4379 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4380 "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_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.