38#include "lldb/Host/Config.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
43#include "llvm/Config/llvm-config.h"
44#include "llvm/Support/ErrorExtras.h"
45#include "llvm/Support/JSON.h"
46#include "llvm/TargetParser/Triple.h"
48#if HAVE_LIBCOMPRESSION
49#include <compression.h>
55using namespace std::chrono;
59 return os << llvm::formatv(
60 "QOffsets({0}, [{1:@[x]}])", offsets.
segments,
95 std::chrono::steady_clock::time_point start_of_handshake =
96 std::chrono::steady_clock::now();
105 std::chrono::steady_clock::time_point end_of_handshake =
106 std::chrono::steady_clock::now();
107 auto handshake_timeout =
108 std::chrono::duration<double>(end_of_handshake - start_of_handshake)
114 "while waiting for reply to initial "
118 "failed to get reply to handshake packet within timeout of "
236llvm::Expected<std::vector<AcceleratorActions>>
244 return std::vector<AcceleratorActions>();
250 return llvm::createStringError(
251 "failed to send jAcceleratorPluginInitialize packet");
254 return std::vector<AcceleratorActions>();
259 llvm::Expected<std::vector<AcceleratorActions>> actions =
260 llvm::json::parse<std::vector<AcceleratorActions>>(response.
Peek(),
261 "AcceleratorActions");
268 return llvm::createStringErrorV(
269 "malformed jAcceleratorPluginInitialize response '{0}': {1}",
270 response.
GetStringRef(), llvm::toString(actions.takeError()));
273llvm::Expected<AcceleratorBreakpointHitResponse>
277 packet.
PutCString(
"jAcceleratorPluginBreakpointHit:");
283 return llvm::createStringError(
284 "failed to send jAcceleratorPluginBreakpointHit packet");
289 llvm::Expected<AcceleratorBreakpointHitResponse> hit_response =
290 llvm::json::parse<AcceleratorBreakpointHitResponse>(
291 response.
Peek(),
"AcceleratorBreakpointHitResponse");
298 return llvm::createStringErrorV(
299 "malformed jAcceleratorPluginBreakpointHit response '{0}': {1}",
300 response.
GetStringRef(), llvm::toString(hit_response.takeError()));
468 std::vector<std::string> features = {
"xmlRegisters=i386,arm,mips,arc",
474 "qXfer:libraries:read+",
475 "qXfer:libraries-svr4:read+"};
478 for (uint32_t i = 0; i < features.size(); ++i) {
490 for (llvm::StringRef x : llvm::split(response.
GetStringRef(),
';')) {
491 if (x ==
"qXfer:auxv:read+")
493 else if (x ==
"qXfer:libraries-svr4:read+")
495 else if (x ==
"augmented-libraries-svr4-read") {
498 }
else if (x ==
"qXfer:libraries:read+")
500 else if (x ==
"qXfer:features:read+")
502 else if (x ==
"qXfer:memory-map:read+")
504 else if (x ==
"qXfer:siginfo:read+")
506 else if (x ==
"qEcho+")
508 else if (x ==
"QPassSignals+")
510 else if (x ==
"multiprocess+")
512 else if (x ==
"memory-tagging+")
514 else if (x ==
"qSaveCore+")
516 else if (x ==
"native-signals+")
518 else if (x ==
"binary-upload+")
520 else if (x ==
"ReverseContinue+")
522 else if (x ==
"ReverseStep+")
524 else if (x ==
"MultiMemRead+")
526 else if (x ==
"jMultiBreakpoint+")
528 else if (x ==
"accelerator-plugins+")
533 else if (x.consume_front(
"SupportedCompressions=")) {
534 llvm::SmallVector<llvm::StringRef, 4> compressions;
535 x.split(compressions,
',');
536 if (!compressions.empty())
538 }
else if (x.consume_front(
"SupportedWatchpointTypes=")) {
539 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
540 x.split(watchpoint_types,
',');
542 for (
auto wp_type : watchpoint_types) {
543 if (wp_type ==
"x86_64")
545 if (wp_type ==
"aarch64-mask")
547 if (wp_type ==
"aarch64-bas")
550 }
else if (x.consume_front(
"PacketSize=")) {
557 LLDB_LOGF(log,
"Garbled PacketSize spec in qSupported response");
578 assert(!flavor.empty());
589 for (llvm::StringRef token : llvm::split(response.
GetStringRef(),
';')) {
616 return llvm::StringSwitch<bool>(flavor)
634 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
636 __FUNCTION__, payload.GetData());
641 payload.Printf(
";thread:%4.4" PRIx64
";", tid);
688 }
else if (!response.
Empty()) {
777 packet.
Printf(
"qMemTags:%" PRIx64
",%zx:%" PRIx32, addr, len, type);
785 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s: qMemTags packet failed",
793 if (response.
GetChar() !=
'm') {
795 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
806 if (response.
GetBytesLeft() || (expected_bytes != got_bytes)) {
809 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
819 const std::vector<uint8_t> &tags) {
822 packet.
Printf(
"QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr, len, type);
868 if (response.
GetChar() ==
'Q') {
869 if (response.
GetChar() ==
'C') {
883 bool sequence_mutex_unavailable;
885 if (!ids.empty() && !sequence_mutex_unavailable) {
902 return llvm::createStringError(llvm::inconvertibleErrorCode(),
903 "Nothing to launch");
916 return llvm::createStringError(llvm::inconvertibleErrorCode(),
917 "Sending vRun packet failed");
926 return llvm::Error::success();
934 llvm::ListSeparator LS(
",");
935 for (
const auto &arg : llvm::enumerate(args)) {
937 packet.
Format(
"{0},{1},", arg.value().ref().size() * 2, arg.index());
944 return llvm::createStringError(llvm::inconvertibleErrorCode(),
945 "Sending A packet failed");
952 return llvm::createStringError(llvm::inconvertibleErrorCode(),
953 "Sending qLaunchSuccess packet failed");
956 return llvm::Error::success();
957 if (response.
GetChar() ==
'E') {
958 return llvm::createStringError(llvm::inconvertibleErrorCode(),
961 return llvm::createStringError(llvm::inconvertibleErrorCode(),
962 "unknown error occurred launching process");
966 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
967 for (
const auto &kv : env)
968 vec.emplace_back(kv.first(), kv.second);
969 llvm::sort(vec, llvm::less_first());
970 for (
const auto &[k, v] : vec) {
979 char const *name_equal_value) {
980 if (name_equal_value && name_equal_value[0]) {
981 bool send_hex_encoding =
false;
982 for (
const char *p = name_equal_value; *p !=
'\0' && !send_hex_encoding;
984 if (llvm::isPrint(*p)) {
990 send_hex_encoding =
true;
997 send_hex_encoding =
true;
1005 packet.
Printf(
"QEnvironment:%s", name_equal_value);
1024 packet.
PutCString(
"QEnvironmentHexEncoded:");
1046 if (arch && arch[0]) {
1048 packet.
Printf(
"QLaunchArch:%s", arch);
1063 char const *data,
bool *was_supported) {
1064 if (data && *data !=
'\0') {
1066 packet.
Printf(
"QSetProcessEvent:%s", data);
1072 *was_supported =
true;
1076 *was_supported =
false;
1081 *was_supported =
true;
1105 return std::nullopt;
1108std::optional<std::string>
1114 return std::nullopt;
1142 UUID &uuid,
addr_t &value,
bool &value_is_offset) {
1175 llvm::StringRef name, value;
1176 bool success =
false;
1178 if (name ==
"name") {
1181 }
else if (name ==
"version") {
1182 llvm::StringRef major, minor;
1183 std::tie(major, minor) = value.split(
'.');
1197 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1199 llvm::StringRef avail_name;
1201#if HAVE_LIBCOMPRESSION
1203 for (
auto compression : supported_compressions) {
1204 if (compression ==
"lzfse") {
1206 avail_name = compression;
1212 for (
auto compression : supported_compressions) {
1213 if (compression ==
"zlib-deflate") {
1215 avail_name = compression;
1224 for (
auto compression : supported_compressions) {
1225 if (compression ==
"zlib-deflate") {
1227 avail_name = compression;
1234#if HAVE_LIBCOMPRESSION
1236 for (
auto compression : supported_compressions) {
1237 if (compression ==
"lz4") {
1239 avail_name = compression;
1245 for (
auto compression : supported_compressions) {
1246 if (compression ==
"lzma") {
1248 avail_name = compression;
1257 std::string packet =
"QEnableCompression:type:" + avail_name.str() +
";";
1304 tid = pid_tid->second;
1311 std::string &environment) {
1312 if (value ==
"iossimulator" || value ==
"tvossimulator" ||
1313 value ==
"watchossimulator" || value ==
"xrossimulator" ||
1314 value ==
"visionossimulator") {
1315 environment =
"simulator";
1316 os_name = value.drop_back(environment.size()).str();
1317 }
else if (value ==
"maccatalyst") {
1319 environment =
"macabi";
1321 os_name = value.str();
1337 llvm::StringRef name;
1338 llvm::StringRef value;
1341 std::string arch_name;
1342 std::string os_name;
1343 std::string environment;
1344 std::string vendor_name;
1346 uint32_t pointer_byte_size = 0;
1348 uint32_t num_keys_decoded = 0;
1350 if (name ==
"cputype") {
1352 if (!value.getAsInteger(
BASE_10, cpu))
1354 }
else if (name ==
"cpusubtype") {
1356 if (!value.getAsInteger(
BASE_10, sub))
1358 }
else if (name ==
"arch") {
1359 arch_name = std::string(value);
1361 }
else if (name ==
"triple") {
1365 }
else if (name ==
"distribution_id") {
1369 }
else if (name ==
"os_build") {
1373 }
else if (name ==
"hostname") {
1377 }
else if (name ==
"os_kernel") {
1381 }
else if (name ==
"ostype") {
1384 }
else if (name ==
"vendor") {
1385 vendor_name = std::string(value);
1387 }
else if (name ==
"endian") {
1388 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1395 }
else if (name ==
"ptrsize") {
1396 if (!value.getAsInteger(
BASE_10, pointer_byte_size))
1398 }
else if (name ==
"addressing_bits") {
1402 }
else if (name ==
"high_mem_addressing_bits") {
1405 }
else if (name ==
"low_mem_addressing_bits") {
1408 }
else if (name ==
"os_version" ||
1415 }
else if (name ==
"maccatalyst_version") {
1418 }
else if (name ==
"watchpoint_exceptions_received") {
1420 llvm::StringSwitch<LazyBool>(value)
1426 }
else if (name ==
"default_packet_timeout") {
1427 uint32_t timeout_seconds;
1428 if (!value.getAsInteger(
BASE_10, timeout_seconds)) {
1433 }
else if (name ==
"vm-page-size") {
1435 if (!value.getAsInteger(
BASE_10, page_size)) {
1442 if (num_keys_decoded > 0)
1445 if (triple.empty()) {
1446 if (arch_name.empty()) {
1449 if (pointer_byte_size) {
1450 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1456 if (!vendor_name.empty())
1458 llvm::StringRef(vendor_name));
1459 if (!os_name.empty())
1460 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1461 if (!environment.empty())
1462 m_host_arch.GetTriple().setEnvironmentName(environment);
1466 triple += arch_name;
1467 if (!vendor_name.empty() || !os_name.empty()) {
1469 if (vendor_name.empty())
1470 triple +=
"unknown";
1472 triple += vendor_name;
1474 if (os_name.empty())
1475 triple +=
"unknown";
1481 llvm::Triple &host_triple =
m_host_arch.GetTriple();
1482 if (host_triple.getVendor() == llvm::Triple::Apple &&
1483 host_triple.getOS() == llvm::Triple::Darwin) {
1485 case llvm::Triple::aarch64:
1486 case llvm::Triple::aarch64_32:
1487 case llvm::Triple::arm:
1488 case llvm::Triple::thumb:
1489 host_triple.setOS(llvm::Triple::IOS);
1492 host_triple.setOS(llvm::Triple::MacOSX);
1496 if (pointer_byte_size) {
1497 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1505 if (pointer_byte_size) {
1506 assert(pointer_byte_size ==
m_host_arch.GetAddressByteSize());
1513 "GDBRemoteCommunicationClient::%s parsed host "
1514 "architecture as %s, triple as %s from triple text %s",
1518 :
"<null-arch-name>",
1529 const char *data,
size_t data_len, std::chrono::seconds interrupt_timeout) {
1535 interrupt_timeout) ==
1559 return addressable_bits;
1569 uint32_t permissions) {
1573 const int packet_len = ::snprintf(
1574 packet,
sizeof(packet),
"_M%" PRIx64
",%s%s%s", (uint64_t)size,
1575 permissions & lldb::ePermissionsReadable ?
"r" :
"",
1576 permissions & lldb::ePermissionsWritable ?
"w" :
"",
1577 permissions & lldb::ePermissionsExecutable ?
"x" :
"");
1578 assert(packet_len < (
int)
sizeof(packet));
1598 const int packet_len =
1599 ::snprintf(packet,
sizeof(packet),
"_m%" PRIx64, (uint64_t)addr);
1600 assert(packet_len < (
int)
sizeof(packet));
1625 const int packet_len =
1626 ::snprintf(packet,
sizeof(packet),
"qSupportsDetachAndStayStopped:");
1627 assert(packet_len < (
int)
sizeof(packet));
1641 "Stays stopped not supported by this target.");
1657 "Multiprocess extension not supported by the server.");
1672 region_info.
Clear();
1677 const int packet_len = ::snprintf(
1678 packet,
sizeof(packet),
"qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1679 assert(packet_len < (
int)
sizeof(packet));
1685 llvm::StringRef name;
1686 llvm::StringRef value;
1688 bool success =
true;
1689 bool saw_permissions =
false;
1691 if (name ==
"start") {
1692 if (!value.getAsInteger(
BASE_16, addr_value))
1694 }
else if (name ==
"size") {
1695 if (!value.getAsInteger(
BASE_16, addr_value)) {
1703 }
else if (name ==
"permissions" && region_info.
GetRange().
IsValid()) {
1704 saw_permissions =
true;
1706 if (value.contains(
'r'))
1711 if (value.contains(
'w'))
1716 if (value.contains(
'x'))
1730 }
else if (name ==
"name") {
1734 region_info.
SetName(name.c_str());
1735 }
else if (name ==
"flags") {
1739 llvm::StringRef flags = value;
1740 llvm::StringRef flag;
1741 while (flags.size()) {
1742 flags = flags.ltrim();
1743 std::tie(flag, flags) = flags.split(
' ');
1748 else if (flag ==
"ss")
1752 }
else if (name ==
"type") {
1753 for (llvm::StringRef entry : llvm::split(value,
',')) {
1754 if (entry ==
"stack")
1756 else if (entry ==
"heap")
1759 }
else if (name ==
"error") {
1761 std::string error_string;
1765 }
else if (name ==
"dirty-pages") {
1766 std::vector<addr_t> dirty_page_list;
1767 for (llvm::StringRef x : llvm::split(value,
',')) {
1769 x.consume_front(
"0x");
1770 if (llvm::to_integer(x, page, 16))
1771 dirty_page_list.push_back(page);
1774 }
else if (name ==
"protection-key") {
1775 unsigned protection_key = 0;
1776 if (!value.getAsInteger(
BASE_10, protection_key))
1787 if (!saw_permissions) {
1815 region_info = qXfer_region_info;
1818 region_info.
Clear();
1820 }
else if (qXfer_error.
Success()) {
1835 if (!
error.Success())
1838 if (map_region.GetRange().Contains(addr)) {
1839 region = map_region;
1865 llvm::Expected<std::string> xml =
ReadExtFeature(
"memory-map",
"");
1871 if (!xml_document.
ParseMemory(xml->c_str(), xml->size())) {
1887 if (memory_node.
GetName() !=
"memory")
1899 if (type ==
"rom") {
1902 }
else if (type ==
"ram") {
1906 }
else if (type ==
"flash") {
1909 [®ion](
const XMLNode &prop_node) ->
bool {
1912 if (prop_node.
GetName() !=
"property")
1915 if (propname ==
"blocksize") {
1937 std::optional<uint32_t> num;
1943 llvm::StringRef name;
1944 llvm::StringRef value;
1946 if (name ==
"num") {
1962WatchpointHardwareFeature
1981 return std::nullopt;
1986 std::string path{file_spec.
GetPath(
false)};
2006 std::string path{file_spec.
GetPath(
false)};
2026 std::string path{file_spec.
GetPath(
false)};
2047 if ((cols == 0) != (rows == 0))
2050 packet.
Printf(
"QSetSTDIOWindowSize:cols=%u;rows=%u",
2051 static_cast<unsigned>(cols),
static_cast<unsigned>(rows));
2075 return !cwd.empty();
2082 std::string path{working_dir.
GetPath(
false)};
2102 const int packet_len =
2103 ::snprintf(packet,
sizeof(packet),
"QSetDisableASLR:%i", enable ? 1 : 0);
2104 assert(packet_len < (
int)
sizeof(packet));
2119 const int packet_len = ::snprintf(packet,
sizeof(packet),
2120 "QSetDetachOnError:%i", enable ? 1 : 0);
2121 assert(packet_len < (
int)
sizeof(packet));
2137 llvm::StringRef name;
2138 llvm::StringRef value;
2144 std::string os_type;
2147 if (name ==
"pid") {
2149 value.getAsInteger(
BASE_10, pid);
2151 }
else if (name ==
"ppid") {
2153 value.getAsInteger(
BASE_10, pid);
2155 }
else if (name ==
"uid") {
2157 value.getAsInteger(
BASE_10, uid);
2159 }
else if (name ==
"euid") {
2161 value.getAsInteger(
BASE_10, uid);
2163 }
else if (name ==
"gid") {
2165 value.getAsInteger(
BASE_10, gid);
2167 }
else if (name ==
"egid") {
2169 value.getAsInteger(
BASE_10, gid);
2171 }
else if (name ==
"triple") {
2176 }
else if (name ==
"name") {
2183 }
else if (name ==
"args") {
2184 llvm::StringRef encoded_args(value), hex_arg;
2186 bool is_arg0 =
true;
2187 while (!encoded_args.empty()) {
2188 std::tie(hex_arg, encoded_args) = encoded_args.split(
'-');
2203 }
else if (name ==
"cputype") {
2204 value.getAsInteger(
BASE_10, cpu);
2205 }
else if (name ==
"cpusubtype") {
2206 value.getAsInteger(
BASE_10, sub);
2207 }
else if (name ==
"vendor") {
2208 vendor = std::string(value);
2209 }
else if (name ==
"ostype") {
2210 os_type = std::string(value);
2215 if (vendor ==
"apple") {
2219 llvm::StringRef(vendor));
2221 llvm::StringRef(os_type));
2233 process_info.
Clear();
2237 const int packet_len =
2238 ::snprintf(packet,
sizeof(packet),
"qProcessInfoPID:%" PRIu64, pid);
2239 assert(packet_len < (
int)
sizeof(packet));
2269 llvm::StringRef name;
2270 llvm::StringRef value;
2273 std::string os_name;
2274 std::string environment;
2275 std::string vendor_name;
2277 std::string elf_abi;
2278 uint32_t pointer_byte_size = 0;
2281 uint32_t num_keys_decoded = 0;
2284 if (name ==
"cputype") {
2285 if (!value.getAsInteger(
BASE_16, cpu))
2287 }
else if (name ==
"cpusubtype") {
2288 if (!value.getAsInteger(
BASE_16, sub)) {
2294 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2295 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2302 }
else if (name ==
"triple") {
2306 }
else if (name ==
"ostype") {
2309 }
else if (name ==
"vendor") {
2310 vendor_name = std::string(value);
2312 }
else if (name ==
"endian") {
2313 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2320 }
else if (name ==
"ptrsize") {
2321 if (!value.getAsInteger(
BASE_16, pointer_byte_size))
2323 }
else if (name ==
"pid") {
2324 if (!value.getAsInteger(
BASE_16, pid))
2326 }
else if (name ==
"elf_abi") {
2327 elf_abi = std::string(value);
2329 }
else if (name ==
"main-binary-uuid") {
2332 }
else if (name ==
"main-binary-slide") {
2340 }
else if (name ==
"main-binary-address") {
2348 }
else if (name ==
"binary-addresses") {
2351 for (llvm::StringRef x : llvm::split(value,
',')) {
2353 x.consume_front(
"0x");
2354 if (llvm::to_integer(x, vmaddr, 16))
2359 if (num_keys_decoded > 0)
2367 if (!triple.empty()) {
2370 if (pointer_byte_size) {
2371 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2374 !vendor_name.empty()) {
2375 llvm::Triple triple(llvm::Twine(
"-") + vendor_name +
"-" + os_name);
2376 if (!environment.empty())
2377 triple.setEnvironmentName(environment);
2379 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2380 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2381 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2382 switch (triple.getObjectFormat()) {
2383 case llvm::Triple::MachO:
2386 case llvm::Triple::ELF:
2389 case llvm::Triple::COFF:
2392 case llvm::Triple::GOFF:
2393 case llvm::Triple::SPIRV:
2394 case llvm::Triple::Wasm:
2395 case llvm::Triple::XCOFF:
2396 case llvm::Triple::DXContainer:
2397 LLDB_LOGF(log,
"error: not supported target architecture");
2399 case llvm::Triple::UnknownObjectFormat:
2400 LLDB_LOGF(log,
"error: failed to determine target architecture");
2404 if (pointer_byte_size) {
2405 assert(pointer_byte_size ==
m_process_arch.GetAddressByteSize());
2410 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2412 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2426 process_infos.clear();
2434 bool has_name_match =
false;
2435 if (!name.empty()) {
2436 has_name_match =
true;
2438 switch (name_match_type) {
2440 has_name_match =
false;
2452 packet.
PutCString(
"name_match:starts_with;");
2463 if (has_name_match) {
2471 packet.
Printf(
"pid:%" PRIu64
";",
2474 packet.
Printf(
"parent_pid:%" PRIu64
";",
2481 packet.
Printf(
"euid:%u;",
2484 packet.
Printf(
"egid:%u;",
2490 const llvm::Triple &triple = match_arch.
GetTriple();
2506 process_infos.push_back(process_info);
2515 return process_infos.size();
2519 std::string &name) {
2522 const int packet_len =
2523 ::snprintf(packet,
sizeof(packet),
"qUserName:%i", uid);
2524 assert(packet_len < (
int)
sizeof(packet));
2546 std::string &name) {
2549 const int packet_len =
2550 ::snprintf(packet,
sizeof(packet),
"qGroupName:%i", gid);
2551 assert(packet_len < (
int)
sizeof(packet));
2573 uint32_t recv_size) {
2575 packet.
Printf(
"qSpeedTest:response_size:%x;data:", recv_size);
2576 uint32_t bytes_left = send_size;
2577 while (bytes_left > 0) {
2578 if (bytes_left >= 26) {
2579 packet.
PutCString(
"abcdefghijklmnopqrstuvwxyz");
2582 packet.
Printf(
"%*.*s;", bytes_left, bytes_left,
2583 "abcdefghijklmnopqrstuvwxyz");
2592 return duration<float>::zero();
2593 using Dur = duration<float>;
2594 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2595 Dur mean = sum / v.size();
2598 float delta = (d - mean).count();
2599 accum += delta * delta;
2602 return Dur(sqrtf(accum / (v.size() - 1)));
2608 uint64_t recv_amount,
2609 bool json,
Stream &strm) {
2614 strm.
Printf(
"{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2618 strm.
Printf(
"Testing sending %u packets of various sizes:\n",
2622 uint32_t result_idx = 0;
2624 std::vector<duration<float>> packet_times;
2626 for (send_size = 0; send_size <= max_send;
2627 send_size ? send_size *= 2 : send_size = 4) {
2628 for (uint32_t recv_size = 0; recv_size <= max_recv;
2629 recv_size ? recv_size *= 2 : recv_size = 4) {
2632 packet_times.clear();
2634 const auto start_time = steady_clock::now();
2635 for (uint32_t i = 0; i < num_packets; ++i) {
2636 const auto packet_start_time = steady_clock::now();
2639 const auto packet_end_time = steady_clock::now();
2640 packet_times.push_back(packet_end_time - packet_start_time);
2642 const auto end_time = steady_clock::now();
2643 const auto total_time = end_time - start_time;
2645 float packets_per_second =
2646 ((float)num_packets) / duration<float>(total_time).count();
2647 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2648 : duration<float>::zero();
2649 const duration<float> standard_deviation =
2652 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2653 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2654 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2655 result_idx > 0 ?
"," :
"", send_size, recv_size,
2656 total_time, standard_deviation);
2659 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2660 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2661 "standard deviation of {5,10:ms+f6}\n",
2662 send_size, recv_size, duration<float>(total_time),
2663 packets_per_second, duration<float>(average_per_packet),
2664 standard_deviation);
2670 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2672 strm.
Printf(
"\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2673 ": %" PRIu64
",\n \"results\" : [",
2676 strm.
Printf(
"Testing receiving %2.1fMB of data using varying receive "
2682 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2687 if (recv_size > 0) {
2688 const auto start_time = steady_clock::now();
2689 uint32_t bytes_read = 0;
2690 uint32_t packet_count = 0;
2691 while (bytes_read < recv_amount) {
2694 bytes_read += recv_size;
2697 const auto end_time = steady_clock::now();
2698 const auto total_time = end_time - start_time;
2699 float mb_second = ((float)recv_amount) /
2700 duration<float>(total_time).count() /
2702 float packets_per_second =
2703 ((float)packet_count) / duration<float>(total_time).count();
2704 const auto average_per_packet = packet_count > 0
2705 ? total_time / packet_count
2706 : duration<float>::zero();
2709 strm.
Format(
"{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2710 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2711 result_idx > 0 ?
"," :
"", send_size, recv_size,
2715 strm.
Format(
"qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2716 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2717 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2718 send_size, recv_size, packet_count, k_recv_amount_mb,
2719 duration<float>(total_time), mb_second,
2720 packets_per_second, duration<float>(average_per_packet));
2726 strm.
Printf(
"\n ]\n }\n}\n");
2733 uint32_t recv_size) {
2743 const char *remote_accept_hostname,
lldb::pid_t &pid, uint16_t &port,
2744 std::string &socket_name) {
2747 socket_name.clear();
2752 std::string hostname;
2753 if (remote_accept_hostname && remote_accept_hostname[0])
2754 hostname = remote_accept_hostname;
2756 if (HostInfo::GetHostname(hostname)) {
2758 stream.
Printf(
"host:%s;", hostname.c_str());
2762 stream.
Printf(
"host:*;");
2773 llvm::StringRef name;
2774 llvm::StringRef value;
2777 value.getAsInteger(
BASE_10, port);
2778 else if (name ==
"pid")
2779 value.getAsInteger(
BASE_10, pid);
2780 else if (name.compare(
"socket_name") == 0) {
2791 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2792 connection_urls.clear();
2808 for (
size_t i = 0, count = array->
GetSize(); i < count; ++i) {
2809 std::optional<StructuredData::Dictionary *> maybe_element =
2818 port = port_osp->GetUnsignedIntegerValue(0);
2820 std::string socket_name;
2823 socket_name = std::string(socket_name_osp->GetStringValue());
2825 if (port != 0 || !socket_name.empty())
2826 connection_urls.emplace_back(port, socket_name);
2828 return connection_urls.size();
2833 stream.
Printf(
"qKillSpawnedProcess:%" PRId64, pid);
2845 uint64_t tid, uint64_t pid,
char op) {
2851 packet.
Printf(
"p%" PRIx64
".", pid);
2856 packet.
Printf(
"%" PRIx64, tid);
2862 return {{pid, tid}};
2874 return std::nullopt;
2889 return ret.has_value();
2904 return ret.has_value();
2919 ::snprintf(packet,
sizeof(packet),
"qThreadStopInfo%" PRIx64, tid);
2920 assert(packet_len < (
int)
sizeof(packet));
2939 std::chrono::seconds timeout) {
2941 LLDB_LOGF(log,
"GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2942 __FUNCTION__, insert ?
"add" :
"remove", addr);
2949 const int packet_len =
2950 ::snprintf(packet,
sizeof(packet),
"%c%i,%" PRIx64
",%x",
2951 insert ?
'Z' :
'z', type, addr, length);
2953 assert(packet_len + 1 < (
int)
sizeof(packet));
2998std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
3000 bool &sequence_mutex_unavailable) {
3001 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
3005 sequence_mutex_unavailable =
false;
3009 for (packet_result =
3027 ids.push_back(*pid_tid);
3029 }
while (ch ==
',');
3043 ids.emplace_back(1, 1);
3047 LLDB_LOG(log,
"error: failed to get packet sequence mutex, not sending "
3048 "packet 'qfThreadInfo'");
3049 sequence_mutex_unavailable =
true;
3056 std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable) {
3061 if (ids.empty() || sequence_mutex_unavailable)
3064 for (
auto id : ids) {
3070 thread_ids.push_back(
id.second);
3073 return thread_ids.size();
3086 llvm::StringRef command,
3094 std::string *separated_error_output,
3104 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3108 std::string path{working_dir.
GetPath(
false)};
3115 if (response.
GetChar() !=
'F')
3117 if (response.
GetChar() !=
',')
3122 else if (status_ptr)
3123 *status_ptr = exitcode;
3124 if (response.
GetChar() !=
',')
3129 if (response.
GetChar() !=
',')
3134 command_output->assign(output);
3141 uint32_t file_permissions) {
3142 std::string path{file_spec.
GetPath(
false)};
3148 llvm::StringRef packet = stream.
GetString();
3153 packet.str().c_str());
3155 if (response.
GetChar() !=
'F')
3157 packet.str().c_str());
3164 uint32_t file_permissions) {
3165 std::string path{file_spec.
GetPath(
false)};
3171 llvm::StringRef packet = stream.
GetString();
3178 if (response.
GetChar() !=
'F')
3187#define HANDLE_ERRNO(name, value) \
3190#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3199 if (response.
GetChar() !=
'F')
3201 int32_t result = response.
GetS32(-2, 16);
3204 if (response.
GetChar() ==
',') {
3206 if (result_errno != -1)
3218 std::string path(file_spec.
GetPath(
false));
3239 stream.
Printf(
"vFile:close:%x", (
int)fd);
3248std::optional<GDBRemoteFStatData>
3251 stream.
Printf(
"vFile:fstat:%" PRIx64, fd);
3255 if (response.
GetChar() !=
'F')
3256 return std::nullopt;
3257 int64_t size = response.
GetS64(-1, 16);
3258 if (size > 0 && response.
GetChar() ==
';') {
3262 if (buffer.size() !=
sizeof(out))
3263 return std::nullopt;
3264 memcpy(&out, buffer.data(),
sizeof(out));
3269 return std::nullopt;
3272std::optional<GDBRemoteFStatData>
3277 return std::nullopt;
3278 std::optional<GDBRemoteFStatData> st =
FStat(fd);
3287 std::string path(file_spec.
GetPath(
false));
3297 if (response.
GetChar() !=
'F')
3306 std::optional<GDBRemoteFStatData> st =
Stat(file_spec);
3324 while (response.
Peek()) {
3326 while ((ch = response.
GetHexU8(0,
false)) !=
'\0')
3329 if (response.
GetChar() !=
',')
3337 uint32_t &file_permissions) {
3339 std::string path{file_spec.
GetPath(
false)};
3352 if (response.
GetChar() !=
'F') {
3354 "invalid response to '%s' packet", stream.
GetData());
3356 const uint32_t mode = response.
GetS32(-1, 16);
3357 if (
static_cast<int32_t
>(mode) == -1) {
3358 if (response.
GetChar() ==
',') {
3360 if (response_errno > 0)
3377 if (std::optional<GDBRemoteFStatData> st =
Stat(file_spec)) {
3385 uint64_t offset,
void *dst,
3389 stream.
Printf(
"vFile:pread:%x,%" PRIx64
",%" PRIx64, (
int)fd, dst_len,
3394 if (response.
GetChar() !=
'F')
3396 int64_t retcode = response.
GetS64(-1, 16);
3397 if (retcode == -1) {
3399 if (response.
GetChar() ==
',') {
3401 if (response_errno > 0)
3406 const char next = (response.
Peek() ? *response.
Peek() : 0);
3413 const uint64_t data_to_write =
3414 std::min<uint64_t>(dst_len, buffer.size());
3415 if (data_to_write > 0)
3416 memcpy(dst, &buffer[0], data_to_write);
3417 return data_to_write;
3430 stream.
Printf(
"vFile:pwrite:%x,%" PRIx64
",", (
int)fd, offset);
3435 if (response.
GetChar() !=
'F') {
3439 int64_t bytes_written = response.
GetS64(-1, 16);
3440 if (bytes_written == -1) {
3442 if (response.
GetChar() ==
',') {
3444 if (response_errno > 0)
3449 return bytes_written;
3458 std::string src_path{src.
GetPath(
false)}, dst_path{dst.
GetPath(
false)};
3470 if (response.
GetChar() ==
'F') {
3474 if (response.
GetChar() ==
',') {
3476 if (response_errno > 0)
3491 std::string path{file_spec.
GetPath(
false)};
3501 if (response.
GetChar() ==
'F') {
3505 if (response.
GetChar() ==
',') {
3507 if (response_errno > 0)
3525 std::string path(file_spec.
GetPath(
false));
3534 if (response.
GetChar() !=
'F')
3536 if (response.
GetChar() !=
',')
3538 bool retcode = (response.
GetChar() !=
'0');
3555 std::string path(file_spec.
GetPath(
false));
3562 if (response.
GetChar() !=
'F')
3563 return std::make_error_code(std::errc::illegal_byte_sequence);
3564 if (response.
GetChar() !=
',')
3565 return std::make_error_code(std::errc::illegal_byte_sequence);
3566 if (response.
Peek() && *response.
Peek() ==
'x')
3567 return std::make_error_code(std::errc::no_such_file_or_directory);
3584 const size_t MD5_HALF_LENGTH =
sizeof(uint64_t) * 2;
3589 if (part.size() != MD5_HALF_LENGTH)
3590 return std::make_error_code(std::errc::illegal_byte_sequence);
3594 if (part.getAsInteger(
BASE_16, low))
3595 return std::make_error_code(std::errc::illegal_byte_sequence);
3600 if (part.size() != MD5_HALF_LENGTH)
3601 return std::make_error_code(std::errc::illegal_byte_sequence);
3605 if (part.getAsInteger(
BASE_16, high))
3606 return std::make_error_code(std::errc::illegal_byte_sequence);
3608 llvm::MD5::MD5Result result;
3609 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3610 result.data(), low);
3611 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3612 result.data() + 8, high);
3616 return std::make_error_code(std::errc::operation_canceled);
3626 arch.
GetTriple().getVendor() == llvm::Triple::Apple &&
3627 arch.
GetTriple().getOS() == llvm::Triple::IOS &&
3628 (arch.
GetTriple().getArch() == llvm::Triple::aarch64 ||
3629 arch.
GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3632 if (gdb_server_version != 0) {
3634 if (gdb_server_name && strcmp(gdb_server_name,
"debugserver") == 0) {
3635 if (gdb_server_version >= 310)
3648 payload.
Printf(
"p%x", reg);
3657 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3672 response.
GetHexBytes(buffer_sp->GetData(),
'\xcc');
3678 llvm::ArrayRef<uint8_t> data) {
3680 payload.
Printf(
"P%x=", reg_num);
3704 uint32_t &save_id) {
3720 const uint32_t response_save_id = response.
GetU32(0);
3721 if (response_save_id == 0)
3724 save_id = response_save_id;
3737 payload.
Printf(
"QRestoreRegisterState:%u", save_id);
3757 packet.
Printf(
"QSyncThreadState:%4.4" PRIx64
";", tid);
3763llvm::Expected<TraceSupportedResponse>
3768 escaped_packet.
PutCString(
"jLLDBTraceSupported");
3777 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3778 "jLLDBTraceSupported is unsupported");
3780 return llvm::json::parse<TraceSupportedResponse>(response.
Peek(),
3781 "TraceSupportedResponse");
3783 LLDB_LOG(log,
"failed to send packet: jLLDBTraceSupported");
3784 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3785 "failed to send packet: jLLDBTraceSupported");
3790 std::chrono::seconds timeout) {
3794 escaped_packet.
PutCString(
"jLLDBTraceStop:");
3796 std::string json_string;
3797 llvm::raw_string_ostream os(json_string);
3800 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3809 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3810 "jLLDBTraceStop is unsupported");
3812 return llvm::Error::success();
3813 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3814 "Invalid jLLDBTraceStart response");
3816 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStop");
3817 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3818 "failed to send packet: jLLDBTraceStop '%s'",
3824 std::chrono::seconds timeout) {
3828 escaped_packet.
PutCString(
"jLLDBTraceStart:");
3830 std::string json_string;
3831 llvm::raw_string_ostream os(json_string);
3834 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3843 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3844 "jLLDBTraceStart is unsupported");
3846 return llvm::Error::success();
3847 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3848 "Invalid jLLDBTraceStart response");
3850 LLDB_LOG(log,
"failed to send packet: jLLDBTraceStart");
3851 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3852 "failed to send packet: jLLDBTraceStart '%s'",
3856llvm::Expected<std::string>
3858 std::chrono::seconds timeout) {
3862 escaped_packet.
PutCString(
"jLLDBTraceGetState:");
3864 std::string json_string;
3865 llvm::raw_string_ostream os(json_string);
3868 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3877 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3878 "jLLDBTraceGetState is unsupported");
3879 return std::string(response.
Peek());
3882 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetState");
3883 return llvm::createStringError(
3884 llvm::inconvertibleErrorCode(),
3885 "failed to send packet: jLLDBTraceGetState '%s'",
3889llvm::Expected<std::vector<uint8_t>>
3895 escaped_packet.
PutCString(
"jLLDBTraceGetBinaryData:");
3897 std::string json_string;
3898 llvm::raw_string_ostream os(json_string);
3901 escaped_packet.
PutEscapedBytes(json_string.c_str(), json_string.size());
3911 return std::vector<uint8_t>(data.begin(), data.end());
3913 LLDB_LOG(log,
"failed to send packet: jLLDBTraceGetBinaryData");
3914 return llvm::createStringError(
3915 llvm::inconvertibleErrorCode(),
3916 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3924 return std::nullopt;
3926 return std::nullopt;
3930 const auto &GetOffset = [&] {
3932 if (ref.consumeInteger(16, offset))
3934 result.
offsets.push_back(offset);
3938 if (ref.consume_front(
"Text=")) {
3941 return std::nullopt;
3942 if (!ref.consume_front(
";Data=") || !GetOffset())
3943 return std::nullopt;
3946 if (ref.consume_front(
";Bss=") && GetOffset() && ref.empty())
3948 }
else if (ref.consume_front(
"TextSeg=")) {
3951 return std::nullopt;
3954 if (ref.consume_front(
";DataSeg=") && GetOffset() && ref.empty())
3957 return std::nullopt;
3966 std::string module_path = module_file_spec.
GetPath(
false);
3967 if (module_path.empty())
3974 const auto &triple = arch_spec.
GetTriple().getTriple();
3990 llvm::StringRef name;
3991 llvm::StringRef value;
3993 module_spec.
Clear();
3997 if (name ==
"uuid" || name ==
"md5") {
4002 }
else if (name ==
"triple") {
4007 }
else if (name ==
"file_offset") {
4009 if (!value.getAsInteger(
BASE_16, ival))
4011 }
else if (name ==
"file_size") {
4013 if (!value.getAsInteger(
BASE_16, ival))
4015 }
else if (name ==
"file_path") {
4026static std::optional<ModuleSpec>
4030 return std::nullopt;
4032 llvm::StringRef string;
4036 return std::nullopt;
4038 return std::nullopt;
4041 return std::nullopt;
4045 return std::nullopt;
4049 return std::nullopt;
4053 return std::nullopt;
4059std::optional<std::vector<ModuleSpec>>
4061 llvm::ArrayRef<FileSpec> module_file_specs,
const llvm::Triple &triple) {
4065 return std::nullopt;
4067 json::Array module_array;
4068 for (
const FileSpec &module_file_spec : module_file_specs) {
4069 module_array.push_back(
4070 json::Object{{
"file", module_file_spec.GetPath(
false)},
4071 {
"triple", triple.getTriple()}});
4074 unescaped_payload.
PutCString(
"jModulesInfo:");
4075 unescaped_payload.
AsRawOstream() << std::move(module_array);
4088 return std::nullopt;
4092 return std::nullopt;
4097 if (!response_object_sp)
4098 return std::nullopt;
4101 if (!response_array)
4102 return std::nullopt;
4104 std::vector<ModuleSpec> result;
4105 for (
size_t i = 0; i < response_array->
GetSize(); ++i) {
4108 result.push_back(*module_spec);
4118llvm::Expected<std::string>
4120 llvm::StringRef annex) {
4123 llvm::raw_string_ostream output_stream(output);
4137 std::string packet =
4138 (
"qXfer:" +
object +
":read:" + annex +
":" +
4139 llvm::Twine::utohexstr(offset) +
"," + llvm::Twine::utohexstr(size))
4147 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4148 "Error sending $qXfer packet");
4166 return llvm::createStringError(
4167 llvm::inconvertibleErrorCode(),
4168 "Invalid continuation code from $qXfer packet");
4218 bool symbol_response_provided =
false;
4221 bool first_qsymbol_query =
true;
4232 if (symbol_response_provided || first_qsymbol_query) {
4239 first_qsymbol_query =
false;
4248 if (response_str.starts_with(
"qSymbol:")) {
4250 std::string symbol_name;
4252 if (symbol_name.empty())
4263 switch (sc.symbol->GetType()) {
4284 if (sc.module_sp->GetArchitecture()
4286 .getObjectFormat() !=
4287 llvm::Triple::ObjectFormatType::MachO) {
4292 sc.symbol->GetLoadAddress(&process->
GetTarget());
4294 symbol_load_addr = sc.symbol->GetRawValue();
4309 sc.symbol->GetLoadAddress(&process->
GetTarget());
4322 packet.
Printf(
"%" PRIx64, symbol_load_addr);
4323 symbol_response_provided =
true;
4325 symbol_response_provided =
false;
4341 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4366 "GDBRemoteCommunicationClient::%s(): "
4367 "QSupportedAsyncJSONPackets returned invalid "
4374 "GDBRemoteCommunicationClient::%s(): "
4375 "QSupportedAsyncJSONPackets unsupported",
4383 "GDBRemoteCommunicationClient::%s(): supported async "
4385 __FUNCTION__, stream.
GetData());
4395 llvm::ArrayRef<int32_t> signals) {
4398 auto range = llvm::make_range(signals.begin(), signals.end());
4399 std::string packet = formatv(
"QPassSignals:{0:$[;]@(x-2)}", range).str();
4411 "Unknown error happened during sending QPassSignals packet.");
4419 if (type_name.empty()) {
4432 config_sp->Dump(unescaped_stream);
4433 unescaped_stream.
Flush();
4451 "configuring StructuredData feature {0} failed with error {1}",
4457 "configuring StructuredData feature {0} failed when sending packet: "
4459 type_name, (
int)result);
4488 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4489 "failed to send k packet");
4491 char packet_cmd = response.
GetChar(0);
4492 if (packet_cmd ==
'W' || packet_cmd ==
'X')
4495 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4496 "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.