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") {
1625 llvm::StringRef flags = value;
1626 llvm::StringRef flag;
1627 while (flags.size()) {
1628 flags = flags.ltrim();
1629 std::tie(flag, flags) = flags.split(
' ');
1638 }
else if (name ==
"type") {
1639 for (llvm::StringRef entry : llvm::split(value,
',')) {
1640 if (entry ==
"stack")
1642 else if (entry ==
"heap")
1645 }
else if (name ==
"error") {
1647 std::string error_string;
1651 }
else if (name ==
"dirty-pages") {
1652 std::vector<addr_t> dirty_page_list;
1653 for (llvm::StringRef x : llvm::split(value,
',')) {
1655 x.consume_front(
"0x");
1656 if (llvm::to_integer(x, page, 16))
1657 dirty_page_list.push_back(page);
1669 if (!saw_permissions) {
1697 region_info = qXfer_region_info;
1700 region_info.
Clear();
1702 }
else if (qXfer_error.
Success()) {
1717 if (!
error.Success())
1720 if (map_region.GetRange().Contains(addr)) {
1721 region = map_region;
1747 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1753 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1769 if (memory_node.
GetName() !=
"memory")
1780 region.GetRange().SetByteSize(length);
1781 if (type ==
"rom") {
1784 }
else if (type ==
"ram") {
1788 }
else if (type ==
"flash") {
1791 [®ion](
const XMLNode &prop_node) ->
bool {
1794 if (prop_node.
GetName() !=
"property")
1797 if (propname ==
"blocksize") {
1800 region.SetBlocksize(blocksize);
1819 std::optional<uint32_t> num;
1825 llvm::StringRef name;
1826 llvm::StringRef value;
1828 if (name ==
"num") {
1844WatchpointHardwareFeature
1863 return std::nullopt;
1868 std::string path{file_spec.
GetPath(
false)};
1888 std::string path{file_spec.
GetPath(
false)};
1908 std::string path{file_spec.
GetPath(
false)};
1937 return !cwd.empty();
1944 std::string path{working_dir.
GetPath(
false)};
1964 const int packet_len =
1965 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
1966 assert(packet_len < (
int)
sizeof(packet));
1981 const int packet_len = ::snprintf(packet,
sizeof(packet),
1982 "QSetDetachOnError:%i", enable ? 1 : 0);
1983 assert(packet_len < (
int)
sizeof(packet));
1999 llvm::StringRef name;
2000 llvm::StringRef value;
2006 std::string os_type;
2009 if (name ==
"pid") {
2011 value.getAsInteger(0, pid);
2013 }
else if (name ==
"ppid") {
2015 value.getAsInteger(0, pid);
2017 }
else if (name ==
"uid") {
2019 value.getAsInteger(0, uid);
2021 }
else if (name ==
"euid") {
2023 value.getAsInteger(0, uid);
2025 }
else if (name ==
"gid") {
2027 value.getAsInteger(0, gid);
2029 }
else if (name ==
"egid") {
2031 value.getAsInteger(0, gid);
2033 }
else if (name ==
"triple") {
2038 }
else if (name ==
"name") {
2045 }
else if (name ==
"args") {
2046 llvm::StringRef encoded_args(value), hex_arg;
2048 bool is_arg0 =
true;
2049 while (!encoded_args.empty()) {
2050 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2065 }
else if (name ==
"cputype") {
2066 value.getAsInteger(0, cpu);
2067 }
else if (name ==
"cpusubtype") {
2068 value.getAsInteger(0, sub);
2069 }
else if (name ==
"vendor") {
2070 vendor = std::string(value);
2071 }
else if (name ==
"ostype") {
2072 os_type = std::string(value);
2077 if (vendor ==
"apple") {
2081 llvm::StringRef(vendor));
2083 llvm::StringRef(os_type));
2095 process_info.
Clear();
2099 const int packet_len =
2100 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2101 assert(packet_len < (
int)
sizeof(packet));
2131 llvm::StringRef name;
2132 llvm::StringRef value;
2135 std::string arch_name;
2136 std::string os_name;
2137 std::string environment;
2138 std::string vendor_name;
2140 std::string elf_abi;
2141 uint32_t pointer_byte_size = 0;
2144 uint32_t num_keys_decoded = 0;
2147 if (name ==
"cputype") {
2148 if (!value.getAsInteger(16, cpu))
2150 }
else if (name ==
"cpusubtype") {
2151 if (!value.getAsInteger(16, sub)) {
2157 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2158 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2165 }
else if (name ==
"triple") {
2169 }
else if (name ==
"ostype") {
2172 }
else if (name ==
"vendor") {
2173 vendor_name = std::string(value);
2175 }
else if (name ==
"endian") {
2176 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2183 }
else if (name ==
"ptrsize") {
2184 if (!value.getAsInteger(16, pointer_byte_size))
2186 }
else if (name ==
"pid") {
2187 if (!value.getAsInteger(16, pid))
2189 }
else if (name ==
"elf_abi") {
2190 elf_abi = std::string(value);
2192 }
else if (name ==
"main-binary-uuid") {
2195 }
else if (name ==
"main-binary-slide") {
2203 }
else if (name ==
"main-binary-address") {
2211 }
else if (name ==
"binary-addresses") {
2214 for (llvm::StringRef x : llvm::split(value,
',')) {
2216 x.consume_front(
"0x");
2217 if (llvm::to_integer(x, vmaddr, 16))
2222 if (num_keys_decoded > 0)
2230 if (!triple.empty()) {
2233 if (pointer_byte_size) {
2237 !vendor_name.empty()) {
2238 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2239 if (!environment.empty())
2240 triple.setEnvironmentName(environment);
2242 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2243 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2244 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2245 switch (triple.getObjectFormat()) {
2246 case llvm::Triple::MachO:
2249 case llvm::Triple::ELF:
2252 case llvm::Triple::COFF:
2255 case llvm::Triple::GOFF:
2256 case llvm::Triple::SPIRV:
2257 case llvm::Triple::Wasm:
2258 case llvm::Triple::XCOFF:
2259 case llvm::Triple::DXContainer:
2260 LLDB_LOGF(log,
"error: not supported target architecture");
2262 case llvm::Triple::UnknownObjectFormat:
2263 LLDB_LOGF(log,
"error: failed to determine target architecture");
2267 if (pointer_byte_size) {
2289 process_infos.clear();
2297 bool has_name_match =
false;
2298 if (name && name[0]) {
2299 has_name_match =
true;
2301 switch (name_match_type) {
2303 has_name_match =
false;
2315 packet.
PutCString(
"name_match:starts_with;");
2326 if (has_name_match) {
2334 packet.
Printf(
"pid:%" PRIu64
";",
2337 packet.
Printf(
"parent_pid:%" PRIu64
";",
2344 packet.
Printf(
"euid:%u;",
2347 packet.
Printf(
"egid:%u;",
2353 const llvm::Triple &triple = match_arch.
GetTriple();
2369 process_infos.push_back(process_info);
2378 return process_infos.size();
2382 std::string &name) {
2385 const int packet_len =
2386 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2387 assert(packet_len < (
int)
sizeof(packet));
2409 std::string &name) {
2412 const int packet_len =
2413 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2414 assert(packet_len < (
int)
sizeof(packet));
2436 uint32_t recv_size) {
2438 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2439 uint32_t bytes_left = send_size;
2440 while (bytes_left > 0) {
2441 if (bytes_left >= 26) {
2442 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2445 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2446 "abcdefghijklmnopqrstuvwxyz");
2455 return duration<float>::zero();
2456 using Dur = duration<float>;
2457 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2458 Dur mean = sum / v.size();
2461 float delta = (d - mean).count();
2462 accum += delta * delta;
2465 return Dur(sqrtf(accum / (v.size() - 1)));
2471 uint64_t recv_amount,
2472 bool json,
Stream &strm) {
2477 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2481 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2485 uint32_t result_idx = 0;
2487 std::vector<duration<float>> packet_times;
2489 for (send_size = 0; send_size <= max_send;
2490 send_size ? send_size *= 2 : send_size = 4) {
2491 for (uint32_t recv_size = 0; recv_size <= max_recv;
2492 recv_size ? recv_size *= 2 : recv_size = 4) {
2495 packet_times.clear();
2497 const auto start_time = steady_clock::now();
2498 for (uint32_t i = 0; i < num_packets; ++i) {
2499 const auto packet_start_time = steady_clock::now();
2502 const auto packet_end_time = steady_clock::now();
2503 packet_times.push_back(packet_end_time - packet_start_time);
2505 const auto end_time = steady_clock::now();
2506 const auto total_time = end_time - start_time;
2508 float packets_per_second =
2509 ((float)num_packets) / duration<float>(total_time).count();
2510 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2511 : duration<float>::zero();
2512 const duration<float> standard_deviation =
2515 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2516 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2517 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2518 result_idx > 0 ?
"," :
"", send_size, recv_size,
2519 total_time, standard_deviation);
2522 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2523 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2524 "standard deviation of {5,10:ms+f6}\n",
2525 send_size, recv_size, duration<float>(total_time),
2526 packets_per_second, duration<float>(average_per_packet),
2527 standard_deviation);
2533 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2535 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2536 ": %" PRIu64
",\n \"results\" : [",
2539 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2545 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2550 if (recv_size > 0) {
2551 const auto start_time = steady_clock::now();
2552 uint32_t bytes_read = 0;
2553 uint32_t packet_count = 0;
2554 while (bytes_read < recv_amount) {
2557 bytes_read += recv_size;
2560 const auto end_time = steady_clock::now();
2561 const auto total_time = end_time - start_time;
2562 float mb_second = ((float)recv_amount) /
2563 duration<float>(total_time).count() /
2565 float packets_per_second =
2566 ((float)packet_count) / duration<float>(total_time).count();
2567 const auto average_per_packet = packet_count > 0
2568 ? total_time / packet_count
2569 : duration<float>::zero();
2572 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2573 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2574 result_idx > 0 ?
"," :
"", send_size, recv_size,
2578 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2579 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2580 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2581 send_size, recv_size, packet_count, k_recv_amount_mb,
2582 duration<float>(total_time), mb_second,
2583 packets_per_second, duration<float>(average_per_packet));
2589 strm.
Printf(
"\n ]\n }\n}\n");
2596 uint32_t recv_size) {
2598 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2599 uint32_t bytes_left = send_size;
2600 while (bytes_left > 0) {
2601 if (bytes_left >= 26) {
2602 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2605 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2606 "abcdefghijklmnopqrstuvwxyz");
2617 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2618 std::string &socket_name) {
2621 socket_name.clear();
2626 std::string hostname;
2627 if (remote_accept_hostname && remote_accept_hostname[0])
2628 hostname = remote_accept_hostname;
2630 if (HostInfo::GetHostname(hostname)) {
2632 stream.
Printf(
"host:%s;", hostname.c_str());
2636 stream.
Printf(
"host:*;");
2647 llvm::StringRef name;
2648 llvm::StringRef value;
2651 value.getAsInteger(0, port);
2652 else if (name ==
"pid")
2653 value.getAsInteger(0, pid);
2654 else if (name.compare(
"socket_name") == 0) {
2665 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2666 connection_urls.clear();
2682 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2683 std::optional<StructuredData::Dictionary *> maybe_element =
2694 std::string socket_name;
2697 socket_name = std::string(socket_name_osp->GetStringValue());
2699 if (port != 0 || !socket_name.empty())
2700 connection_urls.emplace_back(port, socket_name);
2702 return connection_urls.size();
2707 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2719 uint64_t tid, uint64_t pid,
char op) {
2725 packet.
Printf(
"p%" PRIx64
".", pid);
2730 packet.
Printf(
"%" PRIx64, tid);
2736 return {{pid, tid}};
2748 return std::nullopt;
2763 return ret.has_value();
2778 return ret.has_value();
2793 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2794 assert(packet_len < (
int)
sizeof(packet));
2813 std::chrono::seconds timeout) {
2815 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2816 __FUNCTION__, insert ?
"add" :
"remove", addr);
2823 const int packet_len =
2824 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2825 insert ?
'Z' :
'z', type, addr, length);
2827 assert(packet_len + 1 < (
int)
sizeof(packet));
2872std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2874 bool &sequence_mutex_unavailable) {
2875 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2879 sequence_mutex_unavailable =
false;
2883 for (packet_result =
2901 ids.push_back(*pid_tid);
2903 }
while (ch ==
',');
2917 ids.emplace_back(1, 1);
2921 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
2922 "packet 'qfThreadInfo'");
2923 sequence_mutex_unavailable =
true;
2930 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
2935 if (ids.empty() || sequence_mutex_unavailable)
2938 for (
auto id : ids) {
2944 thread_ids.push_back(
id.second);
2947 return thread_ids.size();
2960 llvm::StringRef command,
2976 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
2980 std::string path{working_dir.
GetPath(
false)};
2987 if (response.
GetChar() !=
'F')
2989 if (response.
GetChar() !=
',')
2994 else if (status_ptr)
2995 *status_ptr = exitcode;
2996 if (response.
GetChar() !=
',')
3001 if (response.
GetChar() !=
',')
3006 command_output->assign(output);
3013 uint32_t file_permissions) {
3014 std::string path{file_spec.
GetPath(
false)};
3020 llvm::StringRef packet = stream.
GetString();
3025 packet.str().c_str());
3027 if (response.
GetChar() !=
'F')
3029 packet.str().c_str());
3036 uint32_t file_permissions) {
3037 std::string path{file_spec.
GetPath(
false)};
3043 llvm::StringRef packet = stream.
GetString();
3050 if (response.
GetChar() !=
'F')
3059#define HANDLE_ERRNO(name, value) \
3062#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3071 if (response.
GetChar() !=
'F')
3073 int32_t result = response.
GetS32(-2, 16);
3076 if (response.
GetChar() ==
',') {
3078 if (result_errno != -1)
3090 std::string path(file_spec.
GetPath(
false));
3111 stream.
Printf(
"vFile:close:%x", (
int)fd);
3120std::optional<GDBRemoteFStatData>
3123 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3127 if (response.
GetChar() !=
'F')
3128 return std::nullopt;
3129 int64_t size = response.
GetS64(-1, 16);
3130 if (size > 0 && response.
GetChar() ==
';') {
3134 if (buffer.size() !=
sizeof(out))
3135 return std::nullopt;
3136 memcpy(&out, buffer.data(),
sizeof(out));
3141 return std::nullopt;
3144std::optional<GDBRemoteFStatData>
3149 return std::nullopt;
3150 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3159 std::string path(file_spec.
GetPath(
false));
3169 if (response.
GetChar() !=
'F')
3178 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3196 while (response.
Peek()) {
3198 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3201 if (response.
GetChar() !=
',')
3209 uint32_t &file_permissions) {
3211 std::string path{file_spec.
GetPath(
false)};
3224 if (response.
GetChar() !=
'F') {
3226 "invalid response to '%s' packet", stream.
GetData());
3228 const uint32_t mode = response.
GetS32(-1, 16);
3229 if (
static_cast<int32_t
>(mode) == -1) {
3230 if (response.
GetChar() ==
',') {
3232 if (response_errno > 0)
3249 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3257 uint64_t offset,
void *dst,
3261 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3266 if (response.
GetChar() !=
'F')
3268 int64_t retcode = response.
GetS64(-1, 16);
3269 if (retcode == -1) {
3271 if (response.
GetChar() ==
',') {
3273 if (response_errno > 0)
3278 const char next = (response.
Peek() ? *response.
Peek() : 0);
3285 const uint64_t data_to_write =
3286 std::min<uint64_t>(dst_len, buffer.size());
3287 if (data_to_write > 0)
3288 memcpy(dst, &buffer[0], data_to_write);
3289 return data_to_write;
3302 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3307 if (response.
GetChar() !=
'F') {
3311 int64_t bytes_written = response.
GetS64(-1, 16);
3312 if (bytes_written == -1) {
3314 if (response.
GetChar() ==
',') {
3316 if (response_errno > 0)
3321 return bytes_written;
3330 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3342 if (response.
GetChar() ==
'F') {
3346 if (response.
GetChar() ==
',') {
3348 if (response_errno > 0)
3363 std::string path{file_spec.
GetPath(
false)};
3373 if (response.
GetChar() ==
'F') {
3377 if (response.
GetChar() ==
',') {
3379 if (response_errno > 0)
3397 std::string path(file_spec.
GetPath(
false));
3406 if (response.
GetChar() !=
'F')
3408 if (response.
GetChar() !=
',')
3410 bool retcode = (response.
GetChar() !=
'0');
3427 std::string path(file_spec.
GetPath(
false));
3434 if (response.
GetChar() !=
'F')
3435 return std::make_error_code(std::errc::illegal_byte_sequence);
3436 if (response.
GetChar() !=
',')
3437 return std::make_error_code(std::errc::illegal_byte_sequence);
3438 if (response.
Peek() && *response.
Peek() ==
'x')
3439 return std::make_error_code(std::errc::no_such_file_or_directory);
3456 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3461 if (part.size() != MD5_HALF_LENGTH)
3462 return std::make_error_code(std::errc::illegal_byte_sequence);
3466 if (part.getAsInteger(16, low))
3467 return std::make_error_code(std::errc::illegal_byte_sequence);
3472 if (part.size() != MD5_HALF_LENGTH)
3473 return std::make_error_code(std::errc::illegal_byte_sequence);
3477 if (part.getAsInteger(16, high))
3478 return std::make_error_code(std::errc::illegal_byte_sequence);
3480 llvm::MD5::MD5Result result;
3481 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3482 result.data(), low);
3483 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3484 result.data() + 8, high);
3488 return std::make_error_code(std::errc::operation_canceled);
3498 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3499 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3500 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3501 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3504 if (gdb_server_version != 0) {
3506 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3507 if (gdb_server_version >= 310)
3520 payload.
Printf(
"p%x", reg);
3529 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3544 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3550 llvm::ArrayRef<uint8_t> data) {
3552 payload.
Printf(
"P%x=", reg_num);
3576 uint32_t &save_id) {
3592 const uint32_t response_save_id = response.
GetU32(0);
3593 if (response_save_id == 0)
3596 save_id = response_save_id;
3609 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3629 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3635llvm::Expected<TraceSupportedResponse>
3640 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3649 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3650 "jLLDBTraceSupported is unsupported");
3652 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3653 "TraceSupportedResponse");
3655 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3656 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3657 "failed to send packet: jLLDBTraceSupported");
3662 std::chrono::seconds timeout) {
3666 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3668 std::string json_string;
3669 llvm::raw_string_ostream os(json_string);
3672 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3681 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3682 "jLLDBTraceStop is unsupported");
3684 return llvm::Error::success();
3685 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3686 "Invalid jLLDBTraceStart response");
3688 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3689 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3690 "failed to send packet: jLLDBTraceStop '%s'",
3696 std::chrono::seconds timeout) {
3700 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3702 std::string json_string;
3703 llvm::raw_string_ostream os(json_string);
3706 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3715 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3716 "jLLDBTraceStart is unsupported");
3718 return llvm::Error::success();
3719 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3720 "Invalid jLLDBTraceStart response");
3722 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3723 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3724 "failed to send packet: jLLDBTraceStart '%s'",
3728llvm::Expected<std::string>
3730 std::chrono::seconds timeout) {
3734 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3736 std::string json_string;
3737 llvm::raw_string_ostream os(json_string);
3740 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3749 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3750 "jLLDBTraceGetState is unsupported");
3751 return std::string(response.
Peek());
3754 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3755 return llvm::createStringError(
3756 llvm::inconvertibleErrorCode(),
3757 "failed to send packet: jLLDBTraceGetState '%s'",
3761llvm::Expected<std::vector<uint8_t>>
3767 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3769 std::string json_string;
3770 llvm::raw_string_ostream os(json_string);
3773 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3783 return std::vector<uint8_t>(data.begin(), data.end());
3785 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3786 return llvm::createStringError(
3787 llvm::inconvertibleErrorCode(),
3788 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3796 return std::nullopt;
3798 return std::nullopt;
3802 const auto &GetOffset = [&] {
3804 if (ref.consumeInteger(16, offset))
3806 result.
offsets.push_back(offset);
3810 if (ref.consume_front(
"Text=")) {
3813 return std::nullopt;
3814 if (!ref.consume_front(
";Data=") || !GetOffset())
3815 return std::nullopt;
3818 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3820 }
else if (ref.consume_front(
"TextSeg=")) {
3823 return std::nullopt;
3826 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3829 return std::nullopt;
3838 std::string module_path = module_file_spec.
GetPath(
false);
3839 if (module_path.empty())
3846 const auto &triple = arch_spec.
GetTriple().getTriple();
3862 llvm::StringRef name;
3863 llvm::StringRef value;
3865 module_spec.
Clear();
3869 if (name ==
"uuid" || name ==
"md5") {
3874 }
else if (name ==
"triple") {
3879 }
else if (name ==
"file_offset") {
3881 if (!value.getAsInteger(16, ival))
3883 }
else if (name ==
"file_size") {
3885 if (!value.getAsInteger(16, ival))
3887 }
else if (name ==
"file_path") {
3898static std::optional<ModuleSpec>
3902 return std::nullopt;
3904 llvm::StringRef string;
3908 return std::nullopt;
3910 return std::nullopt;
3913 return std::nullopt;
3917 return std::nullopt;
3921 return std::nullopt;
3925 return std::nullopt;
3931std::optional<std::vector<ModuleSpec>>
3933 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
3937 return std::nullopt;
3939 json::Array module_array;
3940 for (
const FileSpec &module_file_spec : module_file_specs) {
3941 module_array.push_back(
3942 json::Object{{
"file", module_file_spec.GetPath(
false)},
3943 {
"triple", triple.getTriple()}});
3946 unescaped_payload.
PutCString(
"jModulesInfo:");
3947 unescaped_payload.
AsRawOstream() << std::move(module_array);
3960 return std::nullopt;
3964 return std::nullopt;
3969 if (!response_object_sp)
3970 return std::nullopt;
3973 if (!response_array)
3974 return std::nullopt;
3976 std::vector<ModuleSpec> result;
3977 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
3980 result.push_back(*module_spec);
3990llvm::Expected<std::string>
3992 llvm::StringRef annex) {
3995 llvm::raw_string_ostream output_stream(output);
4009 std::string packet =
4010 (
"qXfer:" +
object +
":read:" + annex +
":" +
4011 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4019 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4020 "Error sending $qXfer packet");
4038 return llvm::createStringError(
4039 llvm::inconvertibleErrorCode(),
4040 "Invalid continuation code from $qXfer packet");
4090 bool symbol_response_provided =
false;
4093 bool first_qsymbol_query =
true;
4104 if (symbol_response_provided || first_qsymbol_query) {
4111 first_qsymbol_query =
false;
4120 if (response_str.starts_with(
"qSymbol:")) {
4122 std::string symbol_name;
4124 if (symbol_name.empty())
4135 switch (sc.symbol->GetType()) {
4168 sc.symbol->GetLoadAddress(&process->
GetTarget());
4181 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4182 symbol_response_provided =
true;
4184 symbol_response_provided =
false;
4200 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4225 "GDBRemoteCommunicationClient::%s(): "
4226 "QSupportedAsyncJSONPackets returned invalid "
4233 "GDBRemoteCommunicationClient::%s(): "
4234 "QSupportedAsyncJSONPackets unsupported",
4242 "GDBRemoteCommunicationClient::%s(): supported async "
4244 __FUNCTION__, stream.
GetData());
4254 llvm::ArrayRef<int32_t> signals) {
4257 auto range = llvm::make_range(signals.begin(), signals.end());
4258 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4270 "Unknown error happened during sending QPassSignals packet.");
4278 if (type_name.empty()) {
4291 config_sp->Dump(unescaped_stream);
4292 unescaped_stream.
Flush();
4310 "configuring StructuredData feature {0} failed with error {1}",
4316 "configuring StructuredData feature {0} failed when sending packet: "
4318 type_name, (
int)result);
4345 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4346 "failed to send k packet");
4348 char packet_cmd = response.
GetChar(0);
4349 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4352 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4353 "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 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.