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",
362 for (uint32_t i = 0; i < features.size(); ++i) {
374 for (llvm::StringRef x : llvm::split(response.
GetStringRef(),
';')) {
375 if (x ==
"qXfer:auxv:read+")
377 else if (x ==
"qXfer:libraries-svr4:read+")
379 else if (x ==
"augmented-libraries-svr4-read") {
382 }
else if (x ==
"qXfer:libraries:read+")
384 else if (x ==
"qXfer:features:read+")
386 else if (x ==
"qXfer:memory-map:read+")
388 else if (x ==
"qXfer:siginfo:read+")
390 else if (x ==
"qEcho")
392 else if (x ==
"QPassSignals+")
394 else if (x ==
"multiprocess+")
396 else if (x ==
"memory-tagging+")
398 else if (x ==
"qSaveCore+")
400 else if (x ==
"native-signals+")
405 else if (x.consume_front(
"SupportedCompressions=")) {
406 llvm::SmallVector<llvm::StringRef, 4> compressions;
407 x.split(compressions,
',');
408 if (!compressions.empty())
410 }
else if (x.consume_front(
"SupportedWatchpointTypes=")) {
411 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
412 x.split(watchpoint_types,
',');
414 for (
auto wp_type : watchpoint_types) {
415 if (wp_type ==
"x86_64")
417 if (wp_type ==
"aarch64-mask")
419 if (wp_type ==
"aarch64-bas")
422 }
else if (x.consume_front(
"PacketSize=")) {
429 LLDB_LOGF(log,
"Garbled PacketSize spec in qSupported response");
459 const char *response_cstr = response.
GetStringRef().data();
460 if (::strstr(response_cstr,
";c"))
463 if (::strstr(response_cstr,
";C"))
466 if (::strstr(response_cstr,
";s"))
469 if (::strstr(response_cstr,
";S"))
515 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
517 __FUNCTION__, payload.GetData());
522 payload.Printf(
";thread:%4.4" PRIx64
";", tid);
569 }
else if (!response.
Empty()) {
658 packet.
Printf(
"qMemTags:%" PRIx64
",%zx:%" PRIx32, addr, len, type);
666 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s: qMemTags packet failed",
674 if (response.
GetChar() !=
'm') {
676 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
687 if (response.
GetBytesLeft() || (expected_bytes != got_bytes)) {
690 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
700 const std::vector<uint8_t> &tags) {
703 packet.
Printf(
"QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr, len, type);
721 snprintf(packet,
sizeof(packet),
"x0,0");
748 if (response.
GetChar() ==
'Q') {
749 if (response.
GetChar() ==
'C') {
763 bool sequence_mutex_unavailable;
765 if (!ids.empty() && !sequence_mutex_unavailable) {
782 return llvm::createStringError(llvm::inconvertibleErrorCode(),
783 "Nothing to launch");
796 return llvm::createStringError(llvm::inconvertibleErrorCode(),
797 "Sending vRun packet failed");
806 return llvm::Error::success();
814 llvm::ListSeparator LS(
",");
815 for (
const auto &arg : llvm::enumerate(args)) {
817 packet.
Format(
"{0},{1},", arg.value().ref().size() * 2, arg.index());
824 return llvm::createStringError(llvm::inconvertibleErrorCode(),
825 "Sending A packet failed");
832 return llvm::createStringError(llvm::inconvertibleErrorCode(),
833 "Sending qLaunchSuccess packet failed");
836 return llvm::Error::success();
837 if (response.
GetChar() ==
'E') {
838 return llvm::createStringError(llvm::inconvertibleErrorCode(),
841 return llvm::createStringError(llvm::inconvertibleErrorCode(),
842 "unknown error occurred launching process");
846 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
847 for (
const auto &kv : env)
848 vec.emplace_back(kv.first(), kv.second);
849 llvm::sort(vec, llvm::less_first());
850 for (
const auto &[k, v] : vec) {
859 char const *name_equal_value) {
860 if (name_equal_value && name_equal_value[0]) {
861 bool send_hex_encoding =
false;
862 for (
const char *p = name_equal_value; *p !=
'\0' && !send_hex_encoding;
864 if (llvm::isPrint(*p)) {
870 send_hex_encoding =
true;
877 send_hex_encoding =
true;
885 packet.
Printf(
"QEnvironment:%s", name_equal_value);
926 if (arch && arch[0]) {
928 packet.
Printf(
"QLaunchArch:%s", arch);
943 char const *data,
bool *was_supported) {
944 if (data && *data !=
'\0') {
946 packet.
Printf(
"QSetProcessEvent:%s", data);
952 *was_supported =
true;
956 *was_supported =
false;
961 *was_supported =
true;
988std::optional<std::string>
1022 UUID &uuid,
addr_t &value,
bool &value_is_offset) {
1055 llvm::StringRef name, value;
1056 bool success =
false;
1058 if (name ==
"name") {
1061 }
else if (name ==
"version") {
1062 llvm::StringRef major, minor;
1063 std::tie(major, minor) = value.split(
'.');
1077 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1079 llvm::StringRef avail_name;
1081#if defined(HAVE_LIBCOMPRESSION)
1083 for (
auto compression : supported_compressions) {
1084 if (compression ==
"lzfse") {
1086 avail_name = compression;
1093#if defined(HAVE_LIBCOMPRESSION)
1095 for (
auto compression : supported_compressions) {
1096 if (compression ==
"zlib-deflate") {
1098 avail_name = compression;
1107 for (
auto compression : supported_compressions) {
1108 if (compression ==
"zlib-deflate") {
1110 avail_name = compression;
1117#if defined(HAVE_LIBCOMPRESSION)
1119 for (
auto compression : supported_compressions) {
1120 if (compression ==
"lz4") {
1122 avail_name = compression;
1129#if defined(HAVE_LIBCOMPRESSION)
1131 for (
auto compression : supported_compressions) {
1132 if (compression ==
"lzma") {
1134 avail_name = compression;
1143 std::string packet =
"QEnableCompression:type:" + avail_name.str() +
";";
1190 tid = pid_tid->second;
1197 std::string &environment) {
1198 if (value ==
"iossimulator" || value ==
"tvossimulator" ||
1199 value ==
"watchossimulator" || value ==
"xrossimulator" ||
1200 value ==
"visionossimulator") {
1201 environment =
"simulator";
1202 os_name = value.drop_back(environment.size()).str();
1203 }
else if (value ==
"maccatalyst") {
1205 environment =
"macabi";
1207 os_name = value.str();
1223 llvm::StringRef name;
1224 llvm::StringRef value;
1227 std::string arch_name;
1228 std::string os_name;
1229 std::string environment;
1230 std::string vendor_name;
1232 uint32_t pointer_byte_size = 0;
1234 uint32_t num_keys_decoded = 0;
1236 if (name ==
"cputype") {
1238 if (!value.getAsInteger(0, cpu))
1240 }
else if (name ==
"cpusubtype") {
1242 if (!value.getAsInteger(0, sub))
1244 }
else if (name ==
"arch") {
1245 arch_name = std::string(value);
1247 }
else if (name ==
"triple") {
1251 }
else if (name ==
"distribution_id") {
1255 }
else if (name ==
"os_build") {
1259 }
else if (name ==
"hostname") {
1263 }
else if (name ==
"os_kernel") {
1267 }
else if (name ==
"ostype") {
1270 }
else if (name ==
"vendor") {
1271 vendor_name = std::string(value);
1273 }
else if (name ==
"endian") {
1274 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1281 }
else if (name ==
"ptrsize") {
1282 if (!value.getAsInteger(0, pointer_byte_size))
1284 }
else if (name ==
"addressing_bits") {
1288 }
else if (name ==
"high_mem_addressing_bits") {
1291 }
else if (name ==
"low_mem_addressing_bits") {
1294 }
else if (name ==
"os_version" ||
1301 }
else if (name ==
"maccatalyst_version") {
1304 }
else if (name ==
"watchpoint_exceptions_received") {
1306 llvm::StringSwitch<LazyBool>(value)
1312 }
else if (name ==
"default_packet_timeout") {
1313 uint32_t timeout_seconds;
1314 if (!value.getAsInteger(0, timeout_seconds)) {
1319 }
else if (name ==
"vm-page-size") {
1321 if (!value.getAsInteger(0, page_size)) {
1328 if (num_keys_decoded > 0)
1331 if (triple.empty()) {
1332 if (arch_name.empty()) {
1335 if (pointer_byte_size) {
1342 if (!vendor_name.empty())
1344 llvm::StringRef(vendor_name));
1345 if (!os_name.empty())
1347 if (!environment.empty())
1352 triple += arch_name;
1353 if (!vendor_name.empty() || !os_name.empty()) {
1355 if (vendor_name.empty())
1356 triple +=
"unknown";
1358 triple += vendor_name;
1360 if (os_name.empty())
1361 triple +=
"unknown";
1368 if (host_triple.getVendor() == llvm::Triple::Apple &&
1369 host_triple.getOS() == llvm::Triple::Darwin) {
1371 case llvm::Triple::aarch64:
1372 case llvm::Triple::aarch64_32:
1373 case llvm::Triple::arm:
1374 case llvm::Triple::thumb:
1375 host_triple.setOS(llvm::Triple::IOS);
1378 host_triple.setOS(llvm::Triple::MacOSX);
1382 if (pointer_byte_size) {
1391 if (pointer_byte_size) {
1399 "GDBRemoteCommunicationClient::%s parsed host "
1400 "architecture as %s, triple as %s from triple text %s",
1404 :
"<null-arch-name>",
1444 return addressable_bits;
1454 uint32_t permissions) {
1458 const int packet_len = ::snprintf(
1459 packet,
sizeof(packet),
"_M%" PRIx64
",%s%s%s", (uint64_t)size,
1460 permissions & lldb::ePermissionsReadable ?
"r" :
"",
1461 permissions & lldb::ePermissionsWritable ?
"w" :
"",
1462 permissions & lldb::ePermissionsExecutable ?
"x" :
"");
1463 assert(packet_len < (
int)
sizeof(packet));
1483 const int packet_len =
1484 ::snprintf(packet,
sizeof(packet),
"_m%" PRIx64, (uint64_t)addr);
1485 assert(packet_len < (
int)
sizeof(packet));
1510 const int packet_len =
1511 ::snprintf(packet,
sizeof(packet),
"qSupportsDetachAndStayStopped:");
1512 assert(packet_len < (
int)
sizeof(packet));
1525 error.SetErrorString(
"Stays stopped not supported by this target.");
1540 error.SetErrorString(
"Multiprocess extension not supported by the server.");
1548 error.SetErrorString(
"Sending isconnect packet failed.");
1555 region_info.
Clear();
1560 const int packet_len = ::snprintf(
1561 packet,
sizeof(packet),
"qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1562 assert(packet_len < (
int)
sizeof(packet));
1568 llvm::StringRef name;
1569 llvm::StringRef value;
1571 bool success =
true;
1572 bool saw_permissions =
false;
1574 if (name ==
"start") {
1575 if (!value.getAsInteger(16, addr_value))
1577 }
else if (name ==
"size") {
1578 if (!value.getAsInteger(16, addr_value)) {
1586 }
else if (name ==
"permissions" && region_info.
GetRange().
IsValid()) {
1587 saw_permissions =
true;
1589 if (value.contains(
'r'))
1594 if (value.contains(
'w'))
1599 if (value.contains(
'x'))
1613 }
else if (name ==
"name") {
1617 region_info.
SetName(name.c_str());
1618 }
else if (name ==
"flags") {
1621 llvm::StringRef flags = value;
1622 llvm::StringRef flag;
1623 while (flags.size()) {
1624 flags = flags.ltrim();
1625 std::tie(flag, flags) = flags.split(
' ');
1634 }
else if (name ==
"type") {
1635 std::string comma_sep_str = value.str();
1637 while ((comma_pos = comma_sep_str.find(
',')) != std::string::npos) {
1638 comma_sep_str[comma_pos] =
'\0';
1639 if (comma_sep_str ==
"stack") {
1644 if (comma_sep_str ==
"stack") {
1647 }
else if (name ==
"error") {
1649 std::string error_string;
1652 error.SetErrorString(error_string.c_str());
1653 }
else if (name ==
"dirty-pages") {
1654 std::vector<addr_t> dirty_page_list;
1655 for (llvm::StringRef x : llvm::split(value,
',')) {
1657 x.consume_front(
"0x");
1658 if (llvm::to_integer(x, page, 16))
1659 dirty_page_list.push_back(page);
1671 if (!saw_permissions) {
1679 error.SetErrorString(
"Server returned invalid range");
1687 error.SetErrorString(
"qMemoryRegionInfo is not supported");
1699 region_info = qXfer_region_info;
1702 region_info.
Clear();
1704 }
else if (qXfer_error.
Success()) {
1719 if (!
error.Success())
1722 if (map_region.GetRange().Contains(addr)) {
1723 region = map_region;
1727 error.SetErrorString(
"Region not found");
1740 error.SetErrorString(
"XML is not supported");
1745 error.SetErrorString(
"Memory map is not supported");
1749 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1751 return Status(xml.takeError());
1755 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1756 error.SetErrorString(
"Failed to parse memory map xml");
1762 error.SetErrorString(
"Invalid root node in memory map xml");
1771 if (memory_node.
GetName() !=
"memory")
1782 region.GetRange().SetByteSize(length);
1783 if (type ==
"rom") {
1786 }
else if (type ==
"ram") {
1790 }
else if (type ==
"flash") {
1793 [®ion](
const XMLNode &prop_node) ->
bool {
1796 if (prop_node.
GetName() !=
"property")
1799 if (propname ==
"blocksize") {
1802 region.SetBlocksize(blocksize);
1821 std::optional<uint32_t> num;
1827 llvm::StringRef name;
1828 llvm::StringRef value;
1830 if (name ==
"num") {
1846WatchpointHardwareFeature
1865 return std::nullopt;
1870 std::string path{file_spec.
GetPath(
false)};
1890 std::string path{file_spec.
GetPath(
false)};
1910 std::string path{file_spec.
GetPath(
false)};
1939 return !cwd.empty();
1946 std::string path{working_dir.
GetPath(
false)};
1966 const int packet_len =
1967 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
1968 assert(packet_len < (
int)
sizeof(packet));
1983 const int packet_len = ::snprintf(packet,
sizeof(packet),
1984 "QSetDetachOnError:%i", enable ? 1 : 0);
1985 assert(packet_len < (
int)
sizeof(packet));
2001 llvm::StringRef name;
2002 llvm::StringRef value;
2008 std::string os_type;
2011 if (name ==
"pid") {
2013 value.getAsInteger(0, pid);
2015 }
else if (name ==
"ppid") {
2017 value.getAsInteger(0, pid);
2019 }
else if (name ==
"uid") {
2021 value.getAsInteger(0, uid);
2023 }
else if (name ==
"euid") {
2025 value.getAsInteger(0, uid);
2027 }
else if (name ==
"gid") {
2029 value.getAsInteger(0, gid);
2031 }
else if (name ==
"egid") {
2033 value.getAsInteger(0, gid);
2035 }
else if (name ==
"triple") {
2040 }
else if (name ==
"name") {
2047 }
else if (name ==
"args") {
2048 llvm::StringRef encoded_args(value), hex_arg;
2050 bool is_arg0 =
true;
2051 while (!encoded_args.empty()) {
2052 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2067 }
else if (name ==
"cputype") {
2068 value.getAsInteger(0, cpu);
2069 }
else if (name ==
"cpusubtype") {
2070 value.getAsInteger(0, sub);
2071 }
else if (name ==
"vendor") {
2072 vendor = std::string(value);
2073 }
else if (name ==
"ostype") {
2074 os_type = std::string(value);
2079 if (vendor ==
"apple") {
2083 llvm::StringRef(vendor));
2085 llvm::StringRef(os_type));
2097 process_info.
Clear();
2101 const int packet_len =
2102 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2103 assert(packet_len < (
int)
sizeof(packet));
2133 llvm::StringRef name;
2134 llvm::StringRef value;
2137 std::string arch_name;
2138 std::string os_name;
2139 std::string environment;
2140 std::string vendor_name;
2142 std::string elf_abi;
2143 uint32_t pointer_byte_size = 0;
2146 uint32_t num_keys_decoded = 0;
2149 if (name ==
"cputype") {
2150 if (!value.getAsInteger(16, cpu))
2152 }
else if (name ==
"cpusubtype") {
2153 if (!value.getAsInteger(16, sub)) {
2159 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2160 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2167 }
else if (name ==
"triple") {
2171 }
else if (name ==
"ostype") {
2174 }
else if (name ==
"vendor") {
2175 vendor_name = std::string(value);
2177 }
else if (name ==
"endian") {
2178 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2185 }
else if (name ==
"ptrsize") {
2186 if (!value.getAsInteger(16, pointer_byte_size))
2188 }
else if (name ==
"pid") {
2189 if (!value.getAsInteger(16, pid))
2191 }
else if (name ==
"elf_abi") {
2192 elf_abi = std::string(value);
2194 }
else if (name ==
"main-binary-uuid") {
2197 }
else if (name ==
"main-binary-slide") {
2205 }
else if (name ==
"main-binary-address") {
2213 }
else if (name ==
"binary-addresses") {
2216 for (llvm::StringRef x : llvm::split(value,
',')) {
2218 x.consume_front(
"0x");
2219 if (llvm::to_integer(x, vmaddr, 16))
2224 if (num_keys_decoded > 0)
2232 if (!triple.empty()) {
2235 if (pointer_byte_size) {
2239 !vendor_name.empty()) {
2240 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2241 if (!environment.empty())
2242 triple.setEnvironmentName(environment);
2244 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2245 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2246 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2247 switch (triple.getObjectFormat()) {
2248 case llvm::Triple::MachO:
2251 case llvm::Triple::ELF:
2254 case llvm::Triple::COFF:
2257 case llvm::Triple::GOFF:
2258 case llvm::Triple::SPIRV:
2259 case llvm::Triple::Wasm:
2260 case llvm::Triple::XCOFF:
2261 case llvm::Triple::DXContainer:
2262 LLDB_LOGF(log,
"error: not supported target architecture");
2264 case llvm::Triple::UnknownObjectFormat:
2265 LLDB_LOGF(log,
"error: failed to determine target architecture");
2269 if (pointer_byte_size) {
2291 process_infos.clear();
2299 bool has_name_match =
false;
2300 if (name && name[0]) {
2301 has_name_match =
true;
2303 switch (name_match_type) {
2305 has_name_match =
false;
2317 packet.
PutCString(
"name_match:starts_with;");
2328 if (has_name_match) {
2336 packet.
Printf(
"pid:%" PRIu64
";",
2339 packet.
Printf(
"parent_pid:%" PRIu64
";",
2346 packet.
Printf(
"euid:%u;",
2349 packet.
Printf(
"egid:%u;",
2355 const llvm::Triple &triple = match_arch.
GetTriple();
2371 process_infos.push_back(process_info);
2380 return process_infos.size();
2384 std::string &name) {
2387 const int packet_len =
2388 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2389 assert(packet_len < (
int)
sizeof(packet));
2411 std::string &name) {
2414 const int packet_len =
2415 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2416 assert(packet_len < (
int)
sizeof(packet));
2438 uint32_t recv_size) {
2440 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2441 uint32_t bytes_left = send_size;
2442 while (bytes_left > 0) {
2443 if (bytes_left >= 26) {
2444 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2447 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2448 "abcdefghijklmnopqrstuvwxyz");
2457 return duration<float>::zero();
2458 using Dur = duration<float>;
2459 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2460 Dur mean = sum / v.size();
2463 float delta = (d - mean).count();
2464 accum += delta * delta;
2467 return Dur(sqrtf(accum / (v.size() - 1)));
2473 uint64_t recv_amount,
2474 bool json,
Stream &strm) {
2479 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2483 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2487 uint32_t result_idx = 0;
2489 std::vector<duration<float>> packet_times;
2491 for (send_size = 0; send_size <= max_send;
2492 send_size ? send_size *= 2 : send_size = 4) {
2493 for (uint32_t recv_size = 0; recv_size <= max_recv;
2494 recv_size ? recv_size *= 2 : recv_size = 4) {
2497 packet_times.clear();
2499 const auto start_time = steady_clock::now();
2500 for (uint32_t i = 0; i < num_packets; ++i) {
2501 const auto packet_start_time = steady_clock::now();
2504 const auto packet_end_time = steady_clock::now();
2505 packet_times.push_back(packet_end_time - packet_start_time);
2507 const auto end_time = steady_clock::now();
2508 const auto total_time = end_time - start_time;
2510 float packets_per_second =
2511 ((float)num_packets) / duration<float>(total_time).count();
2512 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2513 : duration<float>::zero();
2514 const duration<float> standard_deviation =
2517 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2518 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2519 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2520 result_idx > 0 ?
"," :
"", send_size, recv_size,
2521 total_time, standard_deviation);
2524 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2525 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2526 "standard deviation of {5,10:ms+f6}\n",
2527 send_size, recv_size, duration<float>(total_time),
2528 packets_per_second, duration<float>(average_per_packet),
2529 standard_deviation);
2535 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2537 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2538 ": %" PRIu64
",\n \"results\" : [",
2541 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2547 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2552 if (recv_size > 0) {
2553 const auto start_time = steady_clock::now();
2554 uint32_t bytes_read = 0;
2555 uint32_t packet_count = 0;
2556 while (bytes_read < recv_amount) {
2559 bytes_read += recv_size;
2562 const auto end_time = steady_clock::now();
2563 const auto total_time = end_time - start_time;
2564 float mb_second = ((float)recv_amount) /
2565 duration<float>(total_time).count() /
2567 float packets_per_second =
2568 ((float)packet_count) / duration<float>(total_time).count();
2569 const auto average_per_packet = packet_count > 0
2570 ? total_time / packet_count
2571 : duration<float>::zero();
2574 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2575 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2576 result_idx > 0 ?
"," :
"", send_size, recv_size,
2580 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2581 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2582 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2583 send_size, recv_size, packet_count, k_recv_amount_mb,
2584 duration<float>(total_time), mb_second,
2585 packets_per_second, duration<float>(average_per_packet));
2591 strm.
Printf(
"\n ]\n }\n}\n");
2598 uint32_t recv_size) {
2600 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2601 uint32_t bytes_left = send_size;
2602 while (bytes_left > 0) {
2603 if (bytes_left >= 26) {
2604 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2607 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2608 "abcdefghijklmnopqrstuvwxyz");
2619 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2620 std::string &socket_name) {
2623 socket_name.clear();
2628 std::string hostname;
2629 if (remote_accept_hostname && remote_accept_hostname[0])
2630 hostname = remote_accept_hostname;
2632 if (HostInfo::GetHostname(hostname)) {
2634 stream.
Printf(
"host:%s;", hostname.c_str());
2638 stream.
Printf(
"host:*;");
2649 llvm::StringRef name;
2650 llvm::StringRef value;
2653 value.getAsInteger(0, port);
2654 else if (name ==
"pid")
2655 value.getAsInteger(0, pid);
2656 else if (name.compare(
"socket_name") == 0) {
2667 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2668 connection_urls.clear();
2684 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2685 std::optional<StructuredData::Dictionary *> maybe_element =
2696 std::string socket_name;
2699 socket_name = std::string(socket_name_osp->GetStringValue());
2701 if (port != 0 || !socket_name.empty())
2702 connection_urls.emplace_back(port, socket_name);
2704 return connection_urls.size();
2709 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2721 uint64_t tid, uint64_t pid,
char op) {
2727 packet.
Printf(
"p%" PRIx64
".", pid);
2732 packet.
Printf(
"%" PRIx64, tid);
2738 return {{pid, tid}};
2750 return std::nullopt;
2765 return ret.has_value();
2780 return ret.has_value();
2795 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2796 assert(packet_len < (
int)
sizeof(packet));
2815 std::chrono::seconds timeout) {
2817 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2818 __FUNCTION__, insert ?
"add" :
"remove", addr);
2825 const int packet_len =
2826 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2827 insert ?
'Z' :
'z', type, addr, length);
2829 assert(packet_len + 1 < (
int)
sizeof(packet));
2874std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2876 bool &sequence_mutex_unavailable) {
2877 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2881 sequence_mutex_unavailable =
false;
2885 for (packet_result =
2903 ids.push_back(*pid_tid);
2905 }
while (ch ==
',');
2919 ids.emplace_back(1, 1);
2923 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
2924 "packet 'qfThreadInfo'");
2925 sequence_mutex_unavailable =
true;
2932 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
2937 if (ids.empty() || sequence_mutex_unavailable)
2940 for (
auto id : ids) {
2946 thread_ids.push_back(
id.second);
2949 return thread_ids.size();
2962 llvm::StringRef command,
2978 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
2982 std::string path{working_dir.
GetPath(
false)};
2989 if (response.
GetChar() !=
'F')
2990 return Status(
"malformed reply");
2991 if (response.
GetChar() !=
',')
2992 return Status(
"malformed reply");
2995 return Status(
"unable to run remote process");
2996 else if (status_ptr)
2997 *status_ptr = exitcode;
2998 if (response.
GetChar() !=
',')
2999 return Status(
"malformed reply");
3003 if (response.
GetChar() !=
',')
3004 return Status(
"malformed reply");
3008 command_output->assign(output);
3011 return Status(
"unable to send packet");
3015 uint32_t file_permissions) {
3016 std::string path{file_spec.
GetPath(
false)};
3022 llvm::StringRef packet = stream.
GetString();
3026 return Status(
"failed to send '%s' packet", packet.str().c_str());
3028 if (response.
GetChar() !=
'F')
3029 return Status(
"invalid response to '%s' packet", packet.str().c_str());
3036 uint32_t file_permissions) {
3037 std::string path{file_spec.
GetPath(
false)};
3043 llvm::StringRef packet = stream.
GetString();
3047 return Status(
"failed to send '%s' packet", stream.
GetData());
3049 if (response.
GetChar() !=
'F')
3050 return Status(
"invalid response to '%s' packet", stream.
GetData());
3057#define HANDLE_ERRNO(name, value) \
3060#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3069 if (response.
GetChar() !=
'F')
3071 int32_t result = response.
GetS32(-2, 16);
3074 if (response.
GetChar() ==
',') {
3076 if (result_errno != -1)
3088 std::string path(file_spec.
GetPath(
false));
3109 stream.
Printf(
"vFile:close:%x", (
int)fd);
3118std::optional<GDBRemoteFStatData>
3121 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3125 if (response.
GetChar() !=
'F')
3126 return std::nullopt;
3127 int64_t size = response.
GetS64(-1, 16);
3128 if (size > 0 && response.
GetChar() ==
';') {
3132 if (buffer.size() !=
sizeof(out))
3133 return std::nullopt;
3134 memcpy(&out, buffer.data(),
sizeof(out));
3139 return std::nullopt;
3142std::optional<GDBRemoteFStatData>
3147 return std::nullopt;
3148 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3157 std::string path(file_spec.
GetPath(
false));
3167 if (response.
GetChar() !=
'F')
3176 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3194 while (response.
Peek()) {
3196 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3199 if (response.
GetChar() !=
',')
3207 uint32_t &file_permissions) {
3209 std::string path{file_spec.
GetPath(
false)};
3217 error.SetErrorStringWithFormat(
"failed to send '%s' packet",
3222 if (response.
GetChar() !=
'F') {
3223 error.SetErrorStringWithFormat(
"invalid response to '%s' packet",
3226 const uint32_t mode = response.
GetS32(-1, 16);
3227 if (
static_cast<int32_t
>(mode) == -1) {
3228 if (response.
GetChar() ==
',') {
3230 if (response_errno > 0)
3233 error.SetErrorToGenericError();
3235 error.SetErrorToGenericError();
3247 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3251 return Status(
"fstat failed");
3255 uint64_t offset,
void *dst,
3259 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3264 if (response.
GetChar() !=
'F')
3266 int64_t retcode = response.
GetS64(-1, 16);
3267 if (retcode == -1) {
3268 error.SetErrorToGenericError();
3269 if (response.
GetChar() ==
',') {
3271 if (response_errno > 0)
3276 const char next = (response.
Peek() ? *response.
Peek() : 0);
3283 const uint64_t data_to_write =
3284 std::min<uint64_t>(dst_len, buffer.size());
3285 if (data_to_write > 0)
3286 memcpy(dst, &buffer[0], data_to_write);
3287 return data_to_write;
3300 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3305 if (response.
GetChar() !=
'F') {
3306 error.SetErrorStringWithFormat(
"write file failed");
3309 int64_t bytes_written = response.
GetS64(-1, 16);
3310 if (bytes_written == -1) {
3311 error.SetErrorToGenericError();
3312 if (response.
GetChar() ==
',') {
3314 if (response_errno > 0)
3319 return bytes_written;
3321 error.SetErrorString(
"failed to send vFile:pwrite packet");
3328 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3340 if (response.
GetChar() ==
'F') {
3343 error.SetErrorToGenericError();
3344 if (response.
GetChar() ==
',') {
3346 if (response_errno > 0)
3352 error.SetErrorStringWithFormat(
"symlink failed");
3355 error.SetErrorString(
"failed to send vFile:symlink packet");
3361 std::string path{file_spec.
GetPath(
false)};
3371 if (response.
GetChar() ==
'F') {
3374 error.SetErrorToGenericError();
3375 if (response.
GetChar() ==
',') {
3377 if (response_errno > 0)
3383 error.SetErrorStringWithFormat(
"unlink failed");
3386 error.SetErrorString(
"failed to send vFile:unlink packet");
3395 std::string path(file_spec.
GetPath(
false));
3404 if (response.
GetChar() !=
'F')
3406 if (response.
GetChar() !=
',')
3408 bool retcode = (response.
GetChar() !=
'0');
3425 std::string path(file_spec.
GetPath(
false));
3432 if (response.
GetChar() !=
'F')
3433 return std::make_error_code(std::errc::illegal_byte_sequence);
3434 if (response.
GetChar() !=
',')
3435 return std::make_error_code(std::errc::illegal_byte_sequence);
3436 if (response.
Peek() && *response.
Peek() ==
'x')
3437 return std::make_error_code(std::errc::no_such_file_or_directory);
3454 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3459 if (part.size() != MD5_HALF_LENGTH)
3460 return std::make_error_code(std::errc::illegal_byte_sequence);
3464 if (part.getAsInteger(16, low))
3465 return std::make_error_code(std::errc::illegal_byte_sequence);
3470 if (part.size() != MD5_HALF_LENGTH)
3471 return std::make_error_code(std::errc::illegal_byte_sequence);
3475 if (part.getAsInteger(16, high))
3476 return std::make_error_code(std::errc::illegal_byte_sequence);
3478 llvm::MD5::MD5Result result;
3479 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3480 result.data(), low);
3481 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3482 result.data() + 8, high);
3486 return std::make_error_code(std::errc::operation_canceled);
3496 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3497 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3498 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3499 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3502 if (gdb_server_version != 0) {
3504 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3505 if (gdb_server_version >= 310)
3518 payload.
Printf(
"p%x", reg);
3527 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3542 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3548 llvm::ArrayRef<uint8_t> data) {
3550 payload.
Printf(
"P%x=", reg_num);
3574 uint32_t &save_id) {
3590 const uint32_t response_save_id = response.
GetU32(0);
3591 if (response_save_id == 0)
3594 save_id = response_save_id;
3607 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3627 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3633llvm::Expected<TraceSupportedResponse>
3638 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3647 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3648 "jLLDBTraceSupported is unsupported");
3650 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3651 "TraceSupportedResponse");
3653 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3654 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3655 "failed to send packet: jLLDBTraceSupported");
3660 std::chrono::seconds timeout) {
3664 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3666 std::string json_string;
3667 llvm::raw_string_ostream os(json_string);
3671 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3680 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3681 "jLLDBTraceStop is unsupported");
3683 return llvm::Error::success();
3684 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3685 "Invalid jLLDBTraceStart response");
3687 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3688 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3689 "failed to send packet: jLLDBTraceStop '%s'",
3695 std::chrono::seconds timeout) {
3699 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3701 std::string json_string;
3702 llvm::raw_string_ostream os(json_string);
3706 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3715 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3716 "jLLDBTraceStart is unsupported");
3718 return llvm::Error::success();
3719 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3720 "Invalid jLLDBTraceStart response");
3722 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3723 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3724 "failed to send packet: jLLDBTraceStart '%s'",
3728llvm::Expected<std::string>
3730 std::chrono::seconds timeout) {
3734 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3736 std::string json_string;
3737 llvm::raw_string_ostream os(json_string);
3741 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3750 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3751 "jLLDBTraceGetState is unsupported");
3752 return std::string(response.
Peek());
3755 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3756 return llvm::createStringError(
3757 llvm::inconvertibleErrorCode(),
3758 "failed to send packet: jLLDBTraceGetState '%s'",
3762llvm::Expected<std::vector<uint8_t>>
3768 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3770 std::string json_string;
3771 llvm::raw_string_ostream os(json_string);
3775 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3785 return std::vector<uint8_t>(data.begin(), data.end());
3787 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3788 return llvm::createStringError(
3789 llvm::inconvertibleErrorCode(),
3790 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3798 return std::nullopt;
3800 return std::nullopt;
3804 const auto &GetOffset = [&] {
3806 if (ref.consumeInteger(16, offset))
3808 result.
offsets.push_back(offset);
3812 if (ref.consume_front(
"Text=")) {
3815 return std::nullopt;
3816 if (!ref.consume_front(
";Data=") || !GetOffset())
3817 return std::nullopt;
3820 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3822 }
else if (ref.consume_front(
"TextSeg=")) {
3825 return std::nullopt;
3828 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3831 return std::nullopt;
3840 std::string module_path = module_file_spec.
GetPath(
false);
3841 if (module_path.empty())
3848 const auto &triple = arch_spec.
GetTriple().getTriple();
3864 llvm::StringRef name;
3865 llvm::StringRef value;
3867 module_spec.
Clear();
3871 if (name ==
"uuid" || name ==
"md5") {
3876 }
else if (name ==
"triple") {
3881 }
else if (name ==
"file_offset") {
3883 if (!value.getAsInteger(16, ival))
3885 }
else if (name ==
"file_size") {
3887 if (!value.getAsInteger(16, ival))
3889 }
else if (name ==
"file_path") {
3900static std::optional<ModuleSpec>
3904 return std::nullopt;
3906 llvm::StringRef string;
3910 return std::nullopt;
3912 return std::nullopt;
3915 return std::nullopt;
3919 return std::nullopt;
3923 return std::nullopt;
3927 return std::nullopt;
3933std::optional<std::vector<ModuleSpec>>
3935 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
3939 return std::nullopt;
3941 json::Array module_array;
3942 for (
const FileSpec &module_file_spec : module_file_specs) {
3943 module_array.push_back(
3944 json::Object{{
"file", module_file_spec.GetPath(
false)},
3945 {
"triple", triple.getTriple()}});
3948 unescaped_payload.
PutCString(
"jModulesInfo:");
3949 unescaped_payload.
AsRawOstream() << std::move(module_array);
3962 return std::nullopt;
3966 return std::nullopt;
3971 if (!response_object_sp)
3972 return std::nullopt;
3975 if (!response_array)
3976 return std::nullopt;
3978 std::vector<ModuleSpec> result;
3979 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
3982 result.push_back(*module_spec);
3992llvm::Expected<std::string>
3994 llvm::StringRef annex) {
3997 llvm::raw_string_ostream output_stream(output);
4011 std::string packet =
4012 (
"qXfer:" +
object +
":read:" + annex +
":" +
4013 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4021 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4022 "Error sending $qXfer packet");
4040 return llvm::createStringError(
4041 llvm::inconvertibleErrorCode(),
4042 "Invalid continuation code from $qXfer packet");
4046 return output_stream.str();
4092 bool symbol_response_provided =
false;
4095 bool first_qsymbol_query =
true;
4106 if (symbol_response_provided || first_qsymbol_query) {
4113 first_qsymbol_query =
false;
4122 if (response_str.starts_with(
"qSymbol:")) {
4124 std::string symbol_name;
4126 if (symbol_name.empty())
4137 switch (sc.symbol->GetType()) {
4170 sc.symbol->GetLoadAddress(&process->
GetTarget());
4183 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4184 symbol_response_provided =
true;
4186 symbol_response_provided =
false;
4202 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4227 "GDBRemoteCommunicationClient::%s(): "
4228 "QSupportedAsyncJSONPackets returned invalid "
4235 "GDBRemoteCommunicationClient::%s(): "
4236 "QSupportedAsyncJSONPackets unsupported",
4244 "GDBRemoteCommunicationClient::%s(): supported async "
4246 __FUNCTION__, stream.
GetData());
4256 llvm::ArrayRef<int32_t> signals) {
4259 auto range = llvm::make_range(signals.begin(), signals.end());
4260 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4266 return Status(
"Sending QPassSignals packet failed");
4271 return Status(
"Unknown error happened during sending QPassSignals packet.");
4279 if (type_name.empty()) {
4280 error.SetErrorString(
"invalid type_name argument");
4292 config_sp->Dump(unescaped_stream);
4293 unescaped_stream.
Flush();
4310 error.SetErrorStringWithFormatv(
4311 "configuring StructuredData feature {0} failed with error {1}",
4316 error.SetErrorStringWithFormatv(
4317 "configuring StructuredData feature {0} failed when sending packet: "
4319 type_name, (
int)result);
4346 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4347 "failed to send k packet");
4349 char packet_cmd = response.
GetChar(0);
4350 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4353 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4354 "unexpected response to k packet: %s",
static llvm::raw_ostream & error(Stream &strm)
duration< float > calculate_standard_deviation(const std::vector< duration< float > > &v)
static std::optional< ModuleSpec > ParseModuleSpec(StructuredData::Dictionary *dict)
static int gdb_errno_to_system(int err)
static void ParseOSType(llvm::StringRef value, std::string &os_name, std::string &environment)
static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response, uint64_t fail_result, Status &error)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
bool IsValid() const
Tests if this ArchSpec is valid.
void Clear()
Clears the object state.
llvm::Triple & GetTriple()
Architecture triple accessor.
void SetFlags(uint32_t flags)
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
A command line argument class.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
void Clear()
Clear the arguments.
bool IsConnected() const
Check if the connection is valid.
virtual lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr)
Disconnect the communications connection if one is currently connected.
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
llvm::StringRef GetCursorArgumentPrefix() const
A uniqued constant string class.
A subclass of DataBuffer that stores a data buffer on the heap.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void SetFlash(OptionalBool val)
void SetMapped(OptionalBool val)
void SetBlocksize(lldb::offset_t blocksize)
void SetMemoryTagged(OptionalBool val)
void SetReadable(OptionalBool val)
void SetExecutable(OptionalBool val)
void SetIsStackMemory(OptionalBool val)
void SetPageSize(int pagesize)
void SetName(const char *name)
void SetWritable(OptionalBool val)
lldb::offset_t GetBlocksize() const
void SetDirtyPageList(std::vector< lldb::addr_t > pagelist)
OptionalBool GetFlash() const
void 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.