37#include "lldb/Host/Config.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
42#include "llvm/Config/llvm-config.h"
43#include "llvm/Support/ErrorExtras.h"
44#include "llvm/Support/JSON.h"
46#if HAVE_LIBCOMPRESSION
47#include <compression.h>
53using namespace std::chrono;
57 return os << llvm::formatv(
58 "QOffsets({0}, [{1:@[x]}])", offsets.
segments,
93 std::chrono::steady_clock::time_point start_of_handshake =
94 std::chrono::steady_clock::now();
103 std::chrono::steady_clock::time_point end_of_handshake =
104 std::chrono::steady_clock::now();
105 auto handshake_timeout =
106 std::chrono::duration<double>(end_of_handshake - start_of_handshake)
112 "while waiting for reply to initial "
116 "failed to get reply to handshake packet within timeout of "
234llvm::Expected<std::vector<AcceleratorActions>>
242 return std::vector<AcceleratorActions>();
248 return llvm::createStringError(
249 "failed to send jAcceleratorPluginInitialize packet");
252 return std::vector<AcceleratorActions>();
257 llvm::Expected<std::vector<AcceleratorActions>> actions =
258 llvm::json::parse<std::vector<AcceleratorActions>>(response.
Peek(),
259 "AcceleratorActions");
266 return llvm::createStringErrorV(
267 "malformed jAcceleratorPluginInitialize response '{0}': {1}",
268 response.
GetStringRef(), llvm::toString(actions.takeError()));
271llvm::Expected<AcceleratorBreakpointHitResponse>
275 packet.
PutCString(
"jAcceleratorPluginBreakpointHit:");
281 return llvm::createStringError(
282 "failed to send jAcceleratorPluginBreakpointHit packet");
287 llvm::Expected<AcceleratorBreakpointHitResponse> hit_response =
288 llvm::json::parse<AcceleratorBreakpointHitResponse>(
289 response.
Peek(),
"AcceleratorBreakpointHitResponse");
296 return llvm::createStringErrorV(
297 "malformed jAcceleratorPluginBreakpointHit response '{0}': {1}",
298 response.
GetStringRef(), llvm::toString(hit_response.takeError()));
466 std::vector<std::string> features = {
"xmlRegisters=i386,arm,mips,arc",
472 "qXfer:libraries:read+",
473 "qXfer:libraries-svr4:read+"};
476 for (uint32_t i = 0; i < features.size(); ++i) {
488 for (llvm::StringRef x : llvm::split(response.
GetStringRef(),
';')) {
489 if (x ==
"qXfer:auxv:read+")
491 else if (x ==
"qXfer:libraries-svr4:read+")
493 else if (x ==
"augmented-libraries-svr4-read") {
496 }
else if (x ==
"qXfer:libraries:read+")
498 else if (x ==
"qXfer:features:read+")
500 else if (x ==
"qXfer:memory-map:read+")
502 else if (x ==
"qXfer:siginfo:read+")
504 else if (x ==
"qEcho+")
506 else if (x ==
"QPassSignals+")
508 else if (x ==
"multiprocess+")
510 else if (x ==
"memory-tagging+")
512 else if (x ==
"qSaveCore+")
514 else if (x ==
"native-signals+")
516 else if (x ==
"binary-upload+")
518 else if (x ==
"ReverseContinue+")
520 else if (x ==
"ReverseStep+")
522 else if (x ==
"MultiMemRead+")
524 else if (x ==
"jMultiBreakpoint+")
526 else if (x ==
"accelerator-plugins+")
531 else if (x.consume_front(
"SupportedCompressions=")) {
532 llvm::SmallVector<llvm::StringRef, 4> compressions;
533 x.split(compressions,
',');
534 if (!compressions.empty())
536 }
else if (x.consume_front(
"SupportedWatchpointTypes=")) {
537 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
538 x.split(watchpoint_types,
',');
540 for (
auto wp_type : watchpoint_types) {
541 if (wp_type ==
"x86_64")
543 if (wp_type ==
"aarch64-mask")
545 if (wp_type ==
"aarch64-bas")
548 }
else if (x.consume_front(
"PacketSize=")) {
555 LLDB_LOGF(log,
"Garbled PacketSize spec in qSupported response");
576 assert(!flavor.empty());
587 for (llvm::StringRef token : llvm::split(response.
GetStringRef(),
';')) {
614 return llvm::StringSwitch<bool>(flavor)
632 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
634 __FUNCTION__, payload.GetData());
639 payload.Printf(
";thread:%4.4" PRIx64
";", tid);
686 }
else if (!response.
Empty()) {
775 packet.
Printf(
"qMemTags:%" PRIx64
",%zx:%" PRIx32, addr, len, type);
783 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s: qMemTags packet failed",
791 if (response.
GetChar() !=
'm') {
793 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
804 if (response.
GetBytesLeft() || (expected_bytes != got_bytes)) {
807 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
817 const std::vector<uint8_t> &tags) {
820 packet.
Printf(
"QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr, len, type);
866 if (response.
GetChar() ==
'Q') {
867 if (response.
GetChar() ==
'C') {
881 bool sequence_mutex_unavailable;
883 if (!ids.empty() && !sequence_mutex_unavailable) {
900 return llvm::createStringError(llvm::inconvertibleErrorCode(),
901 "Nothing to launch");
914 return llvm::createStringError(llvm::inconvertibleErrorCode(),
915 "Sending vRun packet failed");
924 return llvm::Error::success();
932 llvm::ListSeparator LS(
",");
933 for (
const auto &arg : llvm::enumerate(args)) {
935 packet.
Format(
"{0},{1},", arg.value().ref().size() * 2, arg.index());
942 return llvm::createStringError(llvm::inconvertibleErrorCode(),
943 "Sending A packet failed");
950 return llvm::createStringError(llvm::inconvertibleErrorCode(),
951 "Sending qLaunchSuccess packet failed");
954 return llvm::Error::success();
955 if (response.
GetChar() ==
'E') {
956 return llvm::createStringError(llvm::inconvertibleErrorCode(),
959 return llvm::createStringError(llvm::inconvertibleErrorCode(),
960 "unknown error occurred launching process");
964 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
965 for (
const auto &kv : env)
966 vec.emplace_back(kv.first(), kv.second);
967 llvm::sort(vec, llvm::less_first());
968 for (
const auto &[k, v] : vec) {
977 char const *name_equal_value) {
978 if (name_equal_value && name_equal_value[0]) {
979 bool send_hex_encoding =
false;
980 for (
const char *p = name_equal_value; *p !=
'\0' && !send_hex_encoding;
982 if (llvm::isPrint(*p)) {
988 send_hex_encoding =
true;
995 send_hex_encoding =
true;
1003 packet.
Printf(
"QEnvironment:%s", name_equal_value);
1022 packet.
PutCString(
"QEnvironmentHexEncoded:");
1044 if (arch && arch[0]) {
1046 packet.
Printf(
"QLaunchArch:%s", arch);
1061 char const *data,
bool *was_supported) {
1062 if (data && *data !=
'\0') {
1064 packet.
Printf(
"QSetProcessEvent:%s", data);
1070 *was_supported =
true;
1074 *was_supported =
false;
1079 *was_supported =
true;
1103 return std::nullopt;
1106std::optional<std::string>
1112 return std::nullopt;
1140 UUID &uuid,
addr_t &value,
bool &value_is_offset) {
1173 llvm::StringRef name, value;
1174 bool success =
false;
1176 if (name ==
"name") {
1179 }
else if (name ==
"version") {
1180 llvm::StringRef major, minor;
1181 std::tie(major, minor) = value.split(
'.');
1195 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1197 llvm::StringRef avail_name;
1199#if HAVE_LIBCOMPRESSION
1201 for (
auto compression : supported_compressions) {
1202 if (compression ==
"lzfse") {
1204 avail_name = compression;
1210 for (
auto compression : supported_compressions) {
1211 if (compression ==
"zlib-deflate") {
1213 avail_name = compression;
1222 for (
auto compression : supported_compressions) {
1223 if (compression ==
"zlib-deflate") {
1225 avail_name = compression;
1232#if HAVE_LIBCOMPRESSION
1234 for (
auto compression : supported_compressions) {
1235 if (compression ==
"lz4") {
1237 avail_name = compression;
1243 for (
auto compression : supported_compressions) {
1244 if (compression ==
"lzma") {
1246 avail_name = compression;
1255 std::string packet =
"QEnableCompression:type:" + avail_name.str() +
";";
1302 tid = pid_tid->second;
1309 std::string &environment) {
1310 if (value ==
"iossimulator" || value ==
"tvossimulator" ||
1311 value ==
"watchossimulator" || value ==
"xrossimulator" ||
1312 value ==
"visionossimulator") {
1313 environment =
"simulator";
1314 os_name = value.drop_back(environment.size()).str();
1315 }
else if (value ==
"maccatalyst") {
1317 environment =
"macabi";
1319 os_name = value.str();
1335 llvm::StringRef name;
1336 llvm::StringRef value;
1339 std::string arch_name;
1340 std::string os_name;
1341 std::string environment;
1342 std::string vendor_name;
1344 uint32_t pointer_byte_size = 0;
1346 uint32_t num_keys_decoded = 0;
1348 if (name ==
"cputype") {
1350 if (!value.getAsInteger(0, cpu))
1352 }
else if (name ==
"cpusubtype") {
1354 if (!value.getAsInteger(0, sub))
1356 }
else if (name ==
"arch") {
1357 arch_name = std::string(value);
1359 }
else if (name ==
"triple") {
1363 }
else if (name ==
"distribution_id") {
1367 }
else if (name ==
"os_build") {
1371 }
else if (name ==
"hostname") {
1375 }
else if (name ==
"os_kernel") {
1379 }
else if (name ==
"ostype") {
1382 }
else if (name ==
"vendor") {
1383 vendor_name = std::string(value);
1385 }
else if (name ==
"endian") {
1386 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1393 }
else if (name ==
"ptrsize") {
1394 if (!value.getAsInteger(0, pointer_byte_size))
1396 }
else if (name ==
"addressing_bits") {
1400 }
else if (name ==
"high_mem_addressing_bits") {
1403 }
else if (name ==
"low_mem_addressing_bits") {
1406 }
else if (name ==
"os_version" ||
1413 }
else if (name ==
"maccatalyst_version") {
1416 }
else if (name ==
"watchpoint_exceptions_received") {
1418 llvm::StringSwitch<LazyBool>(value)
1424 }
else if (name ==
"default_packet_timeout") {
1425 uint32_t timeout_seconds;
1426 if (!value.getAsInteger(0, timeout_seconds)) {
1431 }
else if (name ==
"vm-page-size") {
1433 if (!value.getAsInteger(0, page_size)) {
1440 if (num_keys_decoded > 0)
1443 if (triple.empty()) {
1444 if (arch_name.empty()) {
1447 if (pointer_byte_size) {
1448 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1454 if (!vendor_name.empty())
1456 llvm::StringRef(vendor_name));
1457 if (!os_name.empty())
1458 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1459 if (!environment.empty())
1460 m_host_arch.GetTriple().setEnvironmentName(environment);
1464 triple += arch_name;
1465 if (!vendor_name.empty() || !os_name.empty()) {
1467 if (vendor_name.empty())
1468 triple +=
"unknown";
1470 triple += vendor_name;
1472 if (os_name.empty())
1473 triple +=
"unknown";
1479 llvm::Triple &host_triple =
m_host_arch.GetTriple();
1480 if (host_triple.getVendor() == llvm::Triple::Apple &&
1481 host_triple.getOS() == llvm::Triple::Darwin) {
1483 case llvm::Triple::aarch64:
1484 case llvm::Triple::aarch64_32:
1485 case llvm::Triple::arm:
1486 case llvm::Triple::thumb:
1487 host_triple.setOS(llvm::Triple::IOS);
1490 host_triple.setOS(llvm::Triple::MacOSX);
1494 if (pointer_byte_size) {
1495 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1503 if (pointer_byte_size) {
1504 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1511 "GDBRemoteCommunicationClient::%s parsed host "
1512 "architecture as %s, triple as %s from triple text %s",
1516 :
"<null-arch-name>",
1527 const char *data,
size_t data_len, std::chrono::seconds interrupt_timeout) {
1533 interrupt_timeout) ==
1557 return addressable_bits;
1567 uint32_t permissions) {
1571 const int packet_len = ::snprintf(
1572 packet,
sizeof(packet),
"_M%" PRIx64
",%s%s%s", (uint64_t)size,
1573 permissions & lldb::ePermissionsReadable ?
"r" :
"",
1574 permissions & lldb::ePermissionsWritable ?
"w" :
"",
1575 permissions & lldb::ePermissionsExecutable ?
"x" :
"");
1576 assert(packet_len < (
int)
sizeof(packet));
1596 const int packet_len =
1597 ::snprintf(packet,
sizeof(packet),
"_m%" PRIx64, (uint64_t)addr);
1598 assert(packet_len < (
int)
sizeof(packet));
1623 const int packet_len =
1624 ::snprintf(packet,
sizeof(packet),
"qSupportsDetachAndStayStopped:");
1625 assert(packet_len < (
int)
sizeof(packet));
1639 "Stays stopped not supported by this target.");
1655 "Multiprocess extension not supported by the server.");
1670 region_info.
Clear();
1675 const int packet_len = ::snprintf(
1676 packet,
sizeof(packet),
"qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1677 assert(packet_len < (
int)
sizeof(packet));
1683 llvm::StringRef name;
1684 llvm::StringRef value;
1686 bool success =
true;
1687 bool saw_permissions =
false;
1689 if (name ==
"start") {
1690 if (!value.getAsInteger(16, addr_value))
1692 }
else if (name ==
"size") {
1693 if (!value.getAsInteger(16, addr_value)) {
1701 }
else if (name ==
"permissions" && region_info.
GetRange().
IsValid()) {
1702 saw_permissions =
true;
1704 if (value.contains(
'r'))
1709 if (value.contains(
'w'))
1714 if (value.contains(
'x'))
1728 }
else if (name ==
"name") {
1732 region_info.
SetName(name.c_str());
1733 }
else if (name ==
"flags") {
1737 llvm::StringRef flags = value;
1738 llvm::StringRef flag;
1739 while (flags.size()) {
1740 flags = flags.ltrim();
1741 std::tie(flag, flags) = flags.split(
' ');
1746 else if (flag ==
"ss")
1750 }
else if (name ==
"type") {
1751 for (llvm::StringRef entry : llvm::split(value,
',')) {
1752 if (entry ==
"stack")
1754 else if (entry ==
"heap")
1757 }
else if (name ==
"error") {
1759 std::string error_string;
1763 }
else if (name ==
"dirty-pages") {
1764 std::vector<addr_t> dirty_page_list;
1765 for (llvm::StringRef x : llvm::split(value,
',')) {
1767 x.consume_front(
"0x");
1768 if (llvm::to_integer(x, page, 16))
1769 dirty_page_list.push_back(page);
1772 }
else if (name ==
"protection-key") {
1773 unsigned protection_key = 0;
1774 if (!value.getAsInteger(10, protection_key))
1785 if (!saw_permissions) {
1813 region_info = qXfer_region_info;
1816 region_info.
Clear();
1818 }
else if (qXfer_error.
Success()) {
1833 if (!
error.Success())
1836 if (map_region.GetRange().Contains(addr)) {
1837 region = map_region;
1863 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1869 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1885 if (memory_node.
GetName() !=
"memory")
1897 if (type ==
"rom") {
1900 }
else if (type ==
"ram") {
1904 }
else if (type ==
"flash") {
1907 [®ion](
const XMLNode &prop_node) ->
bool {
1910 if (prop_node.
GetName() !=
"property")
1913 if (propname ==
"blocksize") {
1935 std::optional<uint32_t> num;
1941 llvm::StringRef name;
1942 llvm::StringRef value;
1944 if (name ==
"num") {
1960WatchpointHardwareFeature
1979 return std::nullopt;
1984 std::string path{file_spec.
GetPath(
false)};
2004 std::string path{file_spec.
GetPath(
false)};
2024 std::string path{file_spec.
GetPath(
false)};
2045 if ((cols == 0) != (rows == 0))
2048 packet.
Printf(
"QSetSTDIOWindowSize:cols=%u;rows=%u",
2049 static_cast<unsigned>(cols),
static_cast<unsigned>(rows));
2073 return !cwd.empty();
2080 std::string path{working_dir.
GetPath(
false)};
2100 const int packet_len =
2101 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
2102 assert(packet_len < (
int)
sizeof(packet));
2117 const int packet_len = ::snprintf(packet,
sizeof(packet),
2118 "QSetDetachOnError:%i", enable ? 1 : 0);
2119 assert(packet_len < (
int)
sizeof(packet));
2135 llvm::StringRef name;
2136 llvm::StringRef value;
2142 std::string os_type;
2145 if (name ==
"pid") {
2147 value.getAsInteger(0, pid);
2149 }
else if (name ==
"ppid") {
2151 value.getAsInteger(0, pid);
2153 }
else if (name ==
"uid") {
2155 value.getAsInteger(0, uid);
2157 }
else if (name ==
"euid") {
2159 value.getAsInteger(0, uid);
2161 }
else if (name ==
"gid") {
2163 value.getAsInteger(0, gid);
2165 }
else if (name ==
"egid") {
2167 value.getAsInteger(0, gid);
2169 }
else if (name ==
"triple") {
2174 }
else if (name ==
"name") {
2181 }
else if (name ==
"args") {
2182 llvm::StringRef encoded_args(value), hex_arg;
2184 bool is_arg0 =
true;
2185 while (!encoded_args.empty()) {
2186 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2201 }
else if (name ==
"cputype") {
2202 value.getAsInteger(0, cpu);
2203 }
else if (name ==
"cpusubtype") {
2204 value.getAsInteger(0, sub);
2205 }
else if (name ==
"vendor") {
2206 vendor = std::string(value);
2207 }
else if (name ==
"ostype") {
2208 os_type = std::string(value);
2213 if (vendor ==
"apple") {
2217 llvm::StringRef(vendor));
2219 llvm::StringRef(os_type));
2231 process_info.
Clear();
2235 const int packet_len =
2236 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2237 assert(packet_len < (
int)
sizeof(packet));
2267 llvm::StringRef name;
2268 llvm::StringRef value;
2271 std::string os_name;
2272 std::string environment;
2273 std::string vendor_name;
2275 std::string elf_abi;
2276 uint32_t pointer_byte_size = 0;
2279 uint32_t num_keys_decoded = 0;
2282 if (name ==
"cputype") {
2283 if (!value.getAsInteger(16, cpu))
2285 }
else if (name ==
"cpusubtype") {
2286 if (!value.getAsInteger(16, sub)) {
2292 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2293 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2300 }
else if (name ==
"triple") {
2304 }
else if (name ==
"ostype") {
2307 }
else if (name ==
"vendor") {
2308 vendor_name = std::string(value);
2310 }
else if (name ==
"endian") {
2311 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2318 }
else if (name ==
"ptrsize") {
2319 if (!value.getAsInteger(16, pointer_byte_size))
2321 }
else if (name ==
"pid") {
2322 if (!value.getAsInteger(16, pid))
2324 }
else if (name ==
"elf_abi") {
2325 elf_abi = std::string(value);
2327 }
else if (name ==
"main-binary-uuid") {
2330 }
else if (name ==
"main-binary-slide") {
2338 }
else if (name ==
"main-binary-address") {
2346 }
else if (name ==
"binary-addresses") {
2349 for (llvm::StringRef x : llvm::split(value,
',')) {
2351 x.consume_front(
"0x");
2352 if (llvm::to_integer(x, vmaddr, 16))
2357 if (num_keys_decoded > 0)
2365 if (!triple.empty()) {
2368 if (pointer_byte_size) {
2369 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2372 !vendor_name.empty()) {
2373 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2374 if (!environment.empty())
2375 triple.setEnvironmentName(environment);
2377 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2378 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2379 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2380 switch (triple.getObjectFormat()) {
2381 case llvm::Triple::MachO:
2384 case llvm::Triple::ELF:
2387 case llvm::Triple::COFF:
2390 case llvm::Triple::GOFF:
2391 case llvm::Triple::SPIRV:
2392 case llvm::Triple::Wasm:
2393 case llvm::Triple::XCOFF:
2394 case llvm::Triple::DXContainer:
2395 LLDB_LOGF(log,
"error: not supported target architecture");
2397 case llvm::Triple::UnknownObjectFormat:
2398 LLDB_LOGF(log,
"error: failed to determine target architecture");
2402 if (pointer_byte_size) {
2403 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2408 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2410 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2424 process_infos.clear();
2432 bool has_name_match =
false;
2433 if (!name.empty()) {
2434 has_name_match =
true;
2436 switch (name_match_type) {
2438 has_name_match =
false;
2450 packet.
PutCString(
"name_match:starts_with;");
2461 if (has_name_match) {
2469 packet.
Printf(
"pid:%" PRIu64
";",
2472 packet.
Printf(
"parent_pid:%" PRIu64
";",
2479 packet.
Printf(
"euid:%u;",
2482 packet.
Printf(
"egid:%u;",
2488 const llvm::Triple &triple = match_arch.
GetTriple();
2504 process_infos.push_back(process_info);
2513 return process_infos.size();
2517 std::string &name) {
2520 const int packet_len =
2521 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2522 assert(packet_len < (
int)
sizeof(packet));
2544 std::string &name) {
2547 const int packet_len =
2548 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2549 assert(packet_len < (
int)
sizeof(packet));
2571 uint32_t recv_size) {
2573 packet.
Printf(
"qSpeedTest:response_size:%i;data:", recv_size);
2574 uint32_t bytes_left = send_size;
2575 while (bytes_left > 0) {
2576 if (bytes_left >= 26) {
2577 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2580 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2581 "abcdefghijklmnopqrstuvwxyz");
2590 return duration<float>::zero();
2591 using Dur = duration<float>;
2592 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2593 Dur mean = sum / v.size();
2596 float delta = (d - mean).count();
2597 accum += delta * delta;
2600 return Dur(sqrtf(accum / (v.size() - 1)));
2606 uint64_t recv_amount,
2607 bool json,
Stream &strm) {
2612 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2616 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2620 uint32_t result_idx = 0;
2622 std::vector<duration<float>> packet_times;
2624 for (send_size = 0; send_size <= max_send;
2625 send_size ? send_size *= 2 : send_size = 4) {
2626 for (uint32_t recv_size = 0; recv_size <= max_recv;
2627 recv_size ? recv_size *= 2 : recv_size = 4) {
2630 packet_times.clear();
2632 const auto start_time = steady_clock::now();
2633 for (uint32_t i = 0; i < num_packets; ++i) {
2634 const auto packet_start_time = steady_clock::now();
2637 const auto packet_end_time = steady_clock::now();
2638 packet_times.push_back(packet_end_time - packet_start_time);
2640 const auto end_time = steady_clock::now();
2641 const auto total_time = end_time - start_time;
2643 float packets_per_second =
2644 ((float)num_packets) / duration<float>(total_time).count();
2645 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2646 : duration<float>::zero();
2647 const duration<float> standard_deviation =
2650 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2651 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2652 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2653 result_idx > 0 ?
"," :
"", send_size, recv_size,
2654 total_time, standard_deviation);
2657 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2658 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2659 "standard deviation of {5,10:ms+f6}\n",
2660 send_size, recv_size, duration<float>(total_time),
2661 packets_per_second, duration<float>(average_per_packet),
2662 standard_deviation);
2668 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2670 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2671 ": %" PRIu64
",\n \"results\" : [",
2674 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2680 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2685 if (recv_size > 0) {
2686 const auto start_time = steady_clock::now();
2687 uint32_t bytes_read = 0;
2688 uint32_t packet_count = 0;
2689 while (bytes_read < recv_amount) {
2692 bytes_read += recv_size;
2695 const auto end_time = steady_clock::now();
2696 const auto total_time = end_time - start_time;
2697 float mb_second = ((float)recv_amount) /
2698 duration<float>(total_time).count() /
2700 float packets_per_second =
2701 ((float)packet_count) / duration<float>(total_time).count();
2702 const auto average_per_packet = packet_count > 0
2703 ? total_time / packet_count
2704 : duration<float>::zero();
2707 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2708 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2709 result_idx > 0 ?
"," :
"", send_size, recv_size,
2713 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2714 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2715 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2716 send_size, recv_size, packet_count, k_recv_amount_mb,
2717 duration<float>(total_time), mb_second,
2718 packets_per_second, duration<float>(average_per_packet));
2724 strm.
Printf(
"\n ]\n }\n}\n");
2731 uint32_t recv_size) {
2741 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2742 std::string &socket_name) {
2745 socket_name.clear();
2750 std::string hostname;
2751 if (remote_accept_hostname && remote_accept_hostname[0])
2752 hostname = remote_accept_hostname;
2754 if (HostInfo::GetHostname(hostname)) {
2756 stream.
Printf(
"host:%s;", hostname.c_str());
2760 stream.
Printf(
"host:*;");
2771 llvm::StringRef name;
2772 llvm::StringRef value;
2775 value.getAsInteger(0, port);
2776 else if (name ==
"pid")
2777 value.getAsInteger(0, pid);
2778 else if (name.compare(
"socket_name") == 0) {
2789 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2790 connection_urls.clear();
2806 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2807 std::optional<StructuredData::Dictionary *> maybe_element =
2816 port = port_osp->GetUnsignedIntegerValue(0);
2818 std::string socket_name;
2821 socket_name = std::string(socket_name_osp->GetStringValue());
2823 if (port != 0 || !socket_name.empty())
2824 connection_urls.emplace_back(port, socket_name);
2826 return connection_urls.size();
2831 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2843 uint64_t tid, uint64_t pid,
char op) {
2849 packet.
Printf(
"p%" PRIx64
".", pid);
2854 packet.
Printf(
"%" PRIx64, tid);
2860 return {{pid, tid}};
2872 return std::nullopt;
2887 return ret.has_value();
2902 return ret.has_value();
2917 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2918 assert(packet_len < (
int)
sizeof(packet));
2937 std::chrono::seconds timeout) {
2939 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2940 __FUNCTION__, insert ?
"add" :
"remove", addr);
2947 const int packet_len =
2948 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2949 insert ?
'Z' :
'z', type, addr, length);
2951 assert(packet_len + 1 < (
int)
sizeof(packet));
2996std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2998 bool &sequence_mutex_unavailable) {
2999 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
3003 sequence_mutex_unavailable =
false;
3007 for (packet_result =
3025 ids.push_back(*pid_tid);
3027 }
while (ch ==
',');
3041 ids.emplace_back(1, 1);
3045 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
3046 "packet 'qfThreadInfo'");
3047 sequence_mutex_unavailable =
true;
3054 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
3059 if (ids.empty() || sequence_mutex_unavailable)
3062 for (
auto id : ids) {
3068 thread_ids.push_back(
id.second);
3071 return thread_ids.size();
3084 llvm::StringRef command,
3092 std::string *separated_error_output,
3102 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3106 std::string path{working_dir.
GetPath(
false)};
3113 if (response.
GetChar() !=
'F')
3115 if (response.
GetChar() !=
',')
3120 else if (status_ptr)
3121 *status_ptr = exitcode;
3122 if (response.
GetChar() !=
',')
3127 if (response.
GetChar() !=
',')
3132 command_output->assign(output);
3139 uint32_t file_permissions) {
3140 std::string path{file_spec.
GetPath(
false)};
3146 llvm::StringRef packet = stream.
GetString();
3151 packet.str().c_str());
3153 if (response.
GetChar() !=
'F')
3155 packet.str().c_str());
3162 uint32_t file_permissions) {
3163 std::string path{file_spec.
GetPath(
false)};
3169 llvm::StringRef packet = stream.
GetString();
3176 if (response.
GetChar() !=
'F')
3185#define HANDLE_ERRNO(name, value) \
3188#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3197 if (response.
GetChar() !=
'F')
3199 int32_t result = response.
GetS32(-2, 16);
3202 if (response.
GetChar() ==
',') {
3204 if (result_errno != -1)
3216 std::string path(file_spec.
GetPath(
false));
3237 stream.
Printf(
"vFile:close:%x", (
int)fd);
3246std::optional<GDBRemoteFStatData>
3249 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3253 if (response.
GetChar() !=
'F')
3254 return std::nullopt;
3255 int64_t size = response.
GetS64(-1, 16);
3256 if (size > 0 && response.
GetChar() ==
';') {
3260 if (buffer.size() !=
sizeof(out))
3261 return std::nullopt;
3262 memcpy(&out, buffer.data(),
sizeof(out));
3267 return std::nullopt;
3270std::optional<GDBRemoteFStatData>
3275 return std::nullopt;
3276 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3285 std::string path(file_spec.
GetPath(
false));
3295 if (response.
GetChar() !=
'F')
3304 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3322 while (response.
Peek()) {
3324 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3327 if (response.
GetChar() !=
',')
3335 uint32_t &file_permissions) {
3337 std::string path{file_spec.
GetPath(
false)};
3350 if (response.
GetChar() !=
'F') {
3352 "invalid response to '%s' packet", stream.
GetData());
3354 const uint32_t mode = response.
GetS32(-1, 16);
3355 if (
static_cast<int32_t
>(mode) == -1) {
3356 if (response.
GetChar() ==
',') {
3358 if (response_errno > 0)
3375 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3383 uint64_t offset,
void *dst,
3387 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3392 if (response.
GetChar() !=
'F')
3394 int64_t retcode = response.
GetS64(-1, 16);
3395 if (retcode == -1) {
3397 if (response.
GetChar() ==
',') {
3399 if (response_errno > 0)
3404 const char next = (response.
Peek() ? *response.
Peek() : 0);
3411 const uint64_t data_to_write =
3412 std::min<uint64_t>(dst_len, buffer.size());
3413 if (data_to_write > 0)
3414 memcpy(dst, &buffer[0], data_to_write);
3415 return data_to_write;
3428 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3433 if (response.
GetChar() !=
'F') {
3437 int64_t bytes_written = response.
GetS64(-1, 16);
3438 if (bytes_written == -1) {
3440 if (response.
GetChar() ==
',') {
3442 if (response_errno > 0)
3447 return bytes_written;
3456 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3468 if (response.
GetChar() ==
'F') {
3472 if (response.
GetChar() ==
',') {
3474 if (response_errno > 0)
3489 std::string path{file_spec.
GetPath(
false)};
3499 if (response.
GetChar() ==
'F') {
3503 if (response.
GetChar() ==
',') {
3505 if (response_errno > 0)
3523 std::string path(file_spec.
GetPath(
false));
3532 if (response.
GetChar() !=
'F')
3534 if (response.
GetChar() !=
',')
3536 bool retcode = (response.
GetChar() !=
'0');
3553 std::string path(file_spec.
GetPath(
false));
3560 if (response.
GetChar() !=
'F')
3561 return std::make_error_code(std::errc::illegal_byte_sequence);
3562 if (response.
GetChar() !=
',')
3563 return std::make_error_code(std::errc::illegal_byte_sequence);
3564 if (response.
Peek() && *response.
Peek() ==
'x')
3565 return std::make_error_code(std::errc::no_such_file_or_directory);
3582 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3587 if (part.size() != MD5_HALF_LENGTH)
3588 return std::make_error_code(std::errc::illegal_byte_sequence);
3592 if (part.getAsInteger(16, low))
3593 return std::make_error_code(std::errc::illegal_byte_sequence);
3598 if (part.size() != MD5_HALF_LENGTH)
3599 return std::make_error_code(std::errc::illegal_byte_sequence);
3603 if (part.getAsInteger(16, high))
3604 return std::make_error_code(std::errc::illegal_byte_sequence);
3606 llvm::MD5::MD5Result result;
3607 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3608 result.data(), low);
3609 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3610 result.data() + 8, high);
3614 return std::make_error_code(std::errc::operation_canceled);
3624 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3625 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3626 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3627 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3630 if (gdb_server_version != 0) {
3632 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3633 if (gdb_server_version >= 310)
3646 payload.
Printf(
"p%x", reg);
3655 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3670 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3676 llvm::ArrayRef<uint8_t> data) {
3678 payload.
Printf(
"P%x=", reg_num);
3702 uint32_t &save_id) {
3718 const uint32_t response_save_id = response.
GetU32(0);
3719 if (response_save_id == 0)
3722 save_id = response_save_id;
3735 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3755 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3761llvm::Expected<TraceSupportedResponse>
3766 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3775 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3776 "jLLDBTraceSupported is unsupported");
3778 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3779 "TraceSupportedResponse");
3781 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3782 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3783 "failed to send packet: jLLDBTraceSupported");
3788 std::chrono::seconds timeout) {
3792 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3794 std::string json_string;
3795 llvm::raw_string_ostream os(json_string);
3798 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3807 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3808 "jLLDBTraceStop is unsupported");
3810 return llvm::Error::success();
3811 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3812 "Invalid jLLDBTraceStart response");
3814 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3815 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3816 "failed to send packet: jLLDBTraceStop '%s'",
3822 std::chrono::seconds timeout) {
3826 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3828 std::string json_string;
3829 llvm::raw_string_ostream os(json_string);
3832 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3841 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3842 "jLLDBTraceStart is unsupported");
3844 return llvm::Error::success();
3845 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3846 "Invalid jLLDBTraceStart response");
3848 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3849 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3850 "failed to send packet: jLLDBTraceStart '%s'",
3854llvm::Expected<std::string>
3856 std::chrono::seconds timeout) {
3860 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3862 std::string json_string;
3863 llvm::raw_string_ostream os(json_string);
3866 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3875 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3876 "jLLDBTraceGetState is unsupported");
3877 return std::string(response.
Peek());
3880 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3881 return llvm::createStringError(
3882 llvm::inconvertibleErrorCode(),
3883 "failed to send packet: jLLDBTraceGetState '%s'",
3887llvm::Expected<std::vector<uint8_t>>
3893 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3895 std::string json_string;
3896 llvm::raw_string_ostream os(json_string);
3899 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3909 return std::vector<uint8_t>(data.begin(), data.end());
3911 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3912 return llvm::createStringError(
3913 llvm::inconvertibleErrorCode(),
3914 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3922 return std::nullopt;
3924 return std::nullopt;
3928 const auto &GetOffset = [&] {
3930 if (ref.consumeInteger(16, offset))
3932 result.
offsets.push_back(offset);
3936 if (ref.consume_front(
"Text=")) {
3939 return std::nullopt;
3940 if (!ref.consume_front(
";Data=") || !GetOffset())
3941 return std::nullopt;
3944 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3946 }
else if (ref.consume_front(
"TextSeg=")) {
3949 return std::nullopt;
3952 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3955 return std::nullopt;
3964 std::string module_path = module_file_spec.
GetPath(
false);
3965 if (module_path.empty())
3972 const auto &triple = arch_spec.
GetTriple().getTriple();
3988 llvm::StringRef name;
3989 llvm::StringRef value;
3991 module_spec.
Clear();
3995 if (name ==
"uuid" || name ==
"md5") {
4000 }
else if (name ==
"triple") {
4005 }
else if (name ==
"file_offset") {
4007 if (!value.getAsInteger(16, ival))
4009 }
else if (name ==
"file_size") {
4011 if (!value.getAsInteger(16, ival))
4013 }
else if (name ==
"file_path") {
4024static std::optional<ModuleSpec>
4028 return std::nullopt;
4030 llvm::StringRef string;
4034 return std::nullopt;
4036 return std::nullopt;
4039 return std::nullopt;
4043 return std::nullopt;
4047 return std::nullopt;
4051 return std::nullopt;
4057std::optional<std::vector<ModuleSpec>>
4059 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4063 return std::nullopt;
4065 json::Array module_array;
4066 for (
const FileSpec &module_file_spec : module_file_specs) {
4067 module_array.push_back(
4068 json::Object{{
"file", module_file_spec.GetPath(
false)},
4069 {
"triple", triple.getTriple()}});
4072 unescaped_payload.
PutCString(
"jModulesInfo:");
4073 unescaped_payload.
AsRawOstream() << std::move(module_array);
4086 return std::nullopt;
4090 return std::nullopt;
4095 if (!response_object_sp)
4096 return std::nullopt;
4099 if (!response_array)
4100 return std::nullopt;
4102 std::vector<ModuleSpec> result;
4103 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
4106 result.push_back(*module_spec);
4116llvm::Expected<std::string>
4118 llvm::StringRef annex) {
4121 llvm::raw_string_ostream output_stream(output);
4135 std::string packet =
4136 (
"qXfer:" +
object +
":read:" + annex +
":" +
4137 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4145 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4146 "Error sending $qXfer packet");
4164 return llvm::createStringError(
4165 llvm::inconvertibleErrorCode(),
4166 "Invalid continuation code from $qXfer packet");
4216 bool symbol_response_provided =
false;
4219 bool first_qsymbol_query =
true;
4230 if (symbol_response_provided || first_qsymbol_query) {
4237 first_qsymbol_query =
false;
4246 if (response_str.starts_with(
"qSymbol:")) {
4248 std::string symbol_name;
4250 if (symbol_name.empty())
4261 switch (sc.symbol->GetType()) {
4294 sc.symbol->GetLoadAddress(&process->
GetTarget());
4307 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4308 symbol_response_provided =
true;
4310 symbol_response_provided =
false;
4326 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4351 "GDBRemoteCommunicationClient::%s(): "
4352 "QSupportedAsyncJSONPackets returned invalid "
4359 "GDBRemoteCommunicationClient::%s(): "
4360 "QSupportedAsyncJSONPackets unsupported",
4368 "GDBRemoteCommunicationClient::%s(): supported async "
4370 __FUNCTION__, stream.
GetData());
4380 llvm::ArrayRef<int32_t> signals) {
4383 auto range = llvm::make_range(signals.begin(), signals.end());
4384 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4396 "Unknown error happened during sending QPassSignals packet.");
4404 if (type_name.empty()) {
4417 config_sp->Dump(unescaped_stream);
4418 unescaped_stream.
Flush();
4436 "configuring StructuredData feature {0} failed with error {1}",
4442 "configuring StructuredData feature {0} failed when sending packet: "
4444 type_name, (
int)result);
4473 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4474 "failed to send k packet");
4476 char packet_cmd = response.
GetChar(0);
4477 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4480 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4481 "unexpected response to k packet: %s",
static llvm::raw_ostream & error(Stream &strm)
duration< float > calculate_standard_deviation(const std::vector< duration< float > > &v)
static std::optional< ModuleSpec > ParseModuleSpec(StructuredData::Dictionary *dict)
static int gdb_errno_to_system(int err)
static void ParseOSType(llvm::StringRef value, std::string &os_name, std::string &environment)
static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response, uint64_t fail_result, Status &error)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
A command line argument class.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
void Clear()
Clear the arguments.
bool IsConnected() const
Check if the connection is valid.
virtual lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr)
Disconnect the communications connection if one is currently connected.
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
llvm::StringRef GetCursorArgumentPrefix() const
A uniqued constant string class.
A subclass of DataBuffer that stores a data buffer on the heap.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void SetReadable(LazyBool val)
LazyBool GetFlash() const
MemoryRegionInfo & SetMemoryTagged(LazyBool val)
void SetBlocksize(lldb::offset_t blocksize)
void SetFlash(LazyBool val)
void SetPageSize(int pagesize)
void SetName(const char *name)
MemoryRegionInfo & SetIsShadowStack(LazyBool val)
lldb::offset_t GetBlocksize() const
MemoryRegionInfo & SetIsStackMemory(LazyBool val)
void SetDirtyPageList(std::vector< lldb::addr_t > pagelist)
MemoryRegionInfo & SetProtectionKey(std::optional< unsigned > key)
void SetMapped(LazyBool val)
void SetExecutable(LazyBool val)
void SetWritable(LazyBool val)
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
void SetObjectSize(uint64_t object_size)
ArchSpec & GetArchitecture()
void SetObjectOffset(uint64_t object_offset)
void SetGroupID(uint32_t gid)
bool ProcessIDIsValid() const
void SetArg0(llvm::StringRef arg)
lldb::pid_t GetProcessID() const
void SetProcessID(lldb::pid_t pid)
FileSpec & GetExecutableFile()
llvm::StringRef GetName() const
bool UserIDIsValid() const
uint32_t GetUserID() const
uint32_t GetGroupID() const
void SetUserID(uint32_t uid)
bool GroupIDIsValid() const
ArchSpec & GetArchitecture()
bool MatchAllProcesses() const
NameMatch GetNameMatchType() const
bool GetMatchAllUsers() const
ProcessInstanceInfo & GetProcessInfo()
uint32_t GetEffectiveUserID() const
void SetEffectiveGroupID(uint32_t gid)
lldb::pid_t GetParentProcessID() const
bool ParentProcessIDIsValid() const
uint32_t GetEffectiveGroupID() const
bool EffectiveUserIDIsValid() const
bool EffectiveGroupIDIsValid() const
void SetParentProcessID(lldb::pid_t pid)
void SetEffectiveUserID(uint32_t uid)
A plug-in interface definition class for debugging a process.
Target & GetTarget()
Get the target object pointer for this module.
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
int PutAsJSON(const T &obj, bool hex_ascii)
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)
Forwards the arguments to llvm::formatv and writes to the stream.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t PutStringAsRawHex8(llvm::StringRef s)
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
virtual void Flush()=0
Flush the stream.
size_t EOL()
Output and End of Line character to the stream.
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
ObjectSP GetItemAtIndex(size_t idx) const
std::optional< Dictionary * > GetItemAtIndexAsDictionary(size_t idx) const
Retrieves the element at index idx from a StructuredData::Array if it is a Dictionary.
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
ObjectSP GetValueForKey(llvm::StringRef key) const
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
Defines a list of symbol context objects.
Defines a symbol context baton that can be handed other debug core functions.
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
Represents UUID's of various sizes.
bool SetFromStringRef(llvm::StringRef str)
XMLNode GetRootElement(const char *required_name=nullptr)
bool ParseMemory(const char *xml, size_t xml_length, const char *url="untitled.xml")
void ForEachChildElement(NodeCallback const &callback) const
llvm::StringRef GetName() const
std::string GetAttributeValue(const char *name, const char *fail_value=nullptr) const
bool GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value=0, int base=0) const
bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value, uint64_t fail_value=0, int base=0) const
GDBRemoteClientBase(const char *comm_name)
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0), bool sync_on_timeout=true)
PacketResult SendPacketAndWaitForResponseNoLock(llvm::StringRef payload, StringExtractorGDBRemote &response, bool sync_on_timeout=true)
virtual void OnRunPacketSent(bool first)
lldb::DataBufferSP ReadRegister(lldb::tid_t tid, uint32_t reg_num)
std::chrono::seconds m_default_packet_timeout
LazyBool m_supports_vCont_S
LazyBool m_supports_detach_stay_stopped
LazyBool m_supports_alloc_dealloc_memory
bool SupportsGDBStoppointPacket(GDBStoppointType type)
ArchSpec GetSystemArchitecture()
bool RestoreRegisterState(lldb::tid_t tid, uint32_t save_id)
const ArchSpec & GetHostArchitecture()
int SendLaunchArchPacket(const char *arch)
lldb::pid_t GetCurrentProcessID(bool allow_lazy=true)
bool AvoidGPackets(ProcessGDBRemote *process)
llvm::VersionTuple GetMacCatalystVersion()
Status CreateSymlink(const FileSpec &src, const FileSpec &dst)
PacketResult SendThreadSpecificPacketAndWaitForResponse(lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response)
LazyBool m_qGDBServerVersion_is_valid
bool GetLoadedDynamicLibrariesInfosSupported()
bool GetHostInfo(bool force=false)
LazyBool m_supports_memory_region_info
LazyBool m_qHostInfo_is_valid
bool KillSpawnedProcess(lldb::pid_t pid)
bool m_supports_jModulesInfo
lldb_private::AddressableBits GetAddressableBits()
LazyBool m_supports_jGetSharedCacheInfo
bool GetReverseContinueSupported()
bool 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 SetSTDIOWindowSize(uint16_t cols, uint16_t rows)
Send the dimensions of the user's stdio terminal window to the server.
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 GetAcceleratorPluginsSupported()
bool m_supports_vFileMode
bool GetMultiprocessSupported()
LazyBool m_qProcessInfo_is_valid
LazyBool m_supports_vCont_c
std::optional< GDBRemoteFStatData > Stat(const FileSpec &file_spec)
std::optional< QOffsets > GetQOffsets()
Use qOffsets to query the offset used when relocating the target executable.
size_t QueryGDBServer(std::vector< std::pair< uint16_t, std::string > > &connection_urls)
int m_target_vm_page_size
llvm::Error SendTraceStop(const TraceStopRequest &request, std::chrono::seconds interrupt_timeout)
uint32_t m_num_supported_hardware_watchpoints
std::optional< xPacketState > m_x_packet_state
void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm)
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions)
std::string m_host_distribution_id
GDBRemoteCommunicationClient()
std::optional< std::string > GetOSBuildString()
bool LaunchGDBServer(const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port, std::string &socket_name)
int SetSTDOUT(const FileSpec &file_spec)
LazyBool m_prepare_for_reg_writing_reply
bool m_supports_qThreadStopInfo
bool SetCurrentThreadForRun(uint64_t tid, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
uint8_t SendGDBStoppointTypePacket(GDBStoppointType type, bool insert, lldb::addr_t addr, uint32_t length, std::chrono::seconds interrupt_timeout)
bool GetpPacketSupported(lldb::tid_t tid)
Status MakeDirectory(const FileSpec &file_spec, uint32_t mode)
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
Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, std::string *separated_error_output, const Timeout< std::micro > &timeout)
LazyBool m_supports_memory_tagging
llvm::Expected< std::string > SendTraceGetState(llvm::StringRef type, std::chrono::seconds interrupt_timeout)
void ResetDiscoverableSettings(bool did_exec)
llvm::Error LaunchProcess(const Args &args)
Launch the process using the provided arguments.
LazyBool m_supports_qXfer_libraries_svr4_read
bool m_process_standalone_value_is_offset
lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp
LazyBool m_attach_or_wait_reply
bool m_supports_jThreadsInfo
bool GetGDBServerVersion()
lldb::user_id_t GetFileSize(const FileSpec &file_spec)
bool GetQXferFeaturesReadSupported()
LazyBool m_watchpoints_trigger_after_instruction
LazyBool m_supports_threads_in_stop_reply
std::vector< lldb::addr_t > m_binary_addresses
void GetRemoteQSupported()
bool GetQPassSignalsSupported()
Status ConfigureRemoteStructuredData(llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp)
Configure a StructuredData feature on the remote end.
bool CloseFile(lldb::user_id_t fd, Status &error)
~GDBRemoteCommunicationClient() override
bool GetReverseStepSupported()
uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error)
llvm::Expected< std::vector< AcceleratorActions > > GetAcceleratorInitializeActions()
Send the "jAcceleratorPluginInitialize" packet and return the actions requested by each accelerator p...
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
int SendStdinNotification(const char *data, size_t data_len, std::chrono::seconds interrupt_timeout=std::chrono::seconds(0))
Sends a GDB remote protocol 'I' packet that delivers stdin data to the remote process.
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_multi_breakpoint
LazyBool m_supports_qXfer_memory_map_read
bool GetHostname(std::string &s)
llvm::Expected< int > KillProcess(lldb::pid_t pid)
bool m_supported_async_json_packets_is_valid
bool GetSyncThreadStateSupported()
bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef< uint8_t > data)
bool m_supports_QEnvironmentHexEncoded
bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info)
Status SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
LazyBool m_curr_pid_is_valid
Status GetQXferMemoryMapRegionInfo(lldb::addr_t addr, MemoryRegionInfo ®ion)
int SetDetachOnError(bool enable)
Sets the DetachOnError flag to enable for the process controlled by the stub.
void OnRunPacketSent(bool first) override
bool m_supports_QEnvironment
lldb::addr_t GetShlibInfoAddr()
Status SendSignalsToIgnore(llvm::ArrayRef< int32_t > signals)
LazyBool m_supports_jThreadExtendedInfo
LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr)
UUID m_process_standalone_uuid
LazyBool m_supports_not_sending_acks
LazyBool m_supports_watchpoint_support_info
bool WriteRegister(lldb::tid_t tid, uint32_t reg_num, llvm::ArrayRef< uint8_t > data)
uint64_t m_max_packet_size
void EnableErrorStringInPacket()
LazyBool m_supports_accelerator_plugins
llvm::Expected< std::vector< uint8_t > > SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request, std::chrono::seconds interrupt_timeout)
LazyBool m_supports_qXfer_libraries_read
bool GetSaveCoreSupported() const
LazyBool m_supports_jLoadedDynamicLibrariesInfos
Status LoadQXferMemoryMap()
LazyBool m_supports_thread_suffix
int SetSTDIN(const FileSpec &file_spec)
Sets the path to use for stdin/out/err for a process that will be launched with the 'A' packet.
LazyBool m_supports_vCont_C
lldb::pid_t m_curr_pid
Current gdb remote protocol process identifier for all other operations.
Status WriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, const std::vector< uint8_t > &tags)
LazyBool m_supports_qSaveCore
LazyBool m_supports_reverse_step
bool GetQXferLibrariesSVR4ReadSupported()
size_t GetCurrentThreadIDs(std::vector< lldb::tid_t > &thread_ids, bool &sequence_mutex_unavailable)
Status Detach(bool keep_stopped, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
std::optional< bool > GetWatchpointReportedAfter()
std::string m_gdb_server_name
std::vector< lldb::addr_t > GetProcessStandaloneBinaries()
bool m_supports_qProcessInfoPID
llvm::VersionTuple m_os_version
bool GetQXferLibrariesReadSupported()
llvm::VersionTuple m_maccatalyst_version
int SetDisableASLR(bool enable)
Sets the disable ASLR flag to enable for a process that will be launched with the 'A' packet.
bool GetUserName(uint32_t uid, std::string &name)
Status GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info)
std::vector< MemoryRegionInfo > m_qXfer_memory_map
bool SyncThreadState(lldb::tid_t tid)
bool m_supports_qfProcessInfo
std::chrono::seconds GetHostDefaultPacketTimeout()
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()
bool GetMultiBreakpointSupported()
xPacketState GetxPacketState()
llvm::ErrorOr< llvm::MD5::MD5Result > CalculateMD5(const FileSpec &file_spec)
bool GetVContSupported(llvm::StringRef flavor)
uint32_t GetGDBServerProgramVersion()
LazyBool m_supports_reverse_continue
llvm::Error SendTraceStart(const llvm::json::Value &request, std::chrono::seconds interrupt_timeout)
bool GetStopReply(StringExtractorGDBRemote &response)
bool m_supports_qUserName
bool GetQXferMemoryMapReadSupported()
bool m_qXfer_memory_map_loaded
llvm::Expected< AcceleratorBreakpointHitResponse > AcceleratorBreakpointHit(const AcceleratorBreakpointHitArgs &args)
Send the "jAcceleratorPluginBreakpointHit" packet to notify the accelerator plugin that one of its re...
bool GetModuleInfo(const FileSpec &module_file_spec, const ArchSpec &arch_spec, ModuleSpec &module_spec)
LazyBool m_supports_vCont_all
std::optional< PidTid > SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid, char op)
bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size)
LazyBool m_supports_multi_mem_read
LazyBool m_supports_QPassSignals
bool GetFileExists(const FileSpec &file_spec)
Status GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
uint32_t FindProcesses(const ProcessInstanceInfoMatch &process_match_info, ProcessInstanceInfoList &process_infos)
lldb::DataBufferSP ReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type)
bool GetMultiMemReadSupported()
bool GetQXferSigInfoReadSupported()
uint32_t m_gdb_server_version
int SetWorkingDir(const FileSpec &working_dir)
Sets the working directory to path for a process that will be launched with the 'A' packet for non pl...
LazyBool m_avoid_g_packets
std::vector< std::pair< lldb::pid_t, lldb::tid_t > > GetCurrentProcessAndThreadIDs(bool &sequence_mutex_unavailable)
bool GetThreadStopInfo(lldb::tid_t tid, StringExtractorGDBRemote &response)
bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id)
bool GetProcessStandaloneBinary(UUID &uuid, lldb::addr_t &value, bool &value_is_offset)
LazyBool m_supports_QSaveRegisterState
WatchpointHardwareFeature m_watchpoint_types
void GetListThreadsInStopReplySupported()
StructuredData::ObjectSP GetThreadsInfo()
std::string m_qSupported_response
bool GetSharedCacheInfoSupported()
LazyBool m_supports_qXfer_auxv_read
bool m_supports_qModuleInfo
const char * GetGDBServerProgramName()
LazyBool m_supports_jGetDyldProcessState
int SendEnvironmentPacket(char const *name_equal_value)
Sends a "QEnvironment:NAME=VALUE" packet that will build up the environment that will get used when l...
std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout)
LazyBool m_supports_qEcho
CompressionType m_compression_type
std::chrono::seconds GetPacketTimeout() const
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_CPUTYPE
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
lldb::ByteOrder InlHostByteOrder()
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const QOffsets &offsets)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
llvm::json::Value toJSON(const Diagnostics::Report &report)
Render a diagnostics report as JSON, for diagnostics dump's terminal output.
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
@ 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
Sent by the client when a plugin-requested breakpoint is hit.
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.