36#include "lldb/Host/Config.h"
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/StringSwitch.h"
41#include "llvm/Config/llvm-config.h"
42#include "llvm/Support/JSON.h"
44#if HAVE_LIBCOMPRESSION
45#include <compression.h>
51using namespace std::chrono;
55 return os << llvm::formatv(
56 "QOffsets({0}, [{1:@[x]}])", offsets.
segments,
91 std::chrono::steady_clock::time_point start_of_handshake =
92 std::chrono::steady_clock::now();
101 std::chrono::steady_clock::time_point end_of_handshake =
102 std::chrono::steady_clock::now();
103 auto handshake_timeout =
104 std::chrono::duration<double>(end_of_handshake - start_of_handshake)
110 "while waiting for reply to initial "
114 "failed to get reply to handshake packet within timeout of "
381 std::vector<std::string> features = {
"xmlRegisters=i386,arm,mips,arc",
389 for (uint32_t i = 0; i < features.size(); ++i) {
401 for (llvm::StringRef x : llvm::split(response.
GetStringRef(),
';')) {
402 if (x ==
"qXfer:auxv:read+")
404 else if (x ==
"qXfer:libraries-svr4:read+")
406 else if (x ==
"augmented-libraries-svr4-read") {
409 }
else if (x ==
"qXfer:libraries:read+")
411 else if (x ==
"qXfer:features:read+")
413 else if (x ==
"qXfer:memory-map:read+")
415 else if (x ==
"qXfer:siginfo:read+")
417 else if (x ==
"qEcho+")
419 else if (x ==
"QPassSignals+")
421 else if (x ==
"multiprocess+")
423 else if (x ==
"memory-tagging+")
425 else if (x ==
"qSaveCore+")
427 else if (x ==
"native-signals+")
429 else if (x ==
"binary-upload+")
431 else if (x ==
"ReverseContinue+")
433 else if (x ==
"ReverseStep+")
435 else if (x ==
"MultiMemRead+")
440 else if (x.consume_front(
"SupportedCompressions=")) {
441 llvm::SmallVector<llvm::StringRef, 4> compressions;
442 x.split(compressions,
',');
443 if (!compressions.empty())
445 }
else if (x.consume_front(
"SupportedWatchpointTypes=")) {
446 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
447 x.split(watchpoint_types,
',');
449 for (
auto wp_type : watchpoint_types) {
450 if (wp_type ==
"x86_64")
452 if (wp_type ==
"aarch64-mask")
454 if (wp_type ==
"aarch64-bas")
457 }
else if (x.consume_front(
"PacketSize=")) {
464 LLDB_LOGF(log,
"Garbled PacketSize spec in qSupported response");
494 const char *response_cstr = response.
GetStringRef().data();
495 if (::strstr(response_cstr,
";c"))
498 if (::strstr(response_cstr,
";C"))
501 if (::strstr(response_cstr,
";s"))
504 if (::strstr(response_cstr,
";S"))
550 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
552 __FUNCTION__, payload.GetData());
557 payload.Printf(
";thread:%4.4" PRIx64
";", tid);
604 }
else if (!response.
Empty()) {
693 packet.
Printf(
"qMemTags:%" PRIx64
",%zx:%" PRIx32, addr, len, type);
701 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s: qMemTags packet failed",
709 if (response.
GetChar() !=
'm') {
711 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
722 if (response.
GetBytesLeft() || (expected_bytes != got_bytes)) {
725 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
735 const std::vector<uint8_t> &tags) {
738 packet.
Printf(
"QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr, len, type);
784 if (response.
GetChar() ==
'Q') {
785 if (response.
GetChar() ==
'C') {
799 bool sequence_mutex_unavailable;
801 if (!ids.empty() && !sequence_mutex_unavailable) {
818 return llvm::createStringError(llvm::inconvertibleErrorCode(),
819 "Nothing to launch");
832 return llvm::createStringError(llvm::inconvertibleErrorCode(),
833 "Sending vRun packet failed");
842 return llvm::Error::success();
850 llvm::ListSeparator LS(
",");
851 for (
const auto &arg : llvm::enumerate(args)) {
853 packet.
Format(
"{0},{1},", arg.value().ref().size() * 2, arg.index());
860 return llvm::createStringError(llvm::inconvertibleErrorCode(),
861 "Sending A packet failed");
868 return llvm::createStringError(llvm::inconvertibleErrorCode(),
869 "Sending qLaunchSuccess packet failed");
872 return llvm::Error::success();
873 if (response.
GetChar() ==
'E') {
874 return llvm::createStringError(llvm::inconvertibleErrorCode(),
877 return llvm::createStringError(llvm::inconvertibleErrorCode(),
878 "unknown error occurred launching process");
882 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
883 for (
const auto &kv : env)
884 vec.emplace_back(kv.first(), kv.second);
885 llvm::sort(vec, llvm::less_first());
886 for (
const auto &[k, v] : vec) {
895 char const *name_equal_value) {
896 if (name_equal_value && name_equal_value[0]) {
897 bool send_hex_encoding =
false;
898 for (
const char *p = name_equal_value; *p !=
'\0' && !send_hex_encoding;
900 if (llvm::isPrint(*p)) {
906 send_hex_encoding =
true;
913 send_hex_encoding =
true;
921 packet.
Printf(
"QEnvironment:%s", name_equal_value);
962 if (arch && arch[0]) {
964 packet.
Printf(
"QLaunchArch:%s", arch);
979 char const *data,
bool *was_supported) {
980 if (data && *data !=
'\0') {
982 packet.
Printf(
"QSetProcessEvent:%s", data);
988 *was_supported =
true;
992 *was_supported =
false;
997 *was_supported =
true;
1021 return std::nullopt;
1024std::optional<std::string>
1030 return std::nullopt;
1058 UUID &uuid,
addr_t &value,
bool &value_is_offset) {
1091 llvm::StringRef name, value;
1092 bool success =
false;
1094 if (name ==
"name") {
1097 }
else if (name ==
"version") {
1098 llvm::StringRef major, minor;
1099 std::tie(major, minor) = value.split(
'.');
1113 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1115 llvm::StringRef avail_name;
1117#if HAVE_LIBCOMPRESSION
1119 for (
auto compression : supported_compressions) {
1120 if (compression ==
"lzfse") {
1122 avail_name = compression;
1128 for (
auto compression : supported_compressions) {
1129 if (compression ==
"zlib-deflate") {
1131 avail_name = compression;
1140 for (
auto compression : supported_compressions) {
1141 if (compression ==
"zlib-deflate") {
1143 avail_name = compression;
1150#if HAVE_LIBCOMPRESSION
1152 for (
auto compression : supported_compressions) {
1153 if (compression ==
"lz4") {
1155 avail_name = compression;
1161 for (
auto compression : supported_compressions) {
1162 if (compression ==
"lzma") {
1164 avail_name = compression;
1173 std::string packet =
"QEnableCompression:type:" + avail_name.str() +
";";
1220 tid = pid_tid->second;
1227 std::string &environment) {
1228 if (value ==
"iossimulator" || value ==
"tvossimulator" ||
1229 value ==
"watchossimulator" || value ==
"xrossimulator" ||
1230 value ==
"visionossimulator") {
1231 environment =
"simulator";
1232 os_name = value.drop_back(environment.size()).str();
1233 }
else if (value ==
"maccatalyst") {
1235 environment =
"macabi";
1237 os_name = value.str();
1253 llvm::StringRef name;
1254 llvm::StringRef value;
1257 std::string arch_name;
1258 std::string os_name;
1259 std::string environment;
1260 std::string vendor_name;
1262 uint32_t pointer_byte_size = 0;
1264 uint32_t num_keys_decoded = 0;
1266 if (name ==
"cputype") {
1268 if (!value.getAsInteger(0, cpu))
1270 }
else if (name ==
"cpusubtype") {
1272 if (!value.getAsInteger(0, sub))
1274 }
else if (name ==
"arch") {
1275 arch_name = std::string(value);
1277 }
else if (name ==
"triple") {
1281 }
else if (name ==
"distribution_id") {
1285 }
else if (name ==
"os_build") {
1289 }
else if (name ==
"hostname") {
1293 }
else if (name ==
"os_kernel") {
1297 }
else if (name ==
"ostype") {
1300 }
else if (name ==
"vendor") {
1301 vendor_name = std::string(value);
1303 }
else if (name ==
"endian") {
1304 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1311 }
else if (name ==
"ptrsize") {
1312 if (!value.getAsInteger(0, pointer_byte_size))
1314 }
else if (name ==
"addressing_bits") {
1318 }
else if (name ==
"high_mem_addressing_bits") {
1321 }
else if (name ==
"low_mem_addressing_bits") {
1324 }
else if (name ==
"os_version" ||
1331 }
else if (name ==
"maccatalyst_version") {
1334 }
else if (name ==
"watchpoint_exceptions_received") {
1336 llvm::StringSwitch<LazyBool>(value)
1342 }
else if (name ==
"default_packet_timeout") {
1343 uint32_t timeout_seconds;
1344 if (!value.getAsInteger(0, timeout_seconds)) {
1349 }
else if (name ==
"vm-page-size") {
1351 if (!value.getAsInteger(0, page_size)) {
1358 if (num_keys_decoded > 0)
1361 if (triple.empty()) {
1362 if (arch_name.empty()) {
1365 if (pointer_byte_size) {
1366 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1372 if (!vendor_name.empty())
1374 llvm::StringRef(vendor_name));
1375 if (!os_name.empty())
1376 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1377 if (!environment.empty())
1378 m_host_arch.GetTriple().setEnvironmentName(environment);
1382 triple += arch_name;
1383 if (!vendor_name.empty() || !os_name.empty()) {
1385 if (vendor_name.empty())
1386 triple +=
"unknown";
1388 triple += vendor_name;
1390 if (os_name.empty())
1391 triple +=
"unknown";
1397 llvm::Triple &host_triple =
m_host_arch.GetTriple();
1398 if (host_triple.getVendor() == llvm::Triple::Apple &&
1399 host_triple.getOS() == llvm::Triple::Darwin) {
1401 case llvm::Triple::aarch64:
1402 case llvm::Triple::aarch64_32:
1403 case llvm::Triple::arm:
1404 case llvm::Triple::thumb:
1405 host_triple.setOS(llvm::Triple::IOS);
1408 host_triple.setOS(llvm::Triple::MacOSX);
1412 if (pointer_byte_size) {
1413 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1421 if (pointer_byte_size) {
1422 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1429 "GDBRemoteCommunicationClient::%s parsed host "
1430 "architecture as %s, triple as %s from triple text %s",
1434 :
"<null-arch-name>",
1474 return addressable_bits;
1484 uint32_t permissions) {
1488 const int packet_len = ::snprintf(
1489 packet,
sizeof(packet),
"_M%" PRIx64
",%s%s%s", (uint64_t)size,
1490 permissions & lldb::ePermissionsReadable ?
"r" :
"",
1491 permissions & lldb::ePermissionsWritable ?
"w" :
"",
1492 permissions & lldb::ePermissionsExecutable ?
"x" :
"");
1493 assert(packet_len < (
int)
sizeof(packet));
1513 const int packet_len =
1514 ::snprintf(packet,
sizeof(packet),
"_m%" PRIx64, (uint64_t)addr);
1515 assert(packet_len < (
int)
sizeof(packet));
1540 const int packet_len =
1541 ::snprintf(packet,
sizeof(packet),
"qSupportsDetachAndStayStopped:");
1542 assert(packet_len < (
int)
sizeof(packet));
1556 "Stays stopped not supported by this target.");
1572 "Multiprocess extension not supported by the server.");
1587 region_info.
Clear();
1592 const int packet_len = ::snprintf(
1593 packet,
sizeof(packet),
"qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1594 assert(packet_len < (
int)
sizeof(packet));
1600 llvm::StringRef name;
1601 llvm::StringRef value;
1603 bool success =
true;
1604 bool saw_permissions =
false;
1606 if (name ==
"start") {
1607 if (!value.getAsInteger(16, addr_value))
1609 }
else if (name ==
"size") {
1610 if (!value.getAsInteger(16, addr_value)) {
1618 }
else if (name ==
"permissions" && region_info.
GetRange().
IsValid()) {
1619 saw_permissions =
true;
1621 if (value.contains(
'r'))
1626 if (value.contains(
'w'))
1631 if (value.contains(
'x'))
1645 }
else if (name ==
"name") {
1649 region_info.
SetName(name.c_str());
1650 }
else if (name ==
"flags") {
1654 llvm::StringRef flags = value;
1655 llvm::StringRef flag;
1656 while (flags.size()) {
1657 flags = flags.ltrim();
1658 std::tie(flag, flags) = flags.split(
' ');
1663 else if (flag ==
"ss")
1667 }
else if (name ==
"type") {
1668 for (llvm::StringRef entry : llvm::split(value,
',')) {
1669 if (entry ==
"stack")
1671 else if (entry ==
"heap")
1674 }
else if (name ==
"error") {
1676 std::string error_string;
1680 }
else if (name ==
"dirty-pages") {
1681 std::vector<addr_t> dirty_page_list;
1682 for (llvm::StringRef x : llvm::split(value,
',')) {
1684 x.consume_front(
"0x");
1685 if (llvm::to_integer(x, page, 16))
1686 dirty_page_list.push_back(page);
1698 if (!saw_permissions) {
1726 region_info = qXfer_region_info;
1729 region_info.
Clear();
1731 }
else if (qXfer_error.
Success()) {
1746 if (!
error.Success())
1749 if (map_region.GetRange().Contains(addr)) {
1750 region = map_region;
1776 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1782 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1798 if (memory_node.
GetName() !=
"memory")
1810 if (type ==
"rom") {
1813 }
else if (type ==
"ram") {
1817 }
else if (type ==
"flash") {
1820 [®ion](
const XMLNode &prop_node) ->
bool {
1823 if (prop_node.
GetName() !=
"property")
1826 if (propname ==
"blocksize") {
1848 std::optional<uint32_t> num;
1854 llvm::StringRef name;
1855 llvm::StringRef value;
1857 if (name ==
"num") {
1873WatchpointHardwareFeature
1892 return std::nullopt;
1897 std::string path{file_spec.
GetPath(
false)};
1917 std::string path{file_spec.
GetPath(
false)};
1937 std::string path{file_spec.
GetPath(
false)};
1966 return !cwd.empty();
1973 std::string path{working_dir.
GetPath(
false)};
1993 const int packet_len =
1994 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
1995 assert(packet_len < (
int)
sizeof(packet));
2010 const int packet_len = ::snprintf(packet,
sizeof(packet),
2011 "QSetDetachOnError:%i", enable ? 1 : 0);
2012 assert(packet_len < (
int)
sizeof(packet));
2028 llvm::StringRef name;
2029 llvm::StringRef value;
2035 std::string os_type;
2038 if (name ==
"pid") {
2040 value.getAsInteger(0, pid);
2042 }
else if (name ==
"ppid") {
2044 value.getAsInteger(0, pid);
2046 }
else if (name ==
"uid") {
2048 value.getAsInteger(0, uid);
2050 }
else if (name ==
"euid") {
2052 value.getAsInteger(0, uid);
2054 }
else if (name ==
"gid") {
2056 value.getAsInteger(0, gid);
2058 }
else if (name ==
"egid") {
2060 value.getAsInteger(0, gid);
2062 }
else if (name ==
"triple") {
2067 }
else if (name ==
"name") {
2074 }
else if (name ==
"args") {
2075 llvm::StringRef encoded_args(value), hex_arg;
2077 bool is_arg0 =
true;
2078 while (!encoded_args.empty()) {
2079 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2094 }
else if (name ==
"cputype") {
2095 value.getAsInteger(0, cpu);
2096 }
else if (name ==
"cpusubtype") {
2097 value.getAsInteger(0, sub);
2098 }
else if (name ==
"vendor") {
2099 vendor = std::string(value);
2100 }
else if (name ==
"ostype") {
2101 os_type = std::string(value);
2106 if (vendor ==
"apple") {
2110 llvm::StringRef(vendor));
2112 llvm::StringRef(os_type));
2124 process_info.
Clear();
2128 const int packet_len =
2129 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2130 assert(packet_len < (
int)
sizeof(packet));
2160 llvm::StringRef name;
2161 llvm::StringRef value;
2164 std::string os_name;
2165 std::string environment;
2166 std::string vendor_name;
2168 std::string elf_abi;
2169 uint32_t pointer_byte_size = 0;
2172 uint32_t num_keys_decoded = 0;
2175 if (name ==
"cputype") {
2176 if (!value.getAsInteger(16, cpu))
2178 }
else if (name ==
"cpusubtype") {
2179 if (!value.getAsInteger(16, sub)) {
2185 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2186 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2193 }
else if (name ==
"triple") {
2197 }
else if (name ==
"ostype") {
2200 }
else if (name ==
"vendor") {
2201 vendor_name = std::string(value);
2203 }
else if (name ==
"endian") {
2204 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2211 }
else if (name ==
"ptrsize") {
2212 if (!value.getAsInteger(16, pointer_byte_size))
2214 }
else if (name ==
"pid") {
2215 if (!value.getAsInteger(16, pid))
2217 }
else if (name ==
"elf_abi") {
2218 elf_abi = std::string(value);
2220 }
else if (name ==
"main-binary-uuid") {
2223 }
else if (name ==
"main-binary-slide") {
2231 }
else if (name ==
"main-binary-address") {
2239 }
else if (name ==
"binary-addresses") {
2242 for (llvm::StringRef x : llvm::split(value,
',')) {
2244 x.consume_front(
"0x");
2245 if (llvm::to_integer(x, vmaddr, 16))
2250 if (num_keys_decoded > 0)
2258 if (!triple.empty()) {
2261 if (pointer_byte_size) {
2262 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2265 !vendor_name.empty()) {
2266 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2267 if (!environment.empty())
2268 triple.setEnvironmentName(environment);
2270 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2271 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2272 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2273 switch (triple.getObjectFormat()) {
2274 case llvm::Triple::MachO:
2277 case llvm::Triple::ELF:
2280 case llvm::Triple::COFF:
2283 case llvm::Triple::GOFF:
2284 case llvm::Triple::SPIRV:
2285 case llvm::Triple::Wasm:
2286 case llvm::Triple::XCOFF:
2287 case llvm::Triple::DXContainer:
2288 LLDB_LOGF(log,
"error: not supported target architecture");
2290 case llvm::Triple::UnknownObjectFormat:
2291 LLDB_LOGF(log,
"error: failed to determine target architecture");
2295 if (pointer_byte_size) {
2296 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2301 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2303 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2317 process_infos.clear();
2325 bool has_name_match =
false;
2326 if (name && name[0]) {
2327 has_name_match =
true;
2329 switch (name_match_type) {
2331 has_name_match =
false;
2343 packet.
PutCString(
"name_match:starts_with;");
2354 if (has_name_match) {
2362 packet.
Printf(
"pid:%" PRIu64
";",
2365 packet.
Printf(
"parent_pid:%" PRIu64
";",
2372 packet.
Printf(
"euid:%u;",
2375 packet.
Printf(
"egid:%u;",
2381 const llvm::Triple &triple = match_arch.
GetTriple();
2397 process_infos.push_back(process_info);
2406 return process_infos.size();
2410 std::string &name) {
2413 const int packet_len =
2414 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2415 assert(packet_len < (
int)
sizeof(packet));
2437 std::string &name) {
2440 const int packet_len =
2441 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2442 assert(packet_len < (
int)
sizeof(packet));
2464 uint32_t recv_size) {
2466 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2467 uint32_t bytes_left = send_size;
2468 while (bytes_left > 0) {
2469 if (bytes_left >= 26) {
2470 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2473 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2474 "abcdefghijklmnopqrstuvwxyz");
2483 return duration<float>::zero();
2484 using Dur = duration<float>;
2485 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2486 Dur mean = sum / v.size();
2489 float delta = (d - mean).count();
2490 accum += delta * delta;
2493 return Dur(sqrtf(accum / (v.size() - 1)));
2499 uint64_t recv_amount,
2500 bool json,
Stream &strm) {
2505 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2509 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2513 uint32_t result_idx = 0;
2515 std::vector<duration<float>> packet_times;
2517 for (send_size = 0; send_size <= max_send;
2518 send_size ? send_size *= 2 : send_size = 4) {
2519 for (uint32_t recv_size = 0; recv_size <= max_recv;
2520 recv_size ? recv_size *= 2 : recv_size = 4) {
2523 packet_times.clear();
2525 const auto start_time = steady_clock::now();
2526 for (uint32_t i = 0; i < num_packets; ++i) {
2527 const auto packet_start_time = steady_clock::now();
2530 const auto packet_end_time = steady_clock::now();
2531 packet_times.push_back(packet_end_time - packet_start_time);
2533 const auto end_time = steady_clock::now();
2534 const auto total_time = end_time - start_time;
2536 float packets_per_second =
2537 ((float)num_packets) / duration<float>(total_time).count();
2538 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2539 : duration<float>::zero();
2540 const duration<float> standard_deviation =
2543 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2544 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2545 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2546 result_idx > 0 ?
"," :
"", send_size, recv_size,
2547 total_time, standard_deviation);
2550 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2551 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2552 "standard deviation of {5,10:ms+f6}\n",
2553 send_size, recv_size, duration<float>(total_time),
2554 packets_per_second, duration<float>(average_per_packet),
2555 standard_deviation);
2561 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2563 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2564 ": %" PRIu64
",\n \"results\" : [",
2567 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2573 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2578 if (recv_size > 0) {
2579 const auto start_time = steady_clock::now();
2580 uint32_t bytes_read = 0;
2581 uint32_t packet_count = 0;
2582 while (bytes_read < recv_amount) {
2585 bytes_read += recv_size;
2588 const auto end_time = steady_clock::now();
2589 const auto total_time = end_time - start_time;
2590 float mb_second = ((float)recv_amount) /
2591 duration<float>(total_time).count() /
2593 float packets_per_second =
2594 ((float)packet_count) / duration<float>(total_time).count();
2595 const auto average_per_packet = packet_count > 0
2596 ? total_time / packet_count
2597 : duration<float>::zero();
2600 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2601 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2602 result_idx > 0 ?
"," :
"", send_size, recv_size,
2606 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2607 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2608 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2609 send_size, recv_size, packet_count, k_recv_amount_mb,
2610 duration<float>(total_time), mb_second,
2611 packets_per_second, duration<float>(average_per_packet));
2617 strm.
Printf(
"\n ]\n }\n}\n");
2624 uint32_t recv_size) {
2626 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2627 uint32_t bytes_left = send_size;
2628 while (bytes_left > 0) {
2629 if (bytes_left >= 26) {
2630 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2633 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2634 "abcdefghijklmnopqrstuvwxyz");
2645 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2646 std::string &socket_name) {
2649 socket_name.clear();
2654 std::string hostname;
2655 if (remote_accept_hostname && remote_accept_hostname[0])
2656 hostname = remote_accept_hostname;
2658 if (HostInfo::GetHostname(hostname)) {
2660 stream.
Printf(
"host:%s;", hostname.c_str());
2664 stream.
Printf(
"host:*;");
2675 llvm::StringRef name;
2676 llvm::StringRef value;
2679 value.getAsInteger(0, port);
2680 else if (name ==
"pid")
2681 value.getAsInteger(0, pid);
2682 else if (name.compare(
"socket_name") == 0) {
2693 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2694 connection_urls.clear();
2710 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2711 std::optional<StructuredData::Dictionary *> maybe_element =
2720 port = port_osp->GetUnsignedIntegerValue(0);
2722 std::string socket_name;
2725 socket_name = std::string(socket_name_osp->GetStringValue());
2727 if (port != 0 || !socket_name.empty())
2728 connection_urls.emplace_back(port, socket_name);
2730 return connection_urls.size();
2735 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2747 uint64_t tid, uint64_t pid,
char op) {
2753 packet.
Printf(
"p%" PRIx64
".", pid);
2758 packet.
Printf(
"%" PRIx64, tid);
2764 return {{pid, tid}};
2776 return std::nullopt;
2791 return ret.has_value();
2806 return ret.has_value();
2821 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2822 assert(packet_len < (
int)
sizeof(packet));
2841 std::chrono::seconds timeout) {
2843 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2844 __FUNCTION__, insert ?
"add" :
"remove", addr);
2851 const int packet_len =
2852 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2853 insert ?
'Z' :
'z', type, addr, length);
2855 assert(packet_len + 1 < (
int)
sizeof(packet));
2900std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2902 bool &sequence_mutex_unavailable) {
2903 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2907 sequence_mutex_unavailable =
false;
2911 for (packet_result =
2929 ids.push_back(*pid_tid);
2931 }
while (ch ==
',');
2945 ids.emplace_back(1, 1);
2949 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
2950 "packet 'qfThreadInfo'");
2951 sequence_mutex_unavailable =
true;
2958 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
2963 if (ids.empty() || sequence_mutex_unavailable)
2966 for (
auto id : ids) {
2972 thread_ids.push_back(
id.second);
2975 return thread_ids.size();
2988 llvm::StringRef command,
3004 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3008 std::string path{working_dir.
GetPath(
false)};
3015 if (response.
GetChar() !=
'F')
3017 if (response.
GetChar() !=
',')
3022 else if (status_ptr)
3023 *status_ptr = exitcode;
3024 if (response.
GetChar() !=
',')
3029 if (response.
GetChar() !=
',')
3034 command_output->assign(output);
3041 uint32_t file_permissions) {
3042 std::string path{file_spec.
GetPath(
false)};
3048 llvm::StringRef packet = stream.
GetString();
3053 packet.str().c_str());
3055 if (response.
GetChar() !=
'F')
3057 packet.str().c_str());
3064 uint32_t file_permissions) {
3065 std::string path{file_spec.
GetPath(
false)};
3071 llvm::StringRef packet = stream.
GetString();
3078 if (response.
GetChar() !=
'F')
3087#define HANDLE_ERRNO(name, value) \
3090#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3099 if (response.
GetChar() !=
'F')
3101 int32_t result = response.
GetS32(-2, 16);
3104 if (response.
GetChar() ==
',') {
3106 if (result_errno != -1)
3118 std::string path(file_spec.
GetPath(
false));
3139 stream.
Printf(
"vFile:close:%x", (
int)fd);
3148std::optional<GDBRemoteFStatData>
3151 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3155 if (response.
GetChar() !=
'F')
3156 return std::nullopt;
3157 int64_t size = response.
GetS64(-1, 16);
3158 if (size > 0 && response.
GetChar() ==
';') {
3162 if (buffer.size() !=
sizeof(out))
3163 return std::nullopt;
3164 memcpy(&out, buffer.data(),
sizeof(out));
3169 return std::nullopt;
3172std::optional<GDBRemoteFStatData>
3177 return std::nullopt;
3178 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3187 std::string path(file_spec.
GetPath(
false));
3197 if (response.
GetChar() !=
'F')
3206 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3224 while (response.
Peek()) {
3226 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3229 if (response.
GetChar() !=
',')
3237 uint32_t &file_permissions) {
3239 std::string path{file_spec.
GetPath(
false)};
3252 if (response.
GetChar() !=
'F') {
3254 "invalid response to '%s' packet", stream.
GetData());
3256 const uint32_t mode = response.
GetS32(-1, 16);
3257 if (
static_cast<int32_t
>(mode) == -1) {
3258 if (response.
GetChar() ==
',') {
3260 if (response_errno > 0)
3277 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3285 uint64_t offset,
void *dst,
3289 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3294 if (response.
GetChar() !=
'F')
3296 int64_t retcode = response.
GetS64(-1, 16);
3297 if (retcode == -1) {
3299 if (response.
GetChar() ==
',') {
3301 if (response_errno > 0)
3306 const char next = (response.
Peek() ? *response.
Peek() : 0);
3313 const uint64_t data_to_write =
3314 std::min<uint64_t>(dst_len, buffer.size());
3315 if (data_to_write > 0)
3316 memcpy(dst, &buffer[0], data_to_write);
3317 return data_to_write;
3330 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3335 if (response.
GetChar() !=
'F') {
3339 int64_t bytes_written = response.
GetS64(-1, 16);
3340 if (bytes_written == -1) {
3342 if (response.
GetChar() ==
',') {
3344 if (response_errno > 0)
3349 return bytes_written;
3358 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3370 if (response.
GetChar() ==
'F') {
3374 if (response.
GetChar() ==
',') {
3376 if (response_errno > 0)
3391 std::string path{file_spec.
GetPath(
false)};
3401 if (response.
GetChar() ==
'F') {
3405 if (response.
GetChar() ==
',') {
3407 if (response_errno > 0)
3425 std::string path(file_spec.
GetPath(
false));
3434 if (response.
GetChar() !=
'F')
3436 if (response.
GetChar() !=
',')
3438 bool retcode = (response.
GetChar() !=
'0');
3455 std::string path(file_spec.
GetPath(
false));
3462 if (response.
GetChar() !=
'F')
3463 return std::make_error_code(std::errc::illegal_byte_sequence);
3464 if (response.
GetChar() !=
',')
3465 return std::make_error_code(std::errc::illegal_byte_sequence);
3466 if (response.
Peek() && *response.
Peek() ==
'x')
3467 return std::make_error_code(std::errc::no_such_file_or_directory);
3484 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3489 if (part.size() != MD5_HALF_LENGTH)
3490 return std::make_error_code(std::errc::illegal_byte_sequence);
3494 if (part.getAsInteger(16, low))
3495 return std::make_error_code(std::errc::illegal_byte_sequence);
3500 if (part.size() != MD5_HALF_LENGTH)
3501 return std::make_error_code(std::errc::illegal_byte_sequence);
3505 if (part.getAsInteger(16, high))
3506 return std::make_error_code(std::errc::illegal_byte_sequence);
3508 llvm::MD5::MD5Result result;
3509 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3510 result.data(), low);
3511 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3512 result.data() + 8, high);
3516 return std::make_error_code(std::errc::operation_canceled);
3526 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3527 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3528 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3529 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3532 if (gdb_server_version != 0) {
3534 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3535 if (gdb_server_version >= 310)
3548 payload.
Printf(
"p%x", reg);
3557 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3572 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3578 llvm::ArrayRef<uint8_t> data) {
3580 payload.
Printf(
"P%x=", reg_num);
3604 uint32_t &save_id) {
3620 const uint32_t response_save_id = response.
GetU32(0);
3621 if (response_save_id == 0)
3624 save_id = response_save_id;
3637 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3657 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3663llvm::Expected<TraceSupportedResponse>
3668 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3677 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3678 "jLLDBTraceSupported is unsupported");
3680 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3681 "TraceSupportedResponse");
3683 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3684 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3685 "failed to send packet: jLLDBTraceSupported");
3690 std::chrono::seconds timeout) {
3694 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3696 std::string json_string;
3697 llvm::raw_string_ostream os(json_string);
3700 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3709 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3710 "jLLDBTraceStop is unsupported");
3712 return llvm::Error::success();
3713 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3714 "Invalid jLLDBTraceStart response");
3716 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3717 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3718 "failed to send packet: jLLDBTraceStop '%s'",
3724 std::chrono::seconds timeout) {
3728 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3730 std::string json_string;
3731 llvm::raw_string_ostream os(json_string);
3734 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3743 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3744 "jLLDBTraceStart is unsupported");
3746 return llvm::Error::success();
3747 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3748 "Invalid jLLDBTraceStart response");
3750 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3751 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3752 "failed to send packet: jLLDBTraceStart '%s'",
3756llvm::Expected<std::string>
3758 std::chrono::seconds timeout) {
3762 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3764 std::string json_string;
3765 llvm::raw_string_ostream os(json_string);
3768 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3777 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3778 "jLLDBTraceGetState is unsupported");
3779 return std::string(response.
Peek());
3782 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3783 return llvm::createStringError(
3784 llvm::inconvertibleErrorCode(),
3785 "failed to send packet: jLLDBTraceGetState '%s'",
3789llvm::Expected<std::vector<uint8_t>>
3795 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3797 std::string json_string;
3798 llvm::raw_string_ostream os(json_string);
3801 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3811 return std::vector<uint8_t>(data.begin(), data.end());
3813 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3814 return llvm::createStringError(
3815 llvm::inconvertibleErrorCode(),
3816 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3824 return std::nullopt;
3826 return std::nullopt;
3830 const auto &GetOffset = [&] {
3832 if (ref.consumeInteger(16, offset))
3834 result.
offsets.push_back(offset);
3838 if (ref.consume_front(
"Text=")) {
3841 return std::nullopt;
3842 if (!ref.consume_front(
";Data=") || !GetOffset())
3843 return std::nullopt;
3846 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3848 }
else if (ref.consume_front(
"TextSeg=")) {
3851 return std::nullopt;
3854 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3857 return std::nullopt;
3866 std::string module_path = module_file_spec.
GetPath(
false);
3867 if (module_path.empty())
3874 const auto &triple = arch_spec.
GetTriple().getTriple();
3890 llvm::StringRef name;
3891 llvm::StringRef value;
3893 module_spec.
Clear();
3897 if (name ==
"uuid" || name ==
"md5") {
3902 }
else if (name ==
"triple") {
3907 }
else if (name ==
"file_offset") {
3909 if (!value.getAsInteger(16, ival))
3911 }
else if (name ==
"file_size") {
3913 if (!value.getAsInteger(16, ival))
3915 }
else if (name ==
"file_path") {
3926static std::optional<ModuleSpec>
3930 return std::nullopt;
3932 llvm::StringRef string;
3936 return std::nullopt;
3938 return std::nullopt;
3941 return std::nullopt;
3945 return std::nullopt;
3949 return std::nullopt;
3953 return std::nullopt;
3959std::optional<std::vector<ModuleSpec>>
3961 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
3965 return std::nullopt;
3967 json::Array module_array;
3968 for (
const FileSpec &module_file_spec : module_file_specs) {
3969 module_array.push_back(
3970 json::Object{{
"file", module_file_spec.GetPath(
false)},
3971 {
"triple", triple.getTriple()}});
3974 unescaped_payload.
PutCString(
"jModulesInfo:");
3975 unescaped_payload.
AsRawOstream() << std::move(module_array);
3988 return std::nullopt;
3992 return std::nullopt;
3997 if (!response_object_sp)
3998 return std::nullopt;
4001 if (!response_array)
4002 return std::nullopt;
4004 std::vector<ModuleSpec> result;
4005 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
4008 result.push_back(*module_spec);
4018llvm::Expected<std::string>
4020 llvm::StringRef annex) {
4023 llvm::raw_string_ostream output_stream(output);
4037 std::string packet =
4038 (
"qXfer:" +
object +
":read:" + annex +
":" +
4039 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4047 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4048 "Error sending $qXfer packet");
4066 return llvm::createStringError(
4067 llvm::inconvertibleErrorCode(),
4068 "Invalid continuation code from $qXfer packet");
4118 bool symbol_response_provided =
false;
4121 bool first_qsymbol_query =
true;
4132 if (symbol_response_provided || first_qsymbol_query) {
4139 first_qsymbol_query =
false;
4148 if (response_str.starts_with(
"qSymbol:")) {
4150 std::string symbol_name;
4152 if (symbol_name.empty())
4163 switch (sc.symbol->GetType()) {
4196 sc.symbol->GetLoadAddress(&process->
GetTarget());
4209 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4210 symbol_response_provided =
true;
4212 symbol_response_provided =
false;
4228 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4253 "GDBRemoteCommunicationClient::%s(): "
4254 "QSupportedAsyncJSONPackets returned invalid "
4261 "GDBRemoteCommunicationClient::%s(): "
4262 "QSupportedAsyncJSONPackets unsupported",
4270 "GDBRemoteCommunicationClient::%s(): supported async "
4272 __FUNCTION__, stream.
GetData());
4282 llvm::ArrayRef<int32_t> signals) {
4285 auto range = llvm::make_range(signals.begin(), signals.end());
4286 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4298 "Unknown error happened during sending QPassSignals packet.");
4306 if (type_name.empty()) {
4319 config_sp->Dump(unescaped_stream);
4320 unescaped_stream.
Flush();
4338 "configuring StructuredData feature {0} failed with error {1}",
4344 "configuring StructuredData feature {0} failed when sending packet: "
4346 type_name, (
int)result);
4375 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4376 "failed to send k packet");
4378 char packet_cmd = response.
GetChar(0);
4379 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4382 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4383 "unexpected response to k packet: %s",
static llvm::raw_ostream & error(Stream &strm)
duration< float > calculate_standard_deviation(const std::vector< duration< float > > &v)
static std::optional< ModuleSpec > ParseModuleSpec(StructuredData::Dictionary *dict)
static int gdb_errno_to_system(int err)
static void ParseOSType(llvm::StringRef value, std::string &os_name, std::string &environment)
static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response, uint64_t fail_result, Status &error)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
A command line argument class.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
void Clear()
Clear the arguments.
bool IsConnected() const
Check if the connection is valid.
virtual lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr)
Disconnect the communications connection if one is currently connected.
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
llvm::StringRef GetCursorArgumentPrefix() const
A uniqued constant string class.
A subclass of DataBuffer that stores a data buffer on the heap.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void SetFlash(OptionalBool val)
void SetMapped(OptionalBool val)
void SetBlocksize(lldb::offset_t blocksize)
void SetMemoryTagged(OptionalBool val)
void SetReadable(OptionalBool val)
void SetExecutable(OptionalBool val)
void SetIsStackMemory(OptionalBool val)
void SetPageSize(int pagesize)
void SetName(const char *name)
void SetWritable(OptionalBool val)
lldb::offset_t GetBlocksize() const
void SetDirtyPageList(std::vector< lldb::addr_t > pagelist)
OptionalBool GetFlash() const
void SetIsShadowStack(OptionalBool val)
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
void SetObjectSize(uint64_t object_size)
ArchSpec & GetArchitecture()
void SetObjectOffset(uint64_t object_offset)
void SetGroupID(uint32_t gid)
bool ProcessIDIsValid() const
void SetArg0(llvm::StringRef arg)
const char * GetName() const
lldb::pid_t GetProcessID() const
void SetProcessID(lldb::pid_t pid)
FileSpec & GetExecutableFile()
bool UserIDIsValid() const
uint32_t GetUserID() const
uint32_t GetGroupID() const
void SetUserID(uint32_t uid)
bool GroupIDIsValid() const
ArchSpec & GetArchitecture()
bool MatchAllProcesses() const
NameMatch GetNameMatchType() const
bool GetMatchAllUsers() const
ProcessInstanceInfo & GetProcessInfo()
uint32_t GetEffectiveUserID() const
void SetEffectiveGroupID(uint32_t gid)
lldb::pid_t GetParentProcessID() const
bool ParentProcessIDIsValid() const
uint32_t GetEffectiveGroupID() const
bool EffectiveUserIDIsValid() const
bool EffectiveGroupIDIsValid() const
void SetParentProcessID(lldb::pid_t pid)
void SetEffectiveUserID(uint32_t uid)
A plug-in interface definition class for debugging a process.
Target & GetTarget()
Get the target object pointer for this module.
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
const char * GetData() const
void Flush() override
Flush the stream.
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t PutStringAsRawHex8(llvm::StringRef s)
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
virtual void Flush()=0
Flush the stream.
size_t EOL()
Output and End of Line character to the stream.
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
ObjectSP GetItemAtIndex(size_t idx) const
std::optional< Dictionary * > GetItemAtIndexAsDictionary(size_t idx) const
Retrieves the element at index idx from a StructuredData::Array if it is a Dictionary.
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
ObjectSP GetValueForKey(llvm::StringRef key) const
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
Defines a list of symbol context objects.
Defines a symbol context baton that can be handed other debug core functions.
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
Represents UUID's of various sizes.
bool SetFromStringRef(llvm::StringRef str)
XMLNode GetRootElement(const char *required_name=nullptr)
bool ParseMemory(const char *xml, size_t xml_length, const char *url="untitled.xml")
void ForEachChildElement(NodeCallback const &callback) const
llvm::StringRef GetName() const
std::string GetAttributeValue(const char *name, const char *fail_value=nullptr) const
bool GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value=0, int base=0) const
bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value, uint64_t fail_value=0, int base=0) const
GDBRemoteClientBase(const char *comm_name)
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0), bool sync_on_timeout=true)
PacketResult SendPacketAndWaitForResponseNoLock(llvm::StringRef payload, StringExtractorGDBRemote &response, bool sync_on_timeout=true)
virtual void OnRunPacketSent(bool first)
lldb::DataBufferSP ReadRegister(lldb::tid_t tid, uint32_t reg_num)
std::chrono::seconds m_default_packet_timeout
LazyBool m_supports_vCont_S
LazyBool m_supports_detach_stay_stopped
LazyBool m_supports_alloc_dealloc_memory
bool SupportsGDBStoppointPacket(GDBStoppointType type)
ArchSpec GetSystemArchitecture()
bool RestoreRegisterState(lldb::tid_t tid, uint32_t save_id)
const ArchSpec & GetHostArchitecture()
int SendLaunchArchPacket(const char *arch)
lldb::pid_t GetCurrentProcessID(bool allow_lazy=true)
bool AvoidGPackets(ProcessGDBRemote *process)
llvm::VersionTuple GetMacCatalystVersion()
Status CreateSymlink(const FileSpec &src, const FileSpec &dst)
PacketResult SendThreadSpecificPacketAndWaitForResponse(lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response)
LazyBool m_qGDBServerVersion_is_valid
bool GetLoadedDynamicLibrariesInfosSupported()
bool GetHostInfo(bool force=false)
LazyBool m_supports_memory_region_info
LazyBool m_qHostInfo_is_valid
bool KillSpawnedProcess(lldb::pid_t pid)
bool m_supports_jModulesInfo
lldb_private::AddressableBits GetAddressableBits()
LazyBool m_supports_jGetSharedCacheInfo
bool GetReverseContinueSupported()
bool 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
std::optional< xPacketState > m_x_packet_state
void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm)
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions)
std::string m_host_distribution_id
GDBRemoteCommunicationClient()
std::optional< std::string > GetOSBuildString()
bool LaunchGDBServer(const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port, std::string &socket_name)
int SetSTDOUT(const FileSpec &file_spec)
LazyBool m_prepare_for_reg_writing_reply
bool m_supports_qThreadStopInfo
bool SetCurrentThreadForRun(uint64_t tid, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
uint8_t SendGDBStoppointTypePacket(GDBStoppointType type, bool insert, lldb::addr_t addr, uint32_t length, std::chrono::seconds interrupt_timeout)
bool GetpPacketSupported(lldb::tid_t tid)
Status MakeDirectory(const FileSpec &file_spec, uint32_t mode)
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
bool GetReverseStepSupported()
uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error)
LazyBool m_supports_vCont_s
bool m_supports_qGroupName
bool SetCurrentThread(uint64_t tid, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
bool m_supports_vFileExists
bool GetDefaultThreadId(lldb::tid_t &tid)
void ServeSymbolLookups(lldb_private::Process *process)
LazyBool m_uses_native_signals
uint32_t m_low_mem_addressing_bits
lldb::tid_t m_curr_tid
Current gdb remote protocol thread identifier for all other operations.
LazyBool m_supports_qXfer_memory_map_read
bool GetHostname(std::string &s)
llvm::Expected< int > KillProcess(lldb::pid_t pid)
bool m_supported_async_json_packets_is_valid
bool GetSyncThreadStateSupported()
bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef< uint8_t > data)
bool m_supports_QEnvironmentHexEncoded
bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info)
Status SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
LazyBool m_curr_pid_is_valid
Status GetQXferMemoryMapRegionInfo(lldb::addr_t addr, MemoryRegionInfo ®ion)
int SetDetachOnError(bool enable)
Sets the DetachOnError flag to enable for the process controlled by the stub.
void OnRunPacketSent(bool first) override
bool m_supports_QEnvironment
lldb::addr_t GetShlibInfoAddr()
Status SendSignalsToIgnore(llvm::ArrayRef< int32_t > signals)
LazyBool m_supports_jThreadExtendedInfo
LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr)
UUID m_process_standalone_uuid
LazyBool m_supports_not_sending_acks
LazyBool m_supports_watchpoint_support_info
bool WriteRegister(lldb::tid_t tid, uint32_t reg_num, llvm::ArrayRef< uint8_t > data)
uint64_t m_max_packet_size
void EnableErrorStringInPacket()
llvm::Expected< std::vector< uint8_t > > SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request, std::chrono::seconds interrupt_timeout)
LazyBool m_supports_qXfer_libraries_read
bool GetSaveCoreSupported() const
LazyBool m_supports_jLoadedDynamicLibrariesInfos
Status LoadQXferMemoryMap()
LazyBool m_supports_thread_suffix
int SetSTDIN(const FileSpec &file_spec)
Sets the path to use for stdin/out/err for a process that will be launched with the 'A' packet.
LazyBool m_supports_vCont_C
lldb::pid_t m_curr_pid
Current gdb remote protocol process identifier for all other operations.
Status WriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, const std::vector< uint8_t > &tags)
LazyBool m_supports_qSaveCore
LazyBool m_supports_reverse_step
bool GetQXferLibrariesSVR4ReadSupported()
size_t GetCurrentThreadIDs(std::vector< lldb::tid_t > &thread_ids, bool &sequence_mutex_unavailable)
Status Detach(bool keep_stopped, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
std::optional< bool > GetWatchpointReportedAfter()
std::string m_gdb_server_name
std::vector< lldb::addr_t > GetProcessStandaloneBinaries()
bool m_supports_qProcessInfoPID
llvm::VersionTuple m_os_version
bool GetQXferLibrariesReadSupported()
llvm::VersionTuple m_maccatalyst_version
int SetDisableASLR(bool enable)
Sets the disable ASLR flag to enable for a process that will be launched with the 'A' packet.
bool GetUserName(uint32_t uid, std::string &name)
Status GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info)
std::vector< MemoryRegionInfo > m_qXfer_memory_map
bool SyncThreadState(lldb::tid_t tid)
bool m_supports_qfProcessInfo
std::chrono::seconds GetHostDefaultPacketTimeout()
int SendStdinNotification(const char *data, size_t data_len)
Sends a GDB remote protocol 'I' packet that delivers stdin data to the remote process.
bool GetThreadExtendedInfoSupported()
lldb::DataBufferSP ReadAllRegisters(lldb::tid_t tid)
bool GetMemoryTaggingSupported()
void AutoCompleteDiskFileOrDirectory(CompletionRequest &request, bool only_dir)
lldb::pid_t m_curr_pid_run
Current gdb remote protocol process identifier for continue, step, etc.
LazyBool m_supports_multiprocess
void MaybeEnableCompression(llvm::ArrayRef< llvm::StringRef > supported_compressions)
bool GetDynamicLoaderProcessStateSupported()
const ArchSpec & GetProcessArchitecture()
bool DeallocateMemory(lldb::addr_t addr)
llvm::Expected< TraceSupportedResponse > SendTraceSupported(std::chrono::seconds interrupt_timeout)
bool GetQXferAuxvReadSupported()
xPacketState GetxPacketState()
llvm::ErrorOr< llvm::MD5::MD5Result > CalculateMD5(const FileSpec &file_spec)
uint32_t GetGDBServerProgramVersion()
LazyBool m_supports_reverse_continue
llvm::Error SendTraceStart(const llvm::json::Value &request, std::chrono::seconds interrupt_timeout)
bool GetStopReply(StringExtractorGDBRemote &response)
bool m_supports_qUserName
bool GetQXferMemoryMapReadSupported()
bool m_qXfer_memory_map_loaded
bool GetModuleInfo(const FileSpec &module_file_spec, const ArchSpec &arch_spec, ModuleSpec &module_spec)
LazyBool m_supports_vCont_all
std::optional< PidTid > SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid, char op)
bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size)
LazyBool m_supports_multi_mem_read
LazyBool m_supports_QPassSignals
bool GetFileExists(const FileSpec &file_spec)
Status GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
uint32_t FindProcesses(const ProcessInstanceInfoMatch &process_match_info, ProcessInstanceInfoList &process_infos)
lldb::DataBufferSP ReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type)
bool GetMultiMemReadSupported()
bool GetQXferSigInfoReadSupported()
uint32_t m_gdb_server_version
int SetWorkingDir(const FileSpec &working_dir)
Sets the working directory to path for a process that will be launched with the 'A' packet for non pl...
LazyBool m_avoid_g_packets
std::vector< std::pair< lldb::pid_t, lldb::tid_t > > GetCurrentProcessAndThreadIDs(bool &sequence_mutex_unavailable)
bool GetThreadStopInfo(lldb::tid_t tid, StringExtractorGDBRemote &response)
bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id)
bool GetProcessStandaloneBinary(UUID &uuid, lldb::addr_t &value, bool &value_is_offset)
LazyBool m_supports_QSaveRegisterState
WatchpointHardwareFeature m_watchpoint_types
void GetListThreadsInStopReplySupported()
StructuredData::ObjectSP GetThreadsInfo()
std::string m_qSupported_response
bool GetSharedCacheInfoSupported()
LazyBool m_supports_qXfer_auxv_read
bool m_supports_qModuleInfo
const char * GetGDBServerProgramName()
LazyBool m_supports_jGetDyldProcessState
int SendEnvironmentPacket(char const *name_equal_value)
Sends a "QEnvironment:NAME=VALUE" packet that will build up the environment that will get used when l...
std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout)
LazyBool m_supports_qEcho
CompressionType m_compression_type
std::chrono::seconds GetPacketTimeout() const
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_CPUTYPE
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
lldb::ByteOrder InlHostByteOrder()
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const QOffsets &offsets)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
llvm::json::Value toJSON(const TraceSupportedResponse &packet)
@ eErrorTypeGeneric
Generic errors that can be any value.
@ eErrorTypePOSIX
POSIX error codes.
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
bool Contains(BaseType r) const
BaseType GetRangeBase() const
void SetRangeEnd(BaseType end)
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
BaseType GetRangeEnd() const
void SetByteSize(SizeType s)
jLLDBTraceGetBinaryData gdb-remote packet
jLLDBTraceStop gdb-remote packet
The offsets used by the target when relocating the executable.
bool segments
If true, the offsets field describes segments.
std::vector< uint64_t > offsets
The individual offsets.