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 defined(HAVE_LIBCOMPRESSION)
45#include <compression.h>
51using namespace std::chrono;
55 return os << llvm::formatv(
56 "QOffsets({0}, [{1:@[x]}])", offsets.
segments,
64 m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
65 m_supports_qUserName(true), m_supports_qGroupName(true),
66 m_supports_qThreadStopInfo(true), m_supports_z0(true),
67 m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
68 m_supports_z4(true), m_supports_QEnvironment(true),
69 m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
70 m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
71 m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
72 m_supports_vFileSize(true), m_supports_vFileMode(true),
73 m_supports_vFileExists(true), m_supports_vRun(true),
75 m_host_arch(), m_host_distribution_id(), m_process_arch(), m_os_build(),
76 m_os_kernel(), m_hostname(), m_gdb_server_name(),
77 m_default_packet_timeout(0), m_qSupported_response(),
78 m_supported_async_json_packets_sp(), m_qXfer_memory_map() {}
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 "
356 std::vector<std::string> features = {
"xmlRegisters=i386,arm,mips,arc",
364 for (uint32_t i = 0; i < features.size(); ++i) {
376 for (llvm::StringRef x : llvm::split(response.
GetStringRef(),
';')) {
377 if (x ==
"qXfer:auxv:read+")
379 else if (x ==
"qXfer:libraries-svr4:read+")
381 else if (x ==
"augmented-libraries-svr4-read") {
384 }
else if (x ==
"qXfer:libraries:read+")
386 else if (x ==
"qXfer:features:read+")
388 else if (x ==
"qXfer:memory-map:read+")
390 else if (x ==
"qXfer:siginfo:read+")
392 else if (x ==
"qEcho")
394 else if (x ==
"QPassSignals+")
396 else if (x ==
"multiprocess+")
398 else if (x ==
"memory-tagging+")
400 else if (x ==
"qSaveCore+")
402 else if (x ==
"native-signals+")
407 else if (x.consume_front(
"SupportedCompressions=")) {
408 llvm::SmallVector<llvm::StringRef, 4> compressions;
409 x.split(compressions,
',');
410 if (!compressions.empty())
412 }
else if (x.consume_front(
"SupportedWatchpointTypes=")) {
413 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
414 x.split(watchpoint_types,
',');
416 for (
auto wp_type : watchpoint_types) {
417 if (wp_type ==
"x86_64")
419 if (wp_type ==
"aarch64-mask")
421 if (wp_type ==
"aarch64-bas")
424 }
else if (x.consume_front(
"PacketSize=")) {
431 LLDB_LOGF(log,
"Garbled PacketSize spec in qSupported response");
461 const char *response_cstr = response.
GetStringRef().data();
462 if (::strstr(response_cstr,
";c"))
465 if (::strstr(response_cstr,
";C"))
468 if (::strstr(response_cstr,
";s"))
471 if (::strstr(response_cstr,
";S"))
517 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
519 __FUNCTION__, payload.GetData());
524 payload.Printf(
";thread:%4.4" PRIx64
";", tid);
571 }
else if (!response.
Empty()) {
660 packet.
Printf(
"qMemTags:%" PRIx64
",%zx:%" PRIx32, addr, len, type);
668 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s: qMemTags packet failed",
676 if (response.
GetChar() !=
'm') {
678 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
689 if (response.
GetBytesLeft() || (expected_bytes != got_bytes)) {
692 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
702 const std::vector<uint8_t> &tags) {
705 packet.
Printf(
"QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr, len, type);
723 snprintf(packet,
sizeof(packet),
"x0,0");
750 if (response.
GetChar() ==
'Q') {
751 if (response.
GetChar() ==
'C') {
765 bool sequence_mutex_unavailable;
767 if (!ids.empty() && !sequence_mutex_unavailable) {
784 return llvm::createStringError(llvm::inconvertibleErrorCode(),
785 "Nothing to launch");
798 return llvm::createStringError(llvm::inconvertibleErrorCode(),
799 "Sending vRun packet failed");
808 return llvm::Error::success();
816 llvm::ListSeparator LS(
",");
817 for (
const auto &arg : llvm::enumerate(args)) {
819 packet.
Format(
"{0},{1},", arg.value().ref().size() * 2, arg.index());
826 return llvm::createStringError(llvm::inconvertibleErrorCode(),
827 "Sending A packet failed");
834 return llvm::createStringError(llvm::inconvertibleErrorCode(),
835 "Sending qLaunchSuccess packet failed");
838 return llvm::Error::success();
839 if (response.
GetChar() ==
'E') {
840 return llvm::createStringError(llvm::inconvertibleErrorCode(),
843 return llvm::createStringError(llvm::inconvertibleErrorCode(),
844 "unknown error occurred launching process");
848 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
849 for (
const auto &kv : env)
850 vec.emplace_back(kv.first(), kv.second);
851 llvm::sort(vec, llvm::less_first());
852 for (
const auto &[k, v] : vec) {
861 char const *name_equal_value) {
862 if (name_equal_value && name_equal_value[0]) {
863 bool send_hex_encoding =
false;
864 for (
const char *p = name_equal_value; *p !=
'\0' && !send_hex_encoding;
866 if (llvm::isPrint(*p)) {
872 send_hex_encoding =
true;
879 send_hex_encoding =
true;
887 packet.
Printf(
"QEnvironment:%s", name_equal_value);
928 if (arch && arch[0]) {
930 packet.
Printf(
"QLaunchArch:%s", arch);
945 char const *data,
bool *was_supported) {
946 if (data && *data !=
'\0') {
948 packet.
Printf(
"QSetProcessEvent:%s", data);
954 *was_supported =
true;
958 *was_supported =
false;
963 *was_supported =
true;
990std::optional<std::string>
1024 UUID &uuid,
addr_t &value,
bool &value_is_offset) {
1057 llvm::StringRef name, value;
1058 bool success =
false;
1060 if (name ==
"name") {
1063 }
else if (name ==
"version") {
1064 llvm::StringRef major, minor;
1065 std::tie(major, minor) = value.split(
'.');
1079 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1081 llvm::StringRef avail_name;
1083#if defined(HAVE_LIBCOMPRESSION)
1085 for (
auto compression : supported_compressions) {
1086 if (compression ==
"lzfse") {
1088 avail_name = compression;
1095#if defined(HAVE_LIBCOMPRESSION)
1097 for (
auto compression : supported_compressions) {
1098 if (compression ==
"zlib-deflate") {
1100 avail_name = compression;
1109 for (
auto compression : supported_compressions) {
1110 if (compression ==
"zlib-deflate") {
1112 avail_name = compression;
1119#if defined(HAVE_LIBCOMPRESSION)
1121 for (
auto compression : supported_compressions) {
1122 if (compression ==
"lz4") {
1124 avail_name = compression;
1131#if defined(HAVE_LIBCOMPRESSION)
1133 for (
auto compression : supported_compressions) {
1134 if (compression ==
"lzma") {
1136 avail_name = compression;
1145 std::string packet =
"QEnableCompression:type:" + avail_name.str() +
";";
1192 tid = pid_tid->second;
1199 std::string &environment) {
1200 if (value ==
"iossimulator" || value ==
"tvossimulator" ||
1201 value ==
"watchossimulator" || value ==
"xrossimulator" ||
1202 value ==
"visionossimulator") {
1203 environment =
"simulator";
1204 os_name = value.drop_back(environment.size()).str();
1205 }
else if (value ==
"maccatalyst") {
1207 environment =
"macabi";
1209 os_name = value.str();
1225 llvm::StringRef name;
1226 llvm::StringRef value;
1229 std::string arch_name;
1230 std::string os_name;
1231 std::string environment;
1232 std::string vendor_name;
1234 uint32_t pointer_byte_size = 0;
1236 uint32_t num_keys_decoded = 0;
1238 if (name ==
"cputype") {
1240 if (!value.getAsInteger(0, cpu))
1242 }
else if (name ==
"cpusubtype") {
1244 if (!value.getAsInteger(0, sub))
1246 }
else if (name ==
"arch") {
1247 arch_name = std::string(value);
1249 }
else if (name ==
"triple") {
1253 }
else if (name ==
"distribution_id") {
1257 }
else if (name ==
"os_build") {
1261 }
else if (name ==
"hostname") {
1265 }
else if (name ==
"os_kernel") {
1269 }
else if (name ==
"ostype") {
1272 }
else if (name ==
"vendor") {
1273 vendor_name = std::string(value);
1275 }
else if (name ==
"endian") {
1276 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1283 }
else if (name ==
"ptrsize") {
1284 if (!value.getAsInteger(0, pointer_byte_size))
1286 }
else if (name ==
"addressing_bits") {
1290 }
else if (name ==
"high_mem_addressing_bits") {
1293 }
else if (name ==
"low_mem_addressing_bits") {
1296 }
else if (name ==
"os_version" ||
1303 }
else if (name ==
"maccatalyst_version") {
1306 }
else if (name ==
"watchpoint_exceptions_received") {
1308 llvm::StringSwitch<LazyBool>(value)
1314 }
else if (name ==
"default_packet_timeout") {
1315 uint32_t timeout_seconds;
1316 if (!value.getAsInteger(0, timeout_seconds)) {
1321 }
else if (name ==
"vm-page-size") {
1323 if (!value.getAsInteger(0, page_size)) {
1330 if (num_keys_decoded > 0)
1333 if (triple.empty()) {
1334 if (arch_name.empty()) {
1337 if (pointer_byte_size) {
1344 if (!vendor_name.empty())
1346 llvm::StringRef(vendor_name));
1347 if (!os_name.empty())
1349 if (!environment.empty())
1354 triple += arch_name;
1355 if (!vendor_name.empty() || !os_name.empty()) {
1357 if (vendor_name.empty())
1358 triple +=
"unknown";
1360 triple += vendor_name;
1362 if (os_name.empty())
1363 triple +=
"unknown";
1370 if (host_triple.getVendor() == llvm::Triple::Apple &&
1371 host_triple.getOS() == llvm::Triple::Darwin) {
1373 case llvm::Triple::aarch64:
1374 case llvm::Triple::aarch64_32:
1375 case llvm::Triple::arm:
1376 case llvm::Triple::thumb:
1377 host_triple.setOS(llvm::Triple::IOS);
1380 host_triple.setOS(llvm::Triple::MacOSX);
1384 if (pointer_byte_size) {
1393 if (pointer_byte_size) {
1401 "GDBRemoteCommunicationClient::%s parsed host "
1402 "architecture as %s, triple as %s from triple text %s",
1406 :
"<null-arch-name>",
1446 return addressable_bits;
1456 uint32_t permissions) {
1460 const int packet_len = ::snprintf(
1461 packet,
sizeof(packet),
"_M%" PRIx64
",%s%s%s", (uint64_t)size,
1462 permissions & lldb::ePermissionsReadable ?
"r" :
"",
1463 permissions & lldb::ePermissionsWritable ?
"w" :
"",
1464 permissions & lldb::ePermissionsExecutable ?
"x" :
"");
1465 assert(packet_len < (
int)
sizeof(packet));
1485 const int packet_len =
1486 ::snprintf(packet,
sizeof(packet),
"_m%" PRIx64, (uint64_t)addr);
1487 assert(packet_len < (
int)
sizeof(packet));
1512 const int packet_len =
1513 ::snprintf(packet,
sizeof(packet),
"qSupportsDetachAndStayStopped:");
1514 assert(packet_len < (
int)
sizeof(packet));
1528 "Stays stopped not supported by this target.");
1544 "Multiprocess extension not supported by the server.");
1559 region_info.
Clear();
1564 const int packet_len = ::snprintf(
1565 packet,
sizeof(packet),
"qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1566 assert(packet_len < (
int)
sizeof(packet));
1572 llvm::StringRef name;
1573 llvm::StringRef value;
1575 bool success =
true;
1576 bool saw_permissions =
false;
1578 if (name ==
"start") {
1579 if (!value.getAsInteger(16, addr_value))
1581 }
else if (name ==
"size") {
1582 if (!value.getAsInteger(16, addr_value)) {
1590 }
else if (name ==
"permissions" && region_info.
GetRange().
IsValid()) {
1591 saw_permissions =
true;
1593 if (value.contains(
'r'))
1598 if (value.contains(
'w'))
1603 if (value.contains(
'x'))
1617 }
else if (name ==
"name") {
1621 region_info.
SetName(name.c_str());
1622 }
else if (name ==
"flags") {
1626 llvm::StringRef flags = value;
1627 llvm::StringRef flag;
1628 while (flags.size()) {
1629 flags = flags.ltrim();
1630 std::tie(flag, flags) = flags.split(
' ');
1635 else if (flag ==
"ss")
1639 }
else if (name ==
"type") {
1640 for (llvm::StringRef entry : llvm::split(value,
',')) {
1641 if (entry ==
"stack")
1643 else if (entry ==
"heap")
1646 }
else if (name ==
"error") {
1648 std::string error_string;
1652 }
else if (name ==
"dirty-pages") {
1653 std::vector<addr_t> dirty_page_list;
1654 for (llvm::StringRef x : llvm::split(value,
',')) {
1656 x.consume_front(
"0x");
1657 if (llvm::to_integer(x, page, 16))
1658 dirty_page_list.push_back(page);
1670 if (!saw_permissions) {
1698 region_info = qXfer_region_info;
1701 region_info.
Clear();
1703 }
else if (qXfer_error.
Success()) {
1718 if (!
error.Success())
1721 if (map_region.GetRange().Contains(addr)) {
1722 region = map_region;
1748 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1754 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1770 if (memory_node.
GetName() !=
"memory")
1781 region.GetRange().SetByteSize(length);
1782 if (type ==
"rom") {
1785 }
else if (type ==
"ram") {
1789 }
else if (type ==
"flash") {
1792 [®ion](
const XMLNode &prop_node) ->
bool {
1795 if (prop_node.
GetName() !=
"property")
1798 if (propname ==
"blocksize") {
1801 region.SetBlocksize(blocksize);
1820 std::optional<uint32_t> num;
1826 llvm::StringRef name;
1827 llvm::StringRef value;
1829 if (name ==
"num") {
1845WatchpointHardwareFeature
1864 return std::nullopt;
1869 std::string path{file_spec.
GetPath(
false)};
1889 std::string path{file_spec.
GetPath(
false)};
1909 std::string path{file_spec.
GetPath(
false)};
1938 return !cwd.empty();
1945 std::string path{working_dir.
GetPath(
false)};
1965 const int packet_len =
1966 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
1967 assert(packet_len < (
int)
sizeof(packet));
1982 const int packet_len = ::snprintf(packet,
sizeof(packet),
1983 "QSetDetachOnError:%i", enable ? 1 : 0);
1984 assert(packet_len < (
int)
sizeof(packet));
2000 llvm::StringRef name;
2001 llvm::StringRef value;
2007 std::string os_type;
2010 if (name ==
"pid") {
2012 value.getAsInteger(0, pid);
2014 }
else if (name ==
"ppid") {
2016 value.getAsInteger(0, pid);
2018 }
else if (name ==
"uid") {
2020 value.getAsInteger(0, uid);
2022 }
else if (name ==
"euid") {
2024 value.getAsInteger(0, uid);
2026 }
else if (name ==
"gid") {
2028 value.getAsInteger(0, gid);
2030 }
else if (name ==
"egid") {
2032 value.getAsInteger(0, gid);
2034 }
else if (name ==
"triple") {
2039 }
else if (name ==
"name") {
2046 }
else if (name ==
"args") {
2047 llvm::StringRef encoded_args(value), hex_arg;
2049 bool is_arg0 =
true;
2050 while (!encoded_args.empty()) {
2051 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2066 }
else if (name ==
"cputype") {
2067 value.getAsInteger(0, cpu);
2068 }
else if (name ==
"cpusubtype") {
2069 value.getAsInteger(0, sub);
2070 }
else if (name ==
"vendor") {
2071 vendor = std::string(value);
2072 }
else if (name ==
"ostype") {
2073 os_type = std::string(value);
2078 if (vendor ==
"apple") {
2082 llvm::StringRef(vendor));
2084 llvm::StringRef(os_type));
2096 process_info.
Clear();
2100 const int packet_len =
2101 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2102 assert(packet_len < (
int)
sizeof(packet));
2132 llvm::StringRef name;
2133 llvm::StringRef value;
2136 std::string arch_name;
2137 std::string os_name;
2138 std::string environment;
2139 std::string vendor_name;
2141 std::string elf_abi;
2142 uint32_t pointer_byte_size = 0;
2145 uint32_t num_keys_decoded = 0;
2148 if (name ==
"cputype") {
2149 if (!value.getAsInteger(16, cpu))
2151 }
else if (name ==
"cpusubtype") {
2152 if (!value.getAsInteger(16, sub)) {
2158 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2159 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2166 }
else if (name ==
"triple") {
2170 }
else if (name ==
"ostype") {
2173 }
else if (name ==
"vendor") {
2174 vendor_name = std::string(value);
2176 }
else if (name ==
"endian") {
2177 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2184 }
else if (name ==
"ptrsize") {
2185 if (!value.getAsInteger(16, pointer_byte_size))
2187 }
else if (name ==
"pid") {
2188 if (!value.getAsInteger(16, pid))
2190 }
else if (name ==
"elf_abi") {
2191 elf_abi = std::string(value);
2193 }
else if (name ==
"main-binary-uuid") {
2196 }
else if (name ==
"main-binary-slide") {
2204 }
else if (name ==
"main-binary-address") {
2212 }
else if (name ==
"binary-addresses") {
2215 for (llvm::StringRef x : llvm::split(value,
',')) {
2217 x.consume_front(
"0x");
2218 if (llvm::to_integer(x, vmaddr, 16))
2223 if (num_keys_decoded > 0)
2231 if (!triple.empty()) {
2234 if (pointer_byte_size) {
2238 !vendor_name.empty()) {
2239 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2240 if (!environment.empty())
2241 triple.setEnvironmentName(environment);
2243 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2244 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2245 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2246 switch (triple.getObjectFormat()) {
2247 case llvm::Triple::MachO:
2250 case llvm::Triple::ELF:
2253 case llvm::Triple::COFF:
2256 case llvm::Triple::GOFF:
2257 case llvm::Triple::SPIRV:
2258 case llvm::Triple::Wasm:
2259 case llvm::Triple::XCOFF:
2260 case llvm::Triple::DXContainer:
2261 LLDB_LOGF(log,
"error: not supported target architecture");
2263 case llvm::Triple::UnknownObjectFormat:
2264 LLDB_LOGF(log,
"error: failed to determine target architecture");
2268 if (pointer_byte_size) {
2290 process_infos.clear();
2298 bool has_name_match =
false;
2299 if (name && name[0]) {
2300 has_name_match =
true;
2302 switch (name_match_type) {
2304 has_name_match =
false;
2316 packet.
PutCString(
"name_match:starts_with;");
2327 if (has_name_match) {
2335 packet.
Printf(
"pid:%" PRIu64
";",
2338 packet.
Printf(
"parent_pid:%" PRIu64
";",
2345 packet.
Printf(
"euid:%u;",
2348 packet.
Printf(
"egid:%u;",
2354 const llvm::Triple &triple = match_arch.
GetTriple();
2370 process_infos.push_back(process_info);
2379 return process_infos.size();
2383 std::string &name) {
2386 const int packet_len =
2387 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2388 assert(packet_len < (
int)
sizeof(packet));
2410 std::string &name) {
2413 const int packet_len =
2414 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2415 assert(packet_len < (
int)
sizeof(packet));
2437 uint32_t recv_size) {
2439 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2440 uint32_t bytes_left = send_size;
2441 while (bytes_left > 0) {
2442 if (bytes_left >= 26) {
2443 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2446 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2447 "abcdefghijklmnopqrstuvwxyz");
2456 return duration<float>::zero();
2457 using Dur = duration<float>;
2458 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2459 Dur mean = sum / v.size();
2462 float delta = (d - mean).count();
2463 accum += delta * delta;
2466 return Dur(sqrtf(accum / (v.size() - 1)));
2472 uint64_t recv_amount,
2473 bool json,
Stream &strm) {
2478 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2482 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2486 uint32_t result_idx = 0;
2488 std::vector<duration<float>> packet_times;
2490 for (send_size = 0; send_size <= max_send;
2491 send_size ? send_size *= 2 : send_size = 4) {
2492 for (uint32_t recv_size = 0; recv_size <= max_recv;
2493 recv_size ? recv_size *= 2 : recv_size = 4) {
2496 packet_times.clear();
2498 const auto start_time = steady_clock::now();
2499 for (uint32_t i = 0; i < num_packets; ++i) {
2500 const auto packet_start_time = steady_clock::now();
2503 const auto packet_end_time = steady_clock::now();
2504 packet_times.push_back(packet_end_time - packet_start_time);
2506 const auto end_time = steady_clock::now();
2507 const auto total_time = end_time - start_time;
2509 float packets_per_second =
2510 ((float)num_packets) / duration<float>(total_time).count();
2511 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2512 : duration<float>::zero();
2513 const duration<float> standard_deviation =
2516 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2517 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2518 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2519 result_idx > 0 ?
"," :
"", send_size, recv_size,
2520 total_time, standard_deviation);
2523 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2524 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2525 "standard deviation of {5,10:ms+f6}\n",
2526 send_size, recv_size, duration<float>(total_time),
2527 packets_per_second, duration<float>(average_per_packet),
2528 standard_deviation);
2534 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2536 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2537 ": %" PRIu64
",\n \"results\" : [",
2540 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2546 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2551 if (recv_size > 0) {
2552 const auto start_time = steady_clock::now();
2553 uint32_t bytes_read = 0;
2554 uint32_t packet_count = 0;
2555 while (bytes_read < recv_amount) {
2558 bytes_read += recv_size;
2561 const auto end_time = steady_clock::now();
2562 const auto total_time = end_time - start_time;
2563 float mb_second = ((float)recv_amount) /
2564 duration<float>(total_time).count() /
2566 float packets_per_second =
2567 ((float)packet_count) / duration<float>(total_time).count();
2568 const auto average_per_packet = packet_count > 0
2569 ? total_time / packet_count
2570 : duration<float>::zero();
2573 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2574 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2575 result_idx > 0 ?
"," :
"", send_size, recv_size,
2579 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2580 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2581 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2582 send_size, recv_size, packet_count, k_recv_amount_mb,
2583 duration<float>(total_time), mb_second,
2584 packets_per_second, duration<float>(average_per_packet));
2590 strm.
Printf(
"\n ]\n }\n}\n");
2597 uint32_t recv_size) {
2599 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2600 uint32_t bytes_left = send_size;
2601 while (bytes_left > 0) {
2602 if (bytes_left >= 26) {
2603 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2606 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2607 "abcdefghijklmnopqrstuvwxyz");
2618 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2619 std::string &socket_name) {
2622 socket_name.clear();
2627 std::string hostname;
2628 if (remote_accept_hostname && remote_accept_hostname[0])
2629 hostname = remote_accept_hostname;
2631 if (HostInfo::GetHostname(hostname)) {
2633 stream.
Printf(
"host:%s;", hostname.c_str());
2637 stream.
Printf(
"host:*;");
2648 llvm::StringRef name;
2649 llvm::StringRef value;
2652 value.getAsInteger(0, port);
2653 else if (name ==
"pid")
2654 value.getAsInteger(0, pid);
2655 else if (name.compare(
"socket_name") == 0) {
2666 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2667 connection_urls.clear();
2683 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2684 std::optional<StructuredData::Dictionary *> maybe_element =
2695 std::string socket_name;
2698 socket_name = std::string(socket_name_osp->GetStringValue());
2700 if (port != 0 || !socket_name.empty())
2701 connection_urls.emplace_back(port, socket_name);
2703 return connection_urls.size();
2708 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2720 uint64_t tid, uint64_t pid,
char op) {
2726 packet.
Printf(
"p%" PRIx64
".", pid);
2731 packet.
Printf(
"%" PRIx64, tid);
2737 return {{pid, tid}};
2749 return std::nullopt;
2764 return ret.has_value();
2779 return ret.has_value();
2794 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2795 assert(packet_len < (
int)
sizeof(packet));
2814 std::chrono::seconds timeout) {
2816 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2817 __FUNCTION__, insert ?
"add" :
"remove", addr);
2824 const int packet_len =
2825 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2826 insert ?
'Z' :
'z', type, addr, length);
2828 assert(packet_len + 1 < (
int)
sizeof(packet));
2873std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2875 bool &sequence_mutex_unavailable) {
2876 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2880 sequence_mutex_unavailable =
false;
2884 for (packet_result =
2902 ids.push_back(*pid_tid);
2904 }
while (ch ==
',');
2918 ids.emplace_back(1, 1);
2922 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
2923 "packet 'qfThreadInfo'");
2924 sequence_mutex_unavailable =
true;
2931 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
2936 if (ids.empty() || sequence_mutex_unavailable)
2939 for (
auto id : ids) {
2945 thread_ids.push_back(
id.second);
2948 return thread_ids.size();
2961 llvm::StringRef command,
2977 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
2981 std::string path{working_dir.
GetPath(
false)};
2988 if (response.
GetChar() !=
'F')
2990 if (response.
GetChar() !=
',')
2995 else if (status_ptr)
2996 *status_ptr = exitcode;
2997 if (response.
GetChar() !=
',')
3002 if (response.
GetChar() !=
',')
3007 command_output->assign(output);
3014 uint32_t file_permissions) {
3015 std::string path{file_spec.
GetPath(
false)};
3021 llvm::StringRef packet = stream.
GetString();
3026 packet.str().c_str());
3028 if (response.
GetChar() !=
'F')
3030 packet.str().c_str());
3037 uint32_t file_permissions) {
3038 std::string path{file_spec.
GetPath(
false)};
3044 llvm::StringRef packet = stream.
GetString();
3051 if (response.
GetChar() !=
'F')
3060#define HANDLE_ERRNO(name, value) \
3063#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3072 if (response.
GetChar() !=
'F')
3074 int32_t result = response.
GetS32(-2, 16);
3077 if (response.
GetChar() ==
',') {
3079 if (result_errno != -1)
3091 std::string path(file_spec.
GetPath(
false));
3112 stream.
Printf(
"vFile:close:%x", (
int)fd);
3121std::optional<GDBRemoteFStatData>
3124 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3128 if (response.
GetChar() !=
'F')
3129 return std::nullopt;
3130 int64_t size = response.
GetS64(-1, 16);
3131 if (size > 0 && response.
GetChar() ==
';') {
3135 if (buffer.size() !=
sizeof(out))
3136 return std::nullopt;
3137 memcpy(&out, buffer.data(),
sizeof(out));
3142 return std::nullopt;
3145std::optional<GDBRemoteFStatData>
3150 return std::nullopt;
3151 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3160 std::string path(file_spec.
GetPath(
false));
3170 if (response.
GetChar() !=
'F')
3179 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3197 while (response.
Peek()) {
3199 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3202 if (response.
GetChar() !=
',')
3210 uint32_t &file_permissions) {
3212 std::string path{file_spec.
GetPath(
false)};
3225 if (response.
GetChar() !=
'F') {
3227 "invalid response to '%s' packet", stream.
GetData());
3229 const uint32_t mode = response.
GetS32(-1, 16);
3230 if (
static_cast<int32_t
>(mode) == -1) {
3231 if (response.
GetChar() ==
',') {
3233 if (response_errno > 0)
3250 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3258 uint64_t offset,
void *dst,
3262 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3267 if (response.
GetChar() !=
'F')
3269 int64_t retcode = response.
GetS64(-1, 16);
3270 if (retcode == -1) {
3272 if (response.
GetChar() ==
',') {
3274 if (response_errno > 0)
3279 const char next = (response.
Peek() ? *response.
Peek() : 0);
3286 const uint64_t data_to_write =
3287 std::min<uint64_t>(dst_len, buffer.size());
3288 if (data_to_write > 0)
3289 memcpy(dst, &buffer[0], data_to_write);
3290 return data_to_write;
3303 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3308 if (response.
GetChar() !=
'F') {
3312 int64_t bytes_written = response.
GetS64(-1, 16);
3313 if (bytes_written == -1) {
3315 if (response.
GetChar() ==
',') {
3317 if (response_errno > 0)
3322 return bytes_written;
3331 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3343 if (response.
GetChar() ==
'F') {
3347 if (response.
GetChar() ==
',') {
3349 if (response_errno > 0)
3364 std::string path{file_spec.
GetPath(
false)};
3374 if (response.
GetChar() ==
'F') {
3378 if (response.
GetChar() ==
',') {
3380 if (response_errno > 0)
3398 std::string path(file_spec.
GetPath(
false));
3407 if (response.
GetChar() !=
'F')
3409 if (response.
GetChar() !=
',')
3411 bool retcode = (response.
GetChar() !=
'0');
3428 std::string path(file_spec.
GetPath(
false));
3435 if (response.
GetChar() !=
'F')
3436 return std::make_error_code(std::errc::illegal_byte_sequence);
3437 if (response.
GetChar() !=
',')
3438 return std::make_error_code(std::errc::illegal_byte_sequence);
3439 if (response.
Peek() && *response.
Peek() ==
'x')
3440 return std::make_error_code(std::errc::no_such_file_or_directory);
3457 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3462 if (part.size() != MD5_HALF_LENGTH)
3463 return std::make_error_code(std::errc::illegal_byte_sequence);
3467 if (part.getAsInteger(16, low))
3468 return std::make_error_code(std::errc::illegal_byte_sequence);
3473 if (part.size() != MD5_HALF_LENGTH)
3474 return std::make_error_code(std::errc::illegal_byte_sequence);
3478 if (part.getAsInteger(16, high))
3479 return std::make_error_code(std::errc::illegal_byte_sequence);
3481 llvm::MD5::MD5Result result;
3482 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3483 result.data(), low);
3484 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3485 result.data() + 8, high);
3489 return std::make_error_code(std::errc::operation_canceled);
3499 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3500 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3501 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3502 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3505 if (gdb_server_version != 0) {
3507 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3508 if (gdb_server_version >= 310)
3521 payload.
Printf(
"p%x", reg);
3530 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3545 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3551 llvm::ArrayRef<uint8_t> data) {
3553 payload.
Printf(
"P%x=", reg_num);
3577 uint32_t &save_id) {
3593 const uint32_t response_save_id = response.
GetU32(0);
3594 if (response_save_id == 0)
3597 save_id = response_save_id;
3610 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3630 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3636llvm::Expected<TraceSupportedResponse>
3641 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3650 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3651 "jLLDBTraceSupported is unsupported");
3653 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3654 "TraceSupportedResponse");
3656 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3657 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3658 "failed to send packet: jLLDBTraceSupported");
3663 std::chrono::seconds timeout) {
3667 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3669 std::string json_string;
3670 llvm::raw_string_ostream os(json_string);
3673 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3682 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3683 "jLLDBTraceStop is unsupported");
3685 return llvm::Error::success();
3686 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3687 "Invalid jLLDBTraceStart response");
3689 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3690 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3691 "failed to send packet: jLLDBTraceStop '%s'",
3697 std::chrono::seconds timeout) {
3701 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3703 std::string json_string;
3704 llvm::raw_string_ostream os(json_string);
3707 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3716 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3717 "jLLDBTraceStart is unsupported");
3719 return llvm::Error::success();
3720 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3721 "Invalid jLLDBTraceStart response");
3723 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3724 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3725 "failed to send packet: jLLDBTraceStart '%s'",
3729llvm::Expected<std::string>
3731 std::chrono::seconds timeout) {
3735 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3737 std::string json_string;
3738 llvm::raw_string_ostream os(json_string);
3741 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3750 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3751 "jLLDBTraceGetState is unsupported");
3752 return std::string(response.
Peek());
3755 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3756 return llvm::createStringError(
3757 llvm::inconvertibleErrorCode(),
3758 "failed to send packet: jLLDBTraceGetState '%s'",
3762llvm::Expected<std::vector<uint8_t>>
3768 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3770 std::string json_string;
3771 llvm::raw_string_ostream os(json_string);
3774 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3784 return std::vector<uint8_t>(data.begin(), data.end());
3786 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3787 return llvm::createStringError(
3788 llvm::inconvertibleErrorCode(),
3789 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3797 return std::nullopt;
3799 return std::nullopt;
3803 const auto &GetOffset = [&] {
3805 if (ref.consumeInteger(16, offset))
3807 result.
offsets.push_back(offset);
3811 if (ref.consume_front(
"Text=")) {
3814 return std::nullopt;
3815 if (!ref.consume_front(
";Data=") || !GetOffset())
3816 return std::nullopt;
3819 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3821 }
else if (ref.consume_front(
"TextSeg=")) {
3824 return std::nullopt;
3827 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3830 return std::nullopt;
3839 std::string module_path = module_file_spec.
GetPath(
false);
3840 if (module_path.empty())
3847 const auto &triple = arch_spec.
GetTriple().getTriple();
3863 llvm::StringRef name;
3864 llvm::StringRef value;
3866 module_spec.
Clear();
3870 if (name ==
"uuid" || name ==
"md5") {
3875 }
else if (name ==
"triple") {
3880 }
else if (name ==
"file_offset") {
3882 if (!value.getAsInteger(16, ival))
3884 }
else if (name ==
"file_size") {
3886 if (!value.getAsInteger(16, ival))
3888 }
else if (name ==
"file_path") {
3899static std::optional<ModuleSpec>
3903 return std::nullopt;
3905 llvm::StringRef string;
3909 return std::nullopt;
3911 return std::nullopt;
3914 return std::nullopt;
3918 return std::nullopt;
3922 return std::nullopt;
3926 return std::nullopt;
3932std::optional<std::vector<ModuleSpec>>
3934 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
3938 return std::nullopt;
3940 json::Array module_array;
3941 for (
const FileSpec &module_file_spec : module_file_specs) {
3942 module_array.push_back(
3943 json::Object{{
"file", module_file_spec.GetPath(
false)},
3944 {
"triple", triple.getTriple()}});
3947 unescaped_payload.
PutCString(
"jModulesInfo:");
3948 unescaped_payload.
AsRawOstream() << std::move(module_array);
3961 return std::nullopt;
3965 return std::nullopt;
3970 if (!response_object_sp)
3971 return std::nullopt;
3974 if (!response_array)
3975 return std::nullopt;
3977 std::vector<ModuleSpec> result;
3978 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
3981 result.push_back(*module_spec);
3991llvm::Expected<std::string>
3993 llvm::StringRef annex) {
3996 llvm::raw_string_ostream output_stream(output);
4010 std::string packet =
4011 (
"qXfer:" +
object +
":read:" + annex +
":" +
4012 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4020 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4021 "Error sending $qXfer packet");
4039 return llvm::createStringError(
4040 llvm::inconvertibleErrorCode(),
4041 "Invalid continuation code from $qXfer packet");
4091 bool symbol_response_provided =
false;
4094 bool first_qsymbol_query =
true;
4105 if (symbol_response_provided || first_qsymbol_query) {
4112 first_qsymbol_query =
false;
4121 if (response_str.starts_with(
"qSymbol:")) {
4123 std::string symbol_name;
4125 if (symbol_name.empty())
4136 switch (sc.symbol->GetType()) {
4169 sc.symbol->GetLoadAddress(&process->
GetTarget());
4182 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4183 symbol_response_provided =
true;
4185 symbol_response_provided =
false;
4201 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4226 "GDBRemoteCommunicationClient::%s(): "
4227 "QSupportedAsyncJSONPackets returned invalid "
4234 "GDBRemoteCommunicationClient::%s(): "
4235 "QSupportedAsyncJSONPackets unsupported",
4243 "GDBRemoteCommunicationClient::%s(): supported async "
4245 __FUNCTION__, stream.
GetData());
4255 llvm::ArrayRef<int32_t> signals) {
4258 auto range = llvm::make_range(signals.begin(), signals.end());
4259 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4271 "Unknown error happened during sending QPassSignals packet.");
4279 if (type_name.empty()) {
4292 config_sp->Dump(unescaped_stream);
4293 unescaped_stream.
Flush();
4311 "configuring StructuredData feature {0} failed with error {1}",
4317 "configuring StructuredData feature {0} failed when sending packet: "
4319 type_name, (
int)result);
4346 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4347 "failed to send k packet");
4349 char packet_cmd = response.
GetChar(0);
4350 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4353 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4354 "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.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
bool IsValid() const
Tests if this ArchSpec is valid.
void Clear()
Clears the object state.
llvm::Triple & GetTriple()
Architecture triple accessor.
void SetFlags(uint32_t flags)
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.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
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
uint64_t GetUnsignedIntegerValue(uint64_t fail_value=0)
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
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
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0))
PacketResult SendPacketAndWaitForResponseNoLock(llvm::StringRef payload, StringExtractorGDBRemote &response)
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 GetVContSupported(char flavor)
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
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)
Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout< std::micro > &timeout)
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
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
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)
bool GetxPacketSupported()
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
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()
llvm::ErrorOr< llvm::MD5::MD5Result > CalculateMD5(const FileSpec &file_spec)
uint32_t GetGDBServerProgramVersion()
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_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 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.