36#include "lldb/Host/Config.h"
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/StringSwitch.h"
41#include "llvm/Support/JSON.h"
43#if defined(HAVE_LIBCOMPRESSION)
44#include <compression.h>
50using namespace std::chrono;
54 return os << llvm::formatv(
55 "QOffsets({0}, [{1:@[x]}])", offsets.
segments,
63 m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
64 m_supports_qUserName(true), m_supports_qGroupName(true),
65 m_supports_qThreadStopInfo(true), m_supports_z0(true),
66 m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
67 m_supports_z4(true), m_supports_QEnvironment(true),
68 m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
69 m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
70 m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
71 m_supports_vFileSize(true), m_supports_vFileMode(true),
72 m_supports_vFileExists(true), m_supports_vRun(true),
74 m_host_arch(), m_host_distribution_id(), m_process_arch(), m_os_build(),
75 m_os_kernel(), m_hostname(), m_gdb_server_name(),
76 m_default_packet_timeout(0), m_qSupported_response(),
77 m_supported_async_json_packets_sp(), m_qXfer_memory_map() {}
90 std::chrono::steady_clock::time_point start_of_handshake =
91 std::chrono::steady_clock::now();
100 std::chrono::steady_clock::time_point end_of_handshake =
101 std::chrono::steady_clock::now();
102 auto handshake_timeout =
103 std::chrono::duration<double>(end_of_handshake - start_of_handshake)
108 "while waiting for reply to initial "
112 "failed to get reply to handshake packet within timeout of "
354 std::vector<std::string> features = {
"xmlRegisters=i386,arm,mips,arc",
355 "multiprocess+",
"fork-events+",
359 for (uint32_t i = 0; i < features.size(); ++i) {
371 for (llvm::StringRef x : llvm::split(response.
GetStringRef(),
';')) {
372 if (x ==
"qXfer:auxv:read+")
374 else if (x ==
"qXfer:libraries-svr4:read+")
376 else if (x ==
"augmented-libraries-svr4-read") {
379 }
else if (x ==
"qXfer:libraries:read+")
381 else if (x ==
"qXfer:features:read+")
383 else if (x ==
"qXfer:memory-map:read+")
385 else if (x ==
"qXfer:siginfo:read+")
387 else if (x ==
"qEcho")
389 else if (x ==
"QPassSignals+")
391 else if (x ==
"multiprocess+")
393 else if (x ==
"memory-tagging+")
395 else if (x ==
"qSaveCore+")
397 else if (x ==
"native-signals+")
402 else if (x.consume_front(
"SupportedCompressions=")) {
403 llvm::SmallVector<llvm::StringRef, 4> compressions;
404 x.split(compressions,
',');
405 if (!compressions.empty())
407 }
else if (x.consume_front(
"SupportedWatchpointTypes=")) {
408 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
409 x.split(watchpoint_types,
',');
411 for (
auto wp_type : watchpoint_types) {
412 if (wp_type ==
"x86_64")
414 if (wp_type ==
"aarch64-mask")
416 if (wp_type ==
"aarch64-bas")
419 }
else if (x.consume_front(
"PacketSize=")) {
426 LLDB_LOGF(log,
"Garbled PacketSize spec in qSupported response");
456 const char *response_cstr = response.
GetStringRef().data();
457 if (::strstr(response_cstr,
";c"))
460 if (::strstr(response_cstr,
";C"))
463 if (::strstr(response_cstr,
";s"))
466 if (::strstr(response_cstr,
";S"))
512 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
514 __FUNCTION__, payload.GetData());
519 payload.Printf(
";thread:%4.4" PRIx64
";", tid);
566 }
else if (!response.
Empty()) {
655 packet.
Printf(
"qMemTags:%" PRIx64
",%zx:%" PRIx32, addr, len, type);
663 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s: qMemTags packet failed",
671 if (response.
GetChar() !=
'm') {
673 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
684 if (response.
GetBytesLeft() || (expected_bytes != got_bytes)) {
687 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
697 const std::vector<uint8_t> &tags) {
700 packet.
Printf(
"QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr, len, type);
718 snprintf(packet,
sizeof(packet),
"x0,0");
745 if (response.
GetChar() ==
'Q') {
746 if (response.
GetChar() ==
'C') {
760 bool sequence_mutex_unavailable;
762 if (!ids.empty() && !sequence_mutex_unavailable) {
779 return llvm::createStringError(llvm::inconvertibleErrorCode(),
780 "Nothing to launch");
793 return llvm::createStringError(llvm::inconvertibleErrorCode(),
794 "Sending vRun packet failed");
803 return llvm::Error::success();
811 llvm::ListSeparator LS(
",");
812 for (
const auto &arg : llvm::enumerate(args)) {
814 packet.
Format(
"{0},{1},", arg.value().ref().size() * 2, arg.index());
821 return llvm::createStringError(llvm::inconvertibleErrorCode(),
822 "Sending A packet failed");
829 return llvm::createStringError(llvm::inconvertibleErrorCode(),
830 "Sending qLaunchSuccess packet failed");
833 return llvm::Error::success();
834 if (response.
GetChar() ==
'E') {
835 return llvm::createStringError(llvm::inconvertibleErrorCode(),
838 return llvm::createStringError(llvm::inconvertibleErrorCode(),
839 "unknown error occurred launching process");
843 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
844 for (
const auto &kv : env)
845 vec.emplace_back(kv.first(), kv.second);
846 llvm::sort(vec, llvm::less_first());
847 for (
const auto &[k, v] : vec) {
856 char const *name_equal_value) {
857 if (name_equal_value && name_equal_value[0]) {
858 bool send_hex_encoding =
false;
859 for (
const char *p = name_equal_value; *p !=
'\0' && !send_hex_encoding;
861 if (llvm::isPrint(*p)) {
867 send_hex_encoding =
true;
874 send_hex_encoding =
true;
882 packet.
Printf(
"QEnvironment:%s", name_equal_value);
923 if (arch && arch[0]) {
925 packet.
Printf(
"QLaunchArch:%s", arch);
940 char const *data,
bool *was_supported) {
941 if (data && *data !=
'\0') {
943 packet.
Printf(
"QSetProcessEvent:%s", data);
949 *was_supported =
true;
953 *was_supported =
false;
958 *was_supported =
true;
985std::optional<std::string>
1019 UUID &uuid,
addr_t &value,
bool &value_is_offset) {
1052 llvm::StringRef name, value;
1053 bool success =
false;
1055 if (name ==
"name") {
1058 }
else if (name ==
"version") {
1059 llvm::StringRef major, minor;
1060 std::tie(major, minor) = value.split(
'.');
1074 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1076 llvm::StringRef avail_name;
1078#if defined(HAVE_LIBCOMPRESSION)
1080 for (
auto compression : supported_compressions) {
1081 if (compression ==
"lzfse") {
1083 avail_name = compression;
1090#if defined(HAVE_LIBCOMPRESSION)
1092 for (
auto compression : supported_compressions) {
1093 if (compression ==
"zlib-deflate") {
1095 avail_name = compression;
1104 for (
auto compression : supported_compressions) {
1105 if (compression ==
"zlib-deflate") {
1107 avail_name = compression;
1114#if defined(HAVE_LIBCOMPRESSION)
1116 for (
auto compression : supported_compressions) {
1117 if (compression ==
"lz4") {
1119 avail_name = compression;
1126#if defined(HAVE_LIBCOMPRESSION)
1128 for (
auto compression : supported_compressions) {
1129 if (compression ==
"lzma") {
1131 avail_name = compression;
1140 std::string packet =
"QEnableCompression:type:" + avail_name.str() +
";";
1187 tid = pid_tid->second;
1194 std::string &environment) {
1195 if (value ==
"iossimulator" || value ==
"tvossimulator" ||
1196 value ==
"watchossimulator" || value ==
"xrossimulator" ||
1197 value ==
"visionossimulator") {
1198 environment =
"simulator";
1199 os_name = value.drop_back(environment.size()).str();
1200 }
else if (value ==
"maccatalyst") {
1202 environment =
"macabi";
1204 os_name = value.str();
1220 llvm::StringRef name;
1221 llvm::StringRef value;
1224 std::string arch_name;
1225 std::string os_name;
1226 std::string environment;
1227 std::string vendor_name;
1229 uint32_t pointer_byte_size = 0;
1231 uint32_t num_keys_decoded = 0;
1233 if (name ==
"cputype") {
1235 if (!value.getAsInteger(0, cpu))
1237 }
else if (name ==
"cpusubtype") {
1239 if (!value.getAsInteger(0, sub))
1241 }
else if (name ==
"arch") {
1242 arch_name = std::string(value);
1244 }
else if (name ==
"triple") {
1248 }
else if (name ==
"distribution_id") {
1252 }
else if (name ==
"os_build") {
1256 }
else if (name ==
"hostname") {
1260 }
else if (name ==
"os_kernel") {
1264 }
else if (name ==
"ostype") {
1267 }
else if (name ==
"vendor") {
1268 vendor_name = std::string(value);
1270 }
else if (name ==
"endian") {
1271 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1278 }
else if (name ==
"ptrsize") {
1279 if (!value.getAsInteger(0, pointer_byte_size))
1281 }
else if (name ==
"addressing_bits") {
1285 }
else if (name ==
"high_mem_addressing_bits") {
1288 }
else if (name ==
"low_mem_addressing_bits") {
1291 }
else if (name ==
"os_version" ||
1298 }
else if (name ==
"maccatalyst_version") {
1301 }
else if (name ==
"watchpoint_exceptions_received") {
1303 llvm::StringSwitch<LazyBool>(value)
1309 }
else if (name ==
"default_packet_timeout") {
1310 uint32_t timeout_seconds;
1311 if (!value.getAsInteger(0, timeout_seconds)) {
1316 }
else if (name ==
"vm-page-size") {
1318 if (!value.getAsInteger(0, page_size)) {
1325 if (num_keys_decoded > 0)
1328 if (triple.empty()) {
1329 if (arch_name.empty()) {
1332 if (pointer_byte_size) {
1339 if (!vendor_name.empty())
1341 llvm::StringRef(vendor_name));
1342 if (!os_name.empty())
1344 if (!environment.empty())
1349 triple += arch_name;
1350 if (!vendor_name.empty() || !os_name.empty()) {
1352 if (vendor_name.empty())
1353 triple +=
"unknown";
1355 triple += vendor_name;
1357 if (os_name.empty())
1358 triple +=
"unknown";
1365 if (host_triple.getVendor() == llvm::Triple::Apple &&
1366 host_triple.getOS() == llvm::Triple::Darwin) {
1368 case llvm::Triple::aarch64:
1369 case llvm::Triple::aarch64_32:
1370 case llvm::Triple::arm:
1371 case llvm::Triple::thumb:
1372 host_triple.setOS(llvm::Triple::IOS);
1375 host_triple.setOS(llvm::Triple::MacOSX);
1379 if (pointer_byte_size) {
1388 if (pointer_byte_size) {
1396 "GDBRemoteCommunicationClient::%s parsed host "
1397 "architecture as %s, triple as %s from triple text %s",
1401 :
"<null-arch-name>",
1441 return addressable_bits;
1451 uint32_t permissions) {
1455 const int packet_len = ::snprintf(
1456 packet,
sizeof(packet),
"_M%" PRIx64
",%s%s%s", (uint64_t)size,
1457 permissions & lldb::ePermissionsReadable ?
"r" :
"",
1458 permissions & lldb::ePermissionsWritable ?
"w" :
"",
1459 permissions & lldb::ePermissionsExecutable ?
"x" :
"");
1460 assert(packet_len < (
int)
sizeof(packet));
1480 const int packet_len =
1481 ::snprintf(packet,
sizeof(packet),
"_m%" PRIx64, (uint64_t)addr);
1482 assert(packet_len < (
int)
sizeof(packet));
1507 const int packet_len =
1508 ::snprintf(packet,
sizeof(packet),
"qSupportsDetachAndStayStopped:");
1509 assert(packet_len < (
int)
sizeof(packet));
1522 error.SetErrorString(
"Stays stopped not supported by this target.");
1537 error.SetErrorString(
"Multiprocess extension not supported by the server.");
1545 error.SetErrorString(
"Sending isconnect packet failed.");
1552 region_info.
Clear();
1557 const int packet_len = ::snprintf(
1558 packet,
sizeof(packet),
"qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1559 assert(packet_len < (
int)
sizeof(packet));
1565 llvm::StringRef name;
1566 llvm::StringRef value;
1568 bool success =
true;
1569 bool saw_permissions =
false;
1571 if (name ==
"start") {
1572 if (!value.getAsInteger(16, addr_value))
1574 }
else if (name ==
"size") {
1575 if (!value.getAsInteger(16, addr_value)) {
1583 }
else if (name ==
"permissions" && region_info.
GetRange().
IsValid()) {
1584 saw_permissions =
true;
1586 if (value.contains(
'r'))
1591 if (value.contains(
'w'))
1596 if (value.contains(
'x'))
1610 }
else if (name ==
"name") {
1614 region_info.
SetName(name.c_str());
1615 }
else if (name ==
"flags") {
1618 llvm::StringRef flags = value;
1619 llvm::StringRef flag;
1620 while (flags.size()) {
1621 flags = flags.ltrim();
1622 std::tie(flag, flags) = flags.split(
' ');
1631 }
else if (name ==
"type") {
1632 std::string comma_sep_str = value.str();
1634 while ((comma_pos = comma_sep_str.find(
',')) != std::string::npos) {
1635 comma_sep_str[comma_pos] =
'\0';
1636 if (comma_sep_str ==
"stack") {
1641 if (comma_sep_str ==
"stack") {
1644 }
else if (name ==
"error") {
1646 std::string error_string;
1649 error.SetErrorString(error_string.c_str());
1650 }
else if (name ==
"dirty-pages") {
1651 std::vector<addr_t> dirty_page_list;
1652 for (llvm::StringRef x : llvm::split(value,
',')) {
1654 x.consume_front(
"0x");
1655 if (llvm::to_integer(x, page, 16))
1656 dirty_page_list.push_back(page);
1668 if (!saw_permissions) {
1676 error.SetErrorString(
"Server returned invalid range");
1684 error.SetErrorString(
"qMemoryRegionInfo is not supported");
1696 region_info = qXfer_region_info;
1699 region_info.
Clear();
1701 }
else if (qXfer_error.
Success()) {
1716 if (!
error.Success())
1719 if (map_region.GetRange().Contains(addr)) {
1720 region = map_region;
1724 error.SetErrorString(
"Region not found");
1737 error.SetErrorString(
"XML is not supported");
1742 error.SetErrorString(
"Memory map is not supported");
1746 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1748 return Status(xml.takeError());
1752 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1753 error.SetErrorString(
"Failed to parse memory map xml");
1759 error.SetErrorString(
"Invalid root node in memory map xml");
1768 if (memory_node.
GetName() !=
"memory")
1779 region.GetRange().SetByteSize(length);
1780 if (type ==
"rom") {
1783 }
else if (type ==
"ram") {
1787 }
else if (type ==
"flash") {
1790 [®ion](
const XMLNode &prop_node) ->
bool {
1793 if (prop_node.
GetName() !=
"property")
1796 if (propname ==
"blocksize") {
1799 region.SetBlocksize(blocksize);
1818 std::optional<uint32_t> num;
1824 llvm::StringRef name;
1825 llvm::StringRef value;
1827 if (name ==
"num") {
1843WatchpointHardwareFeature
1862 return std::nullopt;
1867 std::string path{file_spec.
GetPath(
false)};
1887 std::string path{file_spec.
GetPath(
false)};
1907 std::string path{file_spec.
GetPath(
false)};
1936 return !cwd.empty();
1943 std::string path{working_dir.
GetPath(
false)};
1963 const int packet_len =
1964 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
1965 assert(packet_len < (
int)
sizeof(packet));
1980 const int packet_len = ::snprintf(packet,
sizeof(packet),
1981 "QSetDetachOnError:%i", enable ? 1 : 0);
1982 assert(packet_len < (
int)
sizeof(packet));
1998 llvm::StringRef name;
1999 llvm::StringRef value;
2005 std::string os_type;
2008 if (name ==
"pid") {
2010 value.getAsInteger(0, pid);
2012 }
else if (name ==
"ppid") {
2014 value.getAsInteger(0, pid);
2016 }
else if (name ==
"uid") {
2018 value.getAsInteger(0, uid);
2020 }
else if (name ==
"euid") {
2022 value.getAsInteger(0, uid);
2024 }
else if (name ==
"gid") {
2026 value.getAsInteger(0, gid);
2028 }
else if (name ==
"egid") {
2030 value.getAsInteger(0, gid);
2032 }
else if (name ==
"triple") {
2037 }
else if (name ==
"name") {
2044 }
else if (name ==
"args") {
2045 llvm::StringRef encoded_args(value), hex_arg;
2047 bool is_arg0 =
true;
2048 while (!encoded_args.empty()) {
2049 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2064 }
else if (name ==
"cputype") {
2065 value.getAsInteger(0, cpu);
2066 }
else if (name ==
"cpusubtype") {
2067 value.getAsInteger(0, sub);
2068 }
else if (name ==
"vendor") {
2069 vendor = std::string(value);
2070 }
else if (name ==
"ostype") {
2071 os_type = std::string(value);
2076 if (vendor ==
"apple") {
2080 llvm::StringRef(vendor));
2082 llvm::StringRef(os_type));
2094 process_info.
Clear();
2098 const int packet_len =
2099 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2100 assert(packet_len < (
int)
sizeof(packet));
2130 llvm::StringRef name;
2131 llvm::StringRef value;
2134 std::string arch_name;
2135 std::string os_name;
2136 std::string environment;
2137 std::string vendor_name;
2139 std::string elf_abi;
2140 uint32_t pointer_byte_size = 0;
2143 uint32_t num_keys_decoded = 0;
2146 if (name ==
"cputype") {
2147 if (!value.getAsInteger(16, cpu))
2149 }
else if (name ==
"cpusubtype") {
2150 if (!value.getAsInteger(16, sub)) {
2156 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2157 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2164 }
else if (name ==
"triple") {
2168 }
else if (name ==
"ostype") {
2171 }
else if (name ==
"vendor") {
2172 vendor_name = std::string(value);
2174 }
else if (name ==
"endian") {
2175 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2182 }
else if (name ==
"ptrsize") {
2183 if (!value.getAsInteger(16, pointer_byte_size))
2185 }
else if (name ==
"pid") {
2186 if (!value.getAsInteger(16, pid))
2188 }
else if (name ==
"elf_abi") {
2189 elf_abi = std::string(value);
2191 }
else if (name ==
"main-binary-uuid") {
2194 }
else if (name ==
"main-binary-slide") {
2202 }
else if (name ==
"main-binary-address") {
2210 }
else if (name ==
"binary-addresses") {
2213 for (llvm::StringRef x : llvm::split(value,
',')) {
2215 x.consume_front(
"0x");
2216 if (llvm::to_integer(x, vmaddr, 16))
2221 if (num_keys_decoded > 0)
2229 if (!triple.empty()) {
2232 if (pointer_byte_size) {
2236 !vendor_name.empty()) {
2237 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2238 if (!environment.empty())
2239 triple.setEnvironmentName(environment);
2241 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2242 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2243 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2244 switch (triple.getObjectFormat()) {
2245 case llvm::Triple::MachO:
2248 case llvm::Triple::ELF:
2251 case llvm::Triple::COFF:
2254 case llvm::Triple::GOFF:
2255 case llvm::Triple::SPIRV:
2256 case llvm::Triple::Wasm:
2257 case llvm::Triple::XCOFF:
2258 case llvm::Triple::DXContainer:
2259 LLDB_LOGF(log,
"error: not supported target architecture");
2261 case llvm::Triple::UnknownObjectFormat:
2262 LLDB_LOGF(log,
"error: failed to determine target architecture");
2266 if (pointer_byte_size) {
2288 process_infos.clear();
2296 bool has_name_match =
false;
2297 if (name && name[0]) {
2298 has_name_match =
true;
2300 switch (name_match_type) {
2302 has_name_match =
false;
2314 packet.
PutCString(
"name_match:starts_with;");
2325 if (has_name_match) {
2333 packet.
Printf(
"pid:%" PRIu64
";",
2336 packet.
Printf(
"parent_pid:%" PRIu64
";",
2343 packet.
Printf(
"euid:%u;",
2346 packet.
Printf(
"egid:%u;",
2352 const llvm::Triple &triple = match_arch.
GetTriple();
2368 process_infos.push_back(process_info);
2377 return process_infos.size();
2381 std::string &name) {
2384 const int packet_len =
2385 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2386 assert(packet_len < (
int)
sizeof(packet));
2408 std::string &name) {
2411 const int packet_len =
2412 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2413 assert(packet_len < (
int)
sizeof(packet));
2435 uint32_t recv_size) {
2437 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2438 uint32_t bytes_left = send_size;
2439 while (bytes_left > 0) {
2440 if (bytes_left >= 26) {
2441 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2444 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2445 "abcdefghijklmnopqrstuvwxyz");
2454 return duration<float>::zero();
2455 using Dur = duration<float>;
2456 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2457 Dur mean = sum / v.size();
2460 float delta = (d - mean).count();
2461 accum += delta * delta;
2464 return Dur(sqrtf(accum / (v.size() - 1)));
2470 uint64_t recv_amount,
2471 bool json,
Stream &strm) {
2476 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2480 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2484 uint32_t result_idx = 0;
2486 std::vector<duration<float>> packet_times;
2488 for (send_size = 0; send_size <= max_send;
2489 send_size ? send_size *= 2 : send_size = 4) {
2490 for (uint32_t recv_size = 0; recv_size <= max_recv;
2491 recv_size ? recv_size *= 2 : recv_size = 4) {
2494 packet_times.clear();
2496 const auto start_time = steady_clock::now();
2497 for (uint32_t i = 0; i < num_packets; ++i) {
2498 const auto packet_start_time = steady_clock::now();
2501 const auto packet_end_time = steady_clock::now();
2502 packet_times.push_back(packet_end_time - packet_start_time);
2504 const auto end_time = steady_clock::now();
2505 const auto total_time = end_time - start_time;
2507 float packets_per_second =
2508 ((float)num_packets) / duration<float>(total_time).count();
2509 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2510 : duration<float>::zero();
2511 const duration<float> standard_deviation =
2514 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2515 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2516 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2517 result_idx > 0 ?
"," :
"", send_size, recv_size,
2518 total_time, standard_deviation);
2521 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2522 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2523 "standard deviation of {5,10:ms+f6}\n",
2524 send_size, recv_size, duration<float>(total_time),
2525 packets_per_second, duration<float>(average_per_packet),
2526 standard_deviation);
2532 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2534 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2535 ": %" PRIu64
",\n \"results\" : [",
2538 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2544 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2549 if (recv_size > 0) {
2550 const auto start_time = steady_clock::now();
2551 uint32_t bytes_read = 0;
2552 uint32_t packet_count = 0;
2553 while (bytes_read < recv_amount) {
2556 bytes_read += recv_size;
2559 const auto end_time = steady_clock::now();
2560 const auto total_time = end_time - start_time;
2561 float mb_second = ((float)recv_amount) /
2562 duration<float>(total_time).count() /
2564 float packets_per_second =
2565 ((float)packet_count) / duration<float>(total_time).count();
2566 const auto average_per_packet = packet_count > 0
2567 ? total_time / packet_count
2568 : duration<float>::zero();
2571 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2572 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2573 result_idx > 0 ?
"," :
"", send_size, recv_size,
2577 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2578 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2579 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2580 send_size, recv_size, packet_count, k_recv_amount_mb,
2581 duration<float>(total_time), mb_second,
2582 packets_per_second, duration<float>(average_per_packet));
2588 strm.
Printf(
"\n ]\n }\n}\n");
2595 uint32_t recv_size) {
2597 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2598 uint32_t bytes_left = send_size;
2599 while (bytes_left > 0) {
2600 if (bytes_left >= 26) {
2601 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2604 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2605 "abcdefghijklmnopqrstuvwxyz");
2616 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2617 std::string &socket_name) {
2620 socket_name.clear();
2625 std::string hostname;
2626 if (remote_accept_hostname && remote_accept_hostname[0])
2627 hostname = remote_accept_hostname;
2629 if (HostInfo::GetHostname(hostname)) {
2631 stream.
Printf(
"host:%s;", hostname.c_str());
2635 stream.
Printf(
"host:*;");
2646 llvm::StringRef name;
2647 llvm::StringRef value;
2650 value.getAsInteger(0, port);
2651 else if (name ==
"pid")
2652 value.getAsInteger(0, pid);
2653 else if (name.compare(
"socket_name") == 0) {
2664 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2665 connection_urls.clear();
2681 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2682 std::optional<StructuredData::Dictionary *> maybe_element =
2693 std::string socket_name;
2696 socket_name = std::string(socket_name_osp->GetStringValue());
2698 if (port != 0 || !socket_name.empty())
2699 connection_urls.emplace_back(port, socket_name);
2701 return connection_urls.size();
2706 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2718 uint64_t tid, uint64_t pid,
char op) {
2724 packet.
Printf(
"p%" PRIx64
".", pid);
2729 packet.
Printf(
"%" PRIx64, tid);
2735 return {{pid, tid}};
2747 return std::nullopt;
2762 return ret.has_value();
2777 return ret.has_value();
2792 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2793 assert(packet_len < (
int)
sizeof(packet));
2812 std::chrono::seconds timeout) {
2814 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2815 __FUNCTION__, insert ?
"add" :
"remove", addr);
2822 const int packet_len =
2823 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2824 insert ?
'Z' :
'z', type, addr, length);
2826 assert(packet_len + 1 < (
int)
sizeof(packet));
2871std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2873 bool &sequence_mutex_unavailable) {
2874 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2878 sequence_mutex_unavailable =
false;
2882 for (packet_result =
2900 ids.push_back(*pid_tid);
2902 }
while (ch ==
',');
2916 ids.emplace_back(1, 1);
2920 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
2921 "packet 'qfThreadInfo'");
2922 sequence_mutex_unavailable =
true;
2929 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
2934 if (ids.empty() || sequence_mutex_unavailable)
2937 for (
auto id : ids) {
2943 thread_ids.push_back(
id.second);
2946 return thread_ids.size();
2959 llvm::StringRef command,
2975 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
2979 std::string path{working_dir.
GetPath(
false)};
2986 if (response.
GetChar() !=
'F')
2987 return Status(
"malformed reply");
2988 if (response.
GetChar() !=
',')
2989 return Status(
"malformed reply");
2992 return Status(
"unable to run remote process");
2993 else if (status_ptr)
2994 *status_ptr = exitcode;
2995 if (response.
GetChar() !=
',')
2996 return Status(
"malformed reply");
3000 if (response.
GetChar() !=
',')
3001 return Status(
"malformed reply");
3005 command_output->assign(output);
3008 return Status(
"unable to send packet");
3012 uint32_t file_permissions) {
3013 std::string path{file_spec.
GetPath(
false)};
3019 llvm::StringRef packet = stream.
GetString();
3023 return Status(
"failed to send '%s' packet", packet.str().c_str());
3025 if (response.
GetChar() !=
'F')
3026 return Status(
"invalid response to '%s' packet", packet.str().c_str());
3033 uint32_t file_permissions) {
3034 std::string path{file_spec.
GetPath(
false)};
3040 llvm::StringRef packet = stream.
GetString();
3044 return Status(
"failed to send '%s' packet", stream.
GetData());
3046 if (response.
GetChar() !=
'F')
3047 return Status(
"invalid response to '%s' packet", stream.
GetData());
3054#define HANDLE_ERRNO(name, value) \
3057#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3066 if (response.
GetChar() !=
'F')
3068 int32_t result = response.
GetS32(-2, 16);
3071 if (response.
GetChar() ==
',') {
3073 if (result_errno != -1)
3085 std::string path(file_spec.
GetPath(
false));
3106 stream.
Printf(
"vFile:close:%x", (
int)fd);
3115std::optional<GDBRemoteFStatData>
3118 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3122 if (response.
GetChar() !=
'F')
3123 return std::nullopt;
3124 int64_t size = response.
GetS64(-1, 16);
3125 if (size > 0 && response.
GetChar() ==
';') {
3129 if (buffer.size() !=
sizeof(out))
3130 return std::nullopt;
3131 memcpy(&out, buffer.data(),
sizeof(out));
3136 return std::nullopt;
3139std::optional<GDBRemoteFStatData>
3144 return std::nullopt;
3145 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3154 std::string path(file_spec.
GetPath(
false));
3164 if (response.
GetChar() !=
'F')
3173 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3191 while (response.
Peek()) {
3193 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3196 if (response.
GetChar() !=
',')
3204 uint32_t &file_permissions) {
3206 std::string path{file_spec.
GetPath(
false)};
3214 error.SetErrorStringWithFormat(
"failed to send '%s' packet",
3219 if (response.
GetChar() !=
'F') {
3220 error.SetErrorStringWithFormat(
"invalid response to '%s' packet",
3223 const uint32_t mode = response.
GetS32(-1, 16);
3224 if (
static_cast<int32_t
>(mode) == -1) {
3225 if (response.
GetChar() ==
',') {
3227 if (response_errno > 0)
3230 error.SetErrorToGenericError();
3232 error.SetErrorToGenericError();
3244 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3248 return Status(
"fstat failed");
3252 uint64_t offset,
void *dst,
3256 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3261 if (response.
GetChar() !=
'F')
3263 int64_t retcode = response.
GetS64(-1, 16);
3264 if (retcode == -1) {
3265 error.SetErrorToGenericError();
3266 if (response.
GetChar() ==
',') {
3268 if (response_errno > 0)
3273 const char next = (response.
Peek() ? *response.
Peek() : 0);
3280 const uint64_t data_to_write =
3281 std::min<uint64_t>(dst_len, buffer.size());
3282 if (data_to_write > 0)
3283 memcpy(dst, &buffer[0], data_to_write);
3284 return data_to_write;
3297 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3302 if (response.
GetChar() !=
'F') {
3303 error.SetErrorStringWithFormat(
"write file failed");
3306 int64_t bytes_written = response.
GetS64(-1, 16);
3307 if (bytes_written == -1) {
3308 error.SetErrorToGenericError();
3309 if (response.
GetChar() ==
',') {
3311 if (response_errno > 0)
3316 return bytes_written;
3318 error.SetErrorString(
"failed to send vFile:pwrite packet");
3325 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3337 if (response.
GetChar() ==
'F') {
3340 error.SetErrorToGenericError();
3341 if (response.
GetChar() ==
',') {
3343 if (response_errno > 0)
3349 error.SetErrorStringWithFormat(
"symlink failed");
3352 error.SetErrorString(
"failed to send vFile:symlink packet");
3358 std::string path{file_spec.
GetPath(
false)};
3368 if (response.
GetChar() ==
'F') {
3371 error.SetErrorToGenericError();
3372 if (response.
GetChar() ==
',') {
3374 if (response_errno > 0)
3380 error.SetErrorStringWithFormat(
"unlink failed");
3383 error.SetErrorString(
"failed to send vFile:unlink packet");
3392 std::string path(file_spec.
GetPath(
false));
3401 if (response.
GetChar() !=
'F')
3403 if (response.
GetChar() !=
',')
3405 bool retcode = (response.
GetChar() !=
'0');
3422 std::string path(file_spec.
GetPath(
false));
3429 if (response.
GetChar() !=
'F')
3430 return std::make_error_code(std::errc::illegal_byte_sequence);
3431 if (response.
GetChar() !=
',')
3432 return std::make_error_code(std::errc::illegal_byte_sequence);
3433 if (response.
Peek() && *response.
Peek() ==
'x')
3434 return std::make_error_code(std::errc::no_such_file_or_directory);
3451 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3456 if (part.size() != MD5_HALF_LENGTH)
3457 return std::make_error_code(std::errc::illegal_byte_sequence);
3461 if (part.getAsInteger(16, low))
3462 return std::make_error_code(std::errc::illegal_byte_sequence);
3467 if (part.size() != MD5_HALF_LENGTH)
3468 return std::make_error_code(std::errc::illegal_byte_sequence);
3472 if (part.getAsInteger(16, high))
3473 return std::make_error_code(std::errc::illegal_byte_sequence);
3475 llvm::MD5::MD5Result result;
3476 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3477 result.data(), low);
3478 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3479 result.data() + 8, high);
3483 return std::make_error_code(std::errc::operation_canceled);
3493 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3494 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3495 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3496 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3499 if (gdb_server_version != 0) {
3501 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3502 if (gdb_server_version >= 310)
3515 payload.
Printf(
"p%x", reg);
3524 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3539 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3545 llvm::ArrayRef<uint8_t> data) {
3547 payload.
Printf(
"P%x=", reg_num);
3571 uint32_t &save_id) {
3587 const uint32_t response_save_id = response.
GetU32(0);
3588 if (response_save_id == 0)
3591 save_id = response_save_id;
3604 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3624 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3630llvm::Expected<TraceSupportedResponse>
3635 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3644 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3645 "jLLDBTraceSupported is unsupported");
3647 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3648 "TraceSupportedResponse");
3650 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3651 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3652 "failed to send packet: jLLDBTraceSupported");
3657 std::chrono::seconds timeout) {
3661 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3663 std::string json_string;
3664 llvm::raw_string_ostream os(json_string);
3668 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3677 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3678 "jLLDBTraceStop is unsupported");
3680 return llvm::Error::success();
3681 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3682 "Invalid jLLDBTraceStart response");
3684 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3685 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3686 "failed to send packet: jLLDBTraceStop '%s'",
3692 std::chrono::seconds timeout) {
3696 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3698 std::string json_string;
3699 llvm::raw_string_ostream os(json_string);
3703 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3712 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3713 "jLLDBTraceStart is unsupported");
3715 return llvm::Error::success();
3716 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3717 "Invalid jLLDBTraceStart response");
3719 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3720 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3721 "failed to send packet: jLLDBTraceStart '%s'",
3725llvm::Expected<std::string>
3727 std::chrono::seconds timeout) {
3731 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3733 std::string json_string;
3734 llvm::raw_string_ostream os(json_string);
3738 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3747 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3748 "jLLDBTraceGetState is unsupported");
3749 return std::string(response.
Peek());
3752 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3753 return llvm::createStringError(
3754 llvm::inconvertibleErrorCode(),
3755 "failed to send packet: jLLDBTraceGetState '%s'",
3759llvm::Expected<std::vector<uint8_t>>
3765 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3767 std::string json_string;
3768 llvm::raw_string_ostream os(json_string);
3772 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3782 return std::vector<uint8_t>(data.begin(), data.end());
3784 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3785 return llvm::createStringError(
3786 llvm::inconvertibleErrorCode(),
3787 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3795 return std::nullopt;
3797 return std::nullopt;
3801 const auto &GetOffset = [&] {
3803 if (ref.consumeInteger(16, offset))
3805 result.
offsets.push_back(offset);
3809 if (ref.consume_front(
"Text=")) {
3812 return std::nullopt;
3813 if (!ref.consume_front(
";Data=") || !GetOffset())
3814 return std::nullopt;
3817 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3819 }
else if (ref.consume_front(
"TextSeg=")) {
3822 return std::nullopt;
3825 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3828 return std::nullopt;
3837 std::string module_path = module_file_spec.
GetPath(
false);
3838 if (module_path.empty())
3845 const auto &triple = arch_spec.
GetTriple().getTriple();
3861 llvm::StringRef name;
3862 llvm::StringRef value;
3864 module_spec.
Clear();
3868 if (name ==
"uuid" || name ==
"md5") {
3873 }
else if (name ==
"triple") {
3878 }
else if (name ==
"file_offset") {
3880 if (!value.getAsInteger(16, ival))
3882 }
else if (name ==
"file_size") {
3884 if (!value.getAsInteger(16, ival))
3886 }
else if (name ==
"file_path") {
3897static std::optional<ModuleSpec>
3901 return std::nullopt;
3903 llvm::StringRef string;
3907 return std::nullopt;
3909 return std::nullopt;
3912 return std::nullopt;
3916 return std::nullopt;
3920 return std::nullopt;
3924 return std::nullopt;
3930std::optional<std::vector<ModuleSpec>>
3932 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
3936 return std::nullopt;
3938 json::Array module_array;
3939 for (
const FileSpec &module_file_spec : module_file_specs) {
3940 module_array.push_back(
3941 json::Object{{
"file", module_file_spec.GetPath(
false)},
3942 {
"triple", triple.getTriple()}});
3945 unescaped_payload.
PutCString(
"jModulesInfo:");
3946 unescaped_payload.
AsRawOstream() << std::move(module_array);
3959 return std::nullopt;
3963 return std::nullopt;
3968 if (!response_object_sp)
3969 return std::nullopt;
3972 if (!response_array)
3973 return std::nullopt;
3975 std::vector<ModuleSpec> result;
3976 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
3979 result.push_back(*module_spec);
3989llvm::Expected<std::string>
3991 llvm::StringRef annex) {
3994 llvm::raw_string_ostream output_stream(output);
4008 std::string packet =
4009 (
"qXfer:" +
object +
":read:" + annex +
":" +
4010 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4018 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4019 "Error sending $qXfer packet");
4037 return llvm::createStringError(
4038 llvm::inconvertibleErrorCode(),
4039 "Invalid continuation code from $qXfer packet");
4043 return output_stream.str();
4089 bool symbol_response_provided =
false;
4092 bool first_qsymbol_query =
true;
4103 if (symbol_response_provided || first_qsymbol_query) {
4110 first_qsymbol_query =
false;
4119 if (response_str.starts_with(
"qSymbol:")) {
4121 std::string symbol_name;
4123 if (symbol_name.empty())
4134 switch (sc.symbol->GetType()) {
4167 sc.symbol->GetLoadAddress(&process->
GetTarget());
4180 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4181 symbol_response_provided =
true;
4183 symbol_response_provided =
false;
4199 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4224 "GDBRemoteCommunicationClient::%s(): "
4225 "QSupportedAsyncJSONPackets returned invalid "
4232 "GDBRemoteCommunicationClient::%s(): "
4233 "QSupportedAsyncJSONPackets unsupported",
4241 "GDBRemoteCommunicationClient::%s(): supported async "
4243 __FUNCTION__, stream.
GetData());
4253 llvm::ArrayRef<int32_t> signals) {
4256 auto range = llvm::make_range(signals.begin(), signals.end());
4257 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4263 return Status(
"Sending QPassSignals packet failed");
4268 return Status(
"Unknown error happened during sending QPassSignals packet.");
4276 if (type_name.empty()) {
4277 error.SetErrorString(
"invalid type_name argument");
4289 config_sp->Dump(unescaped_stream);
4290 unescaped_stream.
Flush();
4307 error.SetErrorStringWithFormatv(
4308 "configuring StructuredData feature {0} failed with error {1}",
4313 error.SetErrorStringWithFormatv(
4314 "configuring StructuredData feature {0} failed when sending packet: "
4316 type_name, (
int)result);
4343 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4344 "failed to send k packet");
4346 char packet_cmd = response.
GetChar(0);
4347 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4350 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4351 "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
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
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.