LLDB mainline
GDBRemoteCommunicationClient.cpp
Go to the documentation of this file.
1//===-- GDBRemoteCommunicationClient.cpp ----------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include <cmath>
12#include <sys/stat.h>
13
14#include <numeric>
15#include <optional>
16#include <sstream>
17
19#include "lldb/Host/HostInfo.h"
20#include "lldb/Host/SafeMachO.h"
21#include "lldb/Host/XML.h"
22#include "lldb/Symbol/Symbol.h"
24#include "lldb/Target/Target.h"
26#include "lldb/Utility/Args.h"
30#include "lldb/Utility/Log.h"
31#include "lldb/Utility/State.h"
33
34#include "ProcessGDBRemote.h"
35#include "ProcessGDBRemoteLog.h"
36#include "lldb/Host/Config.h"
38
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/StringSwitch.h"
41#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_ZLIB
42#include "llvm/Support/JSON.h"
43
44#if HAVE_LIBCOMPRESSION
45#include <compression.h>
46#endif
47
48using namespace lldb;
50using namespace lldb_private;
51using namespace std::chrono;
52
53llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os,
54 const QOffsets &offsets) {
55 return os << llvm::formatv(
56 "QOffsets({0}, [{1:@[x]}])", offsets.segments,
57 llvm::make_range(offsets.offsets.begin(), offsets.offsets.end()));
58}
59
60// GDBRemoteCommunicationClient constructor
79
80// Destructor
85
88
89 // Start the read thread after we send the handshake ack since if we fail to
90 // send the handshake ack, there is no reason to continue...
91 std::chrono::steady_clock::time_point start_of_handshake =
92 std::chrono::steady_clock::now();
93 if (SendAck()) {
94 // The return value from QueryNoAckModeSupported() is true if the packet
95 // was sent and _any_ response (including UNIMPLEMENTED) was received), or
96 // false if no response was received. This quickly tells us if we have a
97 // live connection to a remote GDB server...
99 return true;
100 } else {
101 std::chrono::steady_clock::time_point end_of_handshake =
102 std::chrono::steady_clock::now();
103 auto handshake_timeout =
104 std::chrono::duration<double>(end_of_handshake - start_of_handshake)
105 .count();
106 if (error_ptr) {
107 if (!IsConnected())
108 *error_ptr =
109 Status::FromErrorString("Connection shut down by remote side "
110 "while waiting for reply to initial "
111 "handshake packet");
112 else
114 "failed to get reply to handshake packet within timeout of "
115 "%.1f seconds",
116 handshake_timeout);
117 }
118 }
119 } else {
120 if (error_ptr)
121 *error_ptr = Status::FromErrorString("failed to send the handshake ack");
122 }
123 return false;
124}
125
132
139
146
153
160
167
174
181
188
194
201
207
213
219
225
228 m_send_acks = true;
230
231 // This is the first real packet that we'll send in a debug session and it
232 // may take a little longer than normal to receive a reply. Wait at least
233 // 6 seconds for a reply to this packet.
234
235 ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
236
238 if (SendPacketAndWaitForResponse("QStartNoAckMode", response) ==
240 if (response.IsOKResponse()) {
241 m_send_acks = false;
243 }
244 return true;
245 }
246 }
247 return false;
248}
249
262
276
290
292 if (!did_exec) {
293 // Hard reset everything, this is when we first connect to a GDB server
321 m_x_packet_state.reset();
329 m_supports_z0 = true;
330 m_supports_z1 = true;
331 m_supports_z2 = true;
332 m_supports_z3 = true;
333 m_supports_z4 = true;
336 m_supports_qSymbol = true;
339 m_host_arch.Clear();
341 m_os_version = llvm::VersionTuple();
342 m_os_build.clear();
343 m_os_kernel.clear();
344 m_hostname.clear();
345 m_gdb_server_name.clear();
347 m_default_packet_timeout = seconds(0);
350 m_qSupported_response.clear();
356 }
357
358 // These flags should be reset when we first connect to a GDB server and when
359 // our inferior process execs
361 m_process_arch.Clear();
362}
363
365 // Clear out any capabilities we expect to see in the qSupported response
379 m_x_packet_state.reset();
384
385 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
386 // not, we assume no limit
387
388 // build the qSupported packet
389 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc",
390 "multiprocess+",
391 "fork-events+",
392 "vfork-events+",
393 "swbreak+",
394 "hwbreak+"};
395 StreamString packet;
396 packet.PutCString("qSupported");
397 for (uint32_t i = 0; i < features.size(); ++i) {
398 packet.PutCString(i == 0 ? ":" : ";");
399 packet.PutCString(features[i]);
400 }
401
403 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
405 // Hang on to the qSupported packet, so that platforms can do custom
406 // configuration of the transport before attaching/launching the process.
407 m_qSupported_response = response.GetStringRef().str();
408
409 for (llvm::StringRef x : llvm::split(response.GetStringRef(), ';')) {
410 if (x == "qXfer:auxv:read+")
412 else if (x == "qXfer:libraries-svr4:read+")
414 else if (x == "augmented-libraries-svr4-read") {
417 } else if (x == "qXfer:libraries:read+")
419 else if (x == "qXfer:features:read+")
421 else if (x == "qXfer:memory-map:read+")
423 else if (x == "qXfer:siginfo:read+")
425 else if (x == "qEcho+")
427 else if (x == "QPassSignals+")
429 else if (x == "multiprocess+")
431 else if (x == "memory-tagging+")
433 else if (x == "qSaveCore+")
435 else if (x == "native-signals+")
437 else if (x == "binary-upload+")
439 else if (x == "ReverseContinue+")
441 else if (x == "ReverseStep+")
443 else if (x == "MultiMemRead+")
445 else if (x == "jMultiBreakpoint+")
447 // Look for a list of compressions in the features list e.g.
448 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
449 // deflate,lzma
450 else if (x.consume_front("SupportedCompressions=")) {
451 llvm::SmallVector<llvm::StringRef, 4> compressions;
452 x.split(compressions, ',');
453 if (!compressions.empty())
454 MaybeEnableCompression(compressions);
455 } else if (x.consume_front("SupportedWatchpointTypes=")) {
456 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;
457 x.split(watchpoint_types, ',');
458 m_watchpoint_types = eWatchpointHardwareFeatureUnknown;
459 for (auto wp_type : watchpoint_types) {
460 if (wp_type == "x86_64")
461 m_watchpoint_types |= eWatchpointHardwareX86;
462 if (wp_type == "aarch64-mask")
463 m_watchpoint_types |= eWatchpointHardwareArmMASK;
464 if (wp_type == "aarch64-bas")
465 m_watchpoint_types |= eWatchpointHardwareArmBAS;
466 }
467 } else if (x.consume_front("PacketSize=")) {
468 StringExtractorGDBRemote packet_response(x);
470 packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
471 if (m_max_packet_size == 0) {
472 m_max_packet_size = UINT64_MAX; // Must have been a garbled response
474 LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
475 }
476 }
477 }
478 }
479}
480
493
495 assert(!flavor.empty());
504 if (SendPacketAndWaitForResponse("vCont?", response) ==
506 for (llvm::StringRef token : llvm::split(response.GetStringRef(), ';')) {
507 if (token == "c")
509 if (token == "C")
511 if (token == "s")
513 if (token == "S")
515 }
516
522 }
523
529 }
530 }
531 }
532
533 return llvm::StringSwitch<bool>(flavor)
534 .Case("a", m_supports_vCont_any)
535 .Case("A", m_supports_vCont_all)
536 .Case("c", m_supports_vCont_c)
537 .Case("C", m_supports_vCont_C)
538 .Case("s", m_supports_vCont_s)
539 .Case("S", m_supports_vCont_S)
540 .Default(false);
541}
542
545 lldb::tid_t tid, StreamString &&payload,
546 StringExtractorGDBRemote &response) {
547 Lock lock(*this);
548 if (!lock) {
550 LLDB_LOGF(log,
551 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
552 "for %s packet.",
553 __FUNCTION__, payload.GetData());
555 }
556
558 payload.Printf(";thread:%4.4" PRIx64 ";", tid);
559 else {
560 if (!SetCurrentThread(tid))
562 }
563
564 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
565}
566
567// Check if the target supports 'p' packet. It sends out a 'p' packet and
568// checks the response. A normal packet will tell us that support is available.
569//
570// Takes a valid thread ID because p needs to apply to a thread.
576
578 lldb::tid_t tid, llvm::StringRef packetStr) {
579 StreamString payload;
580 payload.PutCString(packetStr);
583 tid, std::move(payload), response) == PacketResult::Success &&
584 response.IsNormalResponse()) {
585 return eLazyBoolYes;
586 }
587 return eLazyBoolNo;
588}
589
593
595 // Get information on all threads at one using the "jThreadsInfo" packet
596 StructuredData::ObjectSP object_sp;
597
601 if (SendPacketAndWaitForResponse("jThreadsInfo", response) ==
603 if (response.IsUnsupportedResponse()) {
605 } else if (!response.Empty()) {
606 object_sp = StructuredData::ParseJSON(response.GetStringRef());
607 }
608 }
609 }
610 return object_sp;
611}
612
626
630 // We try to enable error strings in remote packets but if we fail, we just
631 // work in the older way.
633 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) ==
635 if (response.IsOKResponse()) {
637 }
638 }
639 }
640}
641
655
669
682
689
691 size_t len,
692 int32_t type) {
693 StreamString packet;
694 packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type);
696
697 Log *log = GetLog(GDBRLog::Memory);
698
699 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
701 !response.IsNormalResponse()) {
702 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",
703 __FUNCTION__);
704 return nullptr;
705 }
706
707 // We are expecting
708 // m<hex encoded bytes>
709
710 if (response.GetChar() != 'm') {
711 LLDB_LOGF(log,
712 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
713 "begin with \"m\"",
714 __FUNCTION__);
715 return nullptr;
716 }
717
718 size_t expected_bytes = response.GetBytesLeft() / 2;
719 WritableDataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));
720 size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());
721 // Check both because in some situations chars are consumed even
722 // if the decoding fails.
723 if (response.GetBytesLeft() || (expected_bytes != got_bytes)) {
724 LLDB_LOGF(
725 log,
726 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
727 __FUNCTION__);
728 return nullptr;
729 }
730
731 return buffer_sp;
732}
733
735 lldb::addr_t addr, size_t len, int32_t type,
736 const std::vector<uint8_t> &tags) {
737 // Format QMemTags:address,length:type:tags
738 StreamString packet;
739 packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type);
740 packet.PutBytesAsRawHex8(tags.data(), tags.size());
741
742 Status status;
744 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
746 !response.IsOKResponse()) {
747 status = Status::FromErrorString("QMemTags packet failed");
748 }
749 return status;
750}
751
767
769 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
770 return m_curr_pid;
771
772 // First try to retrieve the pid via the qProcessInfo request.
773 GetCurrentProcessInfo(allow_lazy);
775 // We really got it.
776 return m_curr_pid;
777 } else {
778 // If we don't get a response for qProcessInfo, check if $qC gives us a
779 // result. $qC only returns a real process id on older debugserver and
780 // lldb-platform stubs. The gdb remote protocol documents $qC as returning
781 // the thread id, which newer debugserver and lldb-gdbserver stubs return
782 // correctly.
785 if (response.GetChar() == 'Q') {
786 if (response.GetChar() == 'C') {
788 response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);
791 return m_curr_pid;
792 }
793 }
794 }
795 }
796
797 // If we don't get a response for $qC, check if $qfThreadID gives us a
798 // result.
800 bool sequence_mutex_unavailable;
801 auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
802 if (!ids.empty() && !sequence_mutex_unavailable) {
803 // If server returned an explicit PID, use that.
804 m_curr_pid_run = m_curr_pid = ids.front().first;
805 // Otherwise, use the TID of the first thread (Linux hack).
807 m_curr_pid_run = m_curr_pid = ids.front().second;
809 return m_curr_pid;
810 }
811 }
812 }
813
815}
816
818 if (!args.GetArgumentAtIndex(0))
819 return llvm::createStringError(llvm::inconvertibleErrorCode(),
820 "Nothing to launch");
821 // try vRun first
822 if (m_supports_vRun) {
823 StreamString packet;
824 packet.PutCString("vRun");
825 for (const Args::ArgEntry &arg : args) {
826 packet.PutChar(';');
827 packet.PutStringAsRawHex8(arg.ref());
828 }
829
831 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
833 return llvm::createStringError(llvm::inconvertibleErrorCode(),
834 "Sending vRun packet failed");
835
836 if (response.IsErrorResponse())
837 return response.GetStatus().ToError();
838
839 // vRun replies with a stop reason packet
840 // FIXME: right now we just discard the packet and LLDB queries
841 // for stop reason again
842 if (!response.IsUnsupportedResponse())
843 return llvm::Error::success();
844
845 m_supports_vRun = false;
846 }
847
848 // fallback to A
849 StreamString packet;
850 packet.PutChar('A');
851 llvm::ListSeparator LS(",");
852 for (const auto &arg : llvm::enumerate(args)) {
853 packet << LS;
854 packet.Format("{0},{1},", arg.value().ref().size() * 2, arg.index());
855 packet.PutStringAsRawHex8(arg.value().ref());
856 }
857
859 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
861 return llvm::createStringError(llvm::inconvertibleErrorCode(),
862 "Sending A packet failed");
863 }
864 if (!response.IsOKResponse())
865 return response.GetStatus().ToError();
866
867 if (SendPacketAndWaitForResponse("qLaunchSuccess", response) !=
869 return llvm::createStringError(llvm::inconvertibleErrorCode(),
870 "Sending qLaunchSuccess packet failed");
871 }
872 if (response.IsOKResponse())
873 return llvm::Error::success();
874 if (response.GetChar() == 'E') {
875 return llvm::createStringError(llvm::inconvertibleErrorCode(),
876 response.GetStringRef().substr(1));
877 }
878 return llvm::createStringError(llvm::inconvertibleErrorCode(),
879 "unknown error occurred launching process");
880}
881
883 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;
884 for (const auto &kv : env)
885 vec.emplace_back(kv.first(), kv.second);
886 llvm::sort(vec, llvm::less_first());
887 for (const auto &[k, v] : vec) {
888 int r = SendEnvironmentPacket((k + "=" + v).str().c_str());
889 if (r != 0)
890 return r;
891 }
892 return 0;
893}
894
896 char const *name_equal_value) {
897 if (name_equal_value && name_equal_value[0]) {
898 bool send_hex_encoding = false;
899 for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
900 ++p) {
901 if (llvm::isPrint(*p)) {
902 switch (*p) {
903 case '$':
904 case '#':
905 case '*':
906 case '}':
907 send_hex_encoding = true;
908 break;
909 default:
910 break;
911 }
912 } else {
913 // We have non printable characters, lets hex encode this...
914 send_hex_encoding = true;
915 }
916 }
917
919 // Prefer sending unencoded, if possible and the server supports it.
920 if (!send_hex_encoding && m_supports_QEnvironment) {
921 StreamString packet;
922 packet.Printf("QEnvironment:%s", name_equal_value);
923 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
925 return -1;
926
927 if (response.IsOKResponse())
928 return 0;
929 if (response.IsUnsupportedResponse())
931 else {
932 uint8_t error = response.GetError();
933 if (error)
934 return error;
935 return -1;
936 }
937 }
938
940 StreamString packet;
941 packet.PutCString("QEnvironmentHexEncoded:");
942 packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
943 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
945 return -1;
946
947 if (response.IsOKResponse())
948 return 0;
949 if (response.IsUnsupportedResponse())
951 else {
952 uint8_t error = response.GetError();
953 if (error)
954 return error;
955 return -1;
956 }
957 }
958 }
959 return -1;
960}
961
963 if (arch && arch[0]) {
964 StreamString packet;
965 packet.Printf("QLaunchArch:%s", arch);
967 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
969 if (response.IsOKResponse())
970 return 0;
971 uint8_t error = response.GetError();
972 if (error)
973 return error;
974 }
975 }
976 return -1;
977}
978
980 char const *data, bool *was_supported) {
981 if (data && *data != '\0') {
982 StreamString packet;
983 packet.Printf("QSetProcessEvent:%s", data);
985 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
987 if (response.IsOKResponse()) {
988 if (was_supported)
989 *was_supported = true;
990 return 0;
991 } else if (response.IsUnsupportedResponse()) {
992 if (was_supported)
993 *was_supported = false;
994 return -1;
995 } else {
996 uint8_t error = response.GetError();
997 if (was_supported)
998 *was_supported = true;
999 if (error)
1000 return error;
1001 }
1002 }
1003 }
1004 return -1;
1005}
1006
1008 GetHostInfo();
1009 return m_os_version;
1010}
1011
1016
1018 if (GetHostInfo()) {
1019 if (!m_os_build.empty())
1020 return m_os_build;
1021 }
1022 return std::nullopt;
1023}
1024
1025std::optional<std::string>
1027 if (GetHostInfo()) {
1028 if (!m_os_kernel.empty())
1029 return m_os_kernel;
1030 }
1031 return std::nullopt;
1032}
1033
1035 if (GetHostInfo()) {
1036 if (!m_hostname.empty()) {
1037 s = m_hostname;
1038 return true;
1039 }
1040 }
1041 s.clear();
1042 return false;
1043}
1044
1050
1057
1059 UUID &uuid, addr_t &value, bool &value_is_offset) {
1062
1063 // Return true if we have a UUID or an address/offset of the
1064 // main standalone / firmware binary being used.
1065 if (!m_process_standalone_uuid.IsValid() &&
1067 return false;
1068
1071 value_is_offset = m_process_standalone_value_is_offset;
1072 return true;
1073}
1074
1075std::vector<addr_t>
1081
1084 m_gdb_server_name.clear();
1087
1088 StringExtractorGDBRemote response;
1089 if (SendPacketAndWaitForResponse("qGDBServerVersion", response) ==
1091 if (response.IsNormalResponse()) {
1092 llvm::StringRef name, value;
1093 bool success = false;
1094 while (response.GetNameColonValue(name, value)) {
1095 if (name == "name") {
1096 success = true;
1097 m_gdb_server_name = std::string(value);
1098 } else if (name == "version") {
1099 llvm::StringRef major, minor;
1100 std::tie(major, minor) = value.split('.');
1101 if (!major.getAsInteger(0, m_gdb_server_version))
1102 success = true;
1103 }
1104 }
1105 if (success)
1107 }
1108 }
1109 }
1111}
1112
1114 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1116 llvm::StringRef avail_name;
1117
1118#if HAVE_LIBCOMPRESSION
1119 if (avail_type == CompressionType::None) {
1120 for (auto compression : supported_compressions) {
1121 if (compression == "lzfse") {
1122 avail_type = CompressionType::LZFSE;
1123 avail_name = compression;
1124 break;
1125 }
1126 }
1127 }
1128 if (avail_type == CompressionType::None) {
1129 for (auto compression : supported_compressions) {
1130 if (compression == "zlib-deflate") {
1131 avail_type = CompressionType::ZlibDeflate;
1132 avail_name = compression;
1133 break;
1134 }
1135 }
1136 }
1137#endif
1138
1139#if LLVM_ENABLE_ZLIB
1140 if (avail_type == CompressionType::None) {
1141 for (auto compression : supported_compressions) {
1142 if (compression == "zlib-deflate") {
1143 avail_type = CompressionType::ZlibDeflate;
1144 avail_name = compression;
1145 break;
1146 }
1147 }
1148 }
1149#endif
1150
1151#if HAVE_LIBCOMPRESSION
1152 if (avail_type == CompressionType::None) {
1153 for (auto compression : supported_compressions) {
1154 if (compression == "lz4") {
1155 avail_type = CompressionType::LZ4;
1156 avail_name = compression;
1157 break;
1158 }
1159 }
1160 }
1161 if (avail_type == CompressionType::None) {
1162 for (auto compression : supported_compressions) {
1163 if (compression == "lzma") {
1164 avail_type = CompressionType::LZMA;
1165 avail_name = compression;
1166 break;
1167 }
1168 }
1169 }
1170#endif
1171
1172 if (avail_type != CompressionType::None) {
1173 StringExtractorGDBRemote response;
1174 std::string packet = "QEnableCompression:type:" + avail_name.str() + ";";
1175 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
1176 return;
1177
1178 if (response.IsOKResponse()) {
1179 m_compression_type = avail_type;
1180 }
1181 }
1182}
1183
1185 if (GetGDBServerVersion()) {
1186 if (!m_gdb_server_name.empty())
1187 return m_gdb_server_name.c_str();
1188 }
1189 return nullptr;
1190}
1191
1197
1199 StringExtractorGDBRemote response;
1201 return false;
1202
1203 if (!response.IsNormalResponse())
1204 return false;
1205
1206 if (response.GetChar() == 'Q' && response.GetChar() == 'C') {
1207 auto pid_tid = response.GetPidTid(0);
1208 if (!pid_tid)
1209 return false;
1210
1211 lldb::pid_t pid = pid_tid->first;
1212 // invalid
1214 return false;
1215
1216 // if we get pid as well, update m_curr_pid
1217 if (pid != 0) {
1218 m_curr_pid_run = m_curr_pid = pid;
1220 }
1221 tid = pid_tid->second;
1222 }
1223
1224 return true;
1225}
1226
1227static void ParseOSType(llvm::StringRef value, std::string &os_name,
1228 std::string &environment) {
1229 if (value == "iossimulator" || value == "tvossimulator" ||
1230 value == "watchossimulator" || value == "xrossimulator" ||
1231 value == "visionossimulator") {
1232 environment = "simulator";
1233 os_name = value.drop_back(environment.size()).str();
1234 } else if (value == "maccatalyst") {
1235 os_name = "ios";
1236 environment = "macabi";
1237 } else {
1238 os_name = value.str();
1239 }
1240}
1241
1243 Log *log = GetLog(GDBRLog::Process);
1244
1245 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
1246 // host info computation can require DNS traffic and shelling out to external processes.
1247 // Increase the timeout to account for that.
1248 ScopedTimeout timeout(*this, seconds(10));
1250 StringExtractorGDBRemote response;
1251 if (SendPacketAndWaitForResponse("qHostInfo", response) ==
1253 if (response.IsNormalResponse()) {
1254 llvm::StringRef name;
1255 llvm::StringRef value;
1256 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1257 uint32_t sub = 0;
1258 std::string arch_name;
1259 std::string os_name;
1260 std::string environment;
1261 std::string vendor_name;
1262 std::string triple;
1263 uint32_t pointer_byte_size = 0;
1264 ByteOrder byte_order = eByteOrderInvalid;
1265 uint32_t num_keys_decoded = 0;
1266 while (response.GetNameColonValue(name, value)) {
1267 if (name == "cputype") {
1268 // exception type in big endian hex
1269 if (!value.getAsInteger(0, cpu))
1270 ++num_keys_decoded;
1271 } else if (name == "cpusubtype") {
1272 // exception count in big endian hex
1273 if (!value.getAsInteger(0, sub))
1274 ++num_keys_decoded;
1275 } else if (name == "arch") {
1276 arch_name = std::string(value);
1277 ++num_keys_decoded;
1278 } else if (name == "triple") {
1279 StringExtractor extractor(value);
1280 extractor.GetHexByteString(triple);
1281 ++num_keys_decoded;
1282 } else if (name == "distribution_id") {
1283 StringExtractor extractor(value);
1285 ++num_keys_decoded;
1286 } else if (name == "os_build") {
1287 StringExtractor extractor(value);
1288 extractor.GetHexByteString(m_os_build);
1289 ++num_keys_decoded;
1290 } else if (name == "hostname") {
1291 StringExtractor extractor(value);
1292 extractor.GetHexByteString(m_hostname);
1293 ++num_keys_decoded;
1294 } else if (name == "os_kernel") {
1295 StringExtractor extractor(value);
1296 extractor.GetHexByteString(m_os_kernel);
1297 ++num_keys_decoded;
1298 } else if (name == "ostype") {
1299 ParseOSType(value, os_name, environment);
1300 ++num_keys_decoded;
1301 } else if (name == "vendor") {
1302 vendor_name = std::string(value);
1303 ++num_keys_decoded;
1304 } else if (name == "endian") {
1305 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1306 .Case("little", eByteOrderLittle)
1307 .Case("big", eByteOrderBig)
1308 .Case("pdp", eByteOrderPDP)
1309 .Default(eByteOrderInvalid);
1310 if (byte_order != eByteOrderInvalid)
1311 ++num_keys_decoded;
1312 } else if (name == "ptrsize") {
1313 if (!value.getAsInteger(0, pointer_byte_size))
1314 ++num_keys_decoded;
1315 } else if (name == "addressing_bits") {
1316 if (!value.getAsInteger(0, m_low_mem_addressing_bits)) {
1317 ++num_keys_decoded;
1318 }
1319 } else if (name == "high_mem_addressing_bits") {
1320 if (!value.getAsInteger(0, m_high_mem_addressing_bits))
1321 ++num_keys_decoded;
1322 } else if (name == "low_mem_addressing_bits") {
1323 if (!value.getAsInteger(0, m_low_mem_addressing_bits))
1324 ++num_keys_decoded;
1325 } else if (name == "os_version" ||
1326 name == "version") // Older debugserver binaries used
1327 // the "version" key instead of
1328 // "os_version"...
1329 {
1330 if (!m_os_version.tryParse(value))
1331 ++num_keys_decoded;
1332 } else if (name == "maccatalyst_version") {
1333 if (!m_maccatalyst_version.tryParse(value))
1334 ++num_keys_decoded;
1335 } else if (name == "watchpoint_exceptions_received") {
1337 llvm::StringSwitch<LazyBool>(value)
1338 .Case("before", eLazyBoolNo)
1339 .Case("after", eLazyBoolYes)
1340 .Default(eLazyBoolCalculate);
1342 ++num_keys_decoded;
1343 } else if (name == "default_packet_timeout") {
1344 uint32_t timeout_seconds;
1345 if (!value.getAsInteger(0, timeout_seconds)) {
1346 m_default_packet_timeout = seconds(timeout_seconds);
1348 ++num_keys_decoded;
1349 }
1350 } else if (name == "vm-page-size") {
1351 int page_size;
1352 if (!value.getAsInteger(0, page_size)) {
1353 m_target_vm_page_size = page_size;
1354 ++num_keys_decoded;
1355 }
1356 }
1357 }
1358
1359 if (num_keys_decoded > 0)
1361
1362 if (triple.empty()) {
1363 if (arch_name.empty()) {
1364 if (cpu != LLDB_INVALID_CPUTYPE) {
1365 m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1366 if (pointer_byte_size) {
1367 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1368 }
1369 if (byte_order != eByteOrderInvalid) {
1370 assert(byte_order == m_host_arch.GetByteOrder());
1371 }
1372
1373 if (!vendor_name.empty())
1374 m_host_arch.GetTriple().setVendorName(
1375 llvm::StringRef(vendor_name));
1376 if (!os_name.empty())
1377 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1378 if (!environment.empty())
1379 m_host_arch.GetTriple().setEnvironmentName(environment);
1380 }
1381 } else {
1382 std::string triple;
1383 triple += arch_name;
1384 if (!vendor_name.empty() || !os_name.empty()) {
1385 triple += '-';
1386 if (vendor_name.empty())
1387 triple += "unknown";
1388 else
1389 triple += vendor_name;
1390 triple += '-';
1391 if (os_name.empty())
1392 triple += "unknown";
1393 else
1394 triple += os_name;
1395 }
1396 m_host_arch.SetTriple(triple.c_str());
1397
1398 llvm::Triple &host_triple = m_host_arch.GetTriple();
1399 if (host_triple.getVendor() == llvm::Triple::Apple &&
1400 host_triple.getOS() == llvm::Triple::Darwin) {
1401 switch (m_host_arch.GetMachine()) {
1402 case llvm::Triple::aarch64:
1403 case llvm::Triple::aarch64_32:
1404 case llvm::Triple::arm:
1405 case llvm::Triple::thumb:
1406 host_triple.setOS(llvm::Triple::IOS);
1407 break;
1408 default:
1409 host_triple.setOS(llvm::Triple::MacOSX);
1410 break;
1411 }
1412 }
1413 if (pointer_byte_size) {
1414 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1415 }
1416 if (byte_order != eByteOrderInvalid) {
1417 assert(byte_order == m_host_arch.GetByteOrder());
1418 }
1419 }
1420 } else {
1421 m_host_arch.SetTriple(triple.c_str());
1422 if (pointer_byte_size) {
1423 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1424 }
1425 if (byte_order != eByteOrderInvalid) {
1426 assert(byte_order == m_host_arch.GetByteOrder());
1427 }
1428
1429 LLDB_LOGF(log,
1430 "GDBRemoteCommunicationClient::%s parsed host "
1431 "architecture as %s, triple as %s from triple text %s",
1432 __FUNCTION__,
1433 m_host_arch.GetArchitectureName()
1434 ? m_host_arch.GetArchitectureName()
1435 : "<null-arch-name>",
1436 m_host_arch.GetTriple().getTriple().c_str(),
1437 triple.c_str());
1438 }
1439 }
1440 }
1441 }
1443}
1444
1446 size_t data_len) {
1447 StreamString packet;
1448 packet.PutCString("I");
1449 packet.PutBytesAsRawHex8(data, data_len);
1450 StringExtractorGDBRemote response;
1451 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1453 return 0;
1454 }
1455 return response.GetError();
1456}
1457
1464
1477
1483
1485 uint32_t permissions) {
1488 char packet[64];
1489 const int packet_len = ::snprintf(
1490 packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
1491 permissions & lldb::ePermissionsReadable ? "r" : "",
1492 permissions & lldb::ePermissionsWritable ? "w" : "",
1493 permissions & lldb::ePermissionsExecutable ? "x" : "");
1494 assert(packet_len < (int)sizeof(packet));
1495 UNUSED_IF_ASSERT_DISABLED(packet_len);
1496 StringExtractorGDBRemote response;
1497 if (SendPacketAndWaitForResponse(packet, response) ==
1499 if (response.IsUnsupportedResponse())
1501 else if (!response.IsErrorResponse())
1502 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1503 } else {
1505 }
1506 }
1507 return LLDB_INVALID_ADDRESS;
1508}
1509
1513 char packet[64];
1514 const int packet_len =
1515 ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1516 assert(packet_len < (int)sizeof(packet));
1517 UNUSED_IF_ASSERT_DISABLED(packet_len);
1518 StringExtractorGDBRemote response;
1519 if (SendPacketAndWaitForResponse(packet, response) ==
1521 if (response.IsUnsupportedResponse())
1523 else if (response.IsOKResponse())
1524 return true;
1525 } else {
1527 }
1528 }
1529 return false;
1530}
1531
1533 lldb::pid_t pid) {
1534 Status error;
1536
1537 packet.PutChar('D');
1538 if (keep_stopped) {
1540 char packet[64];
1541 const int packet_len =
1542 ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1543 assert(packet_len < (int)sizeof(packet));
1544 UNUSED_IF_ASSERT_DISABLED(packet_len);
1545 StringExtractorGDBRemote response;
1546 if (SendPacketAndWaitForResponse(packet, response) ==
1548 response.IsOKResponse()) {
1550 } else {
1552 }
1553 }
1554
1557 "Stays stopped not supported by this target.");
1558 return error;
1559 } else {
1560 packet.PutChar('1');
1561 }
1562 }
1563
1565 // Some servers (e.g. qemu) require specifying the PID even if only a single
1566 // process is running.
1567 if (pid == LLDB_INVALID_PROCESS_ID)
1568 pid = GetCurrentProcessID();
1569 packet.PutChar(';');
1570 packet.PutHex64(pid);
1571 } else if (pid != LLDB_INVALID_PROCESS_ID) {
1573 "Multiprocess extension not supported by the server.");
1574 return error;
1575 }
1576
1577 StringExtractorGDBRemote response;
1578 PacketResult packet_result =
1579 SendPacketAndWaitForResponse(packet.GetString(), response);
1580 if (packet_result != PacketResult::Success)
1581 error = Status::FromErrorString("Sending disconnect packet failed.");
1582 return error;
1583}
1584
1586 lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
1587 Status error;
1588 region_info.Clear();
1589
1592 char packet[64];
1593 const int packet_len = ::snprintf(
1594 packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1595 assert(packet_len < (int)sizeof(packet));
1596 UNUSED_IF_ASSERT_DISABLED(packet_len);
1597 StringExtractorGDBRemote response;
1598 if (SendPacketAndWaitForResponse(packet, response) ==
1601 llvm::StringRef name;
1602 llvm::StringRef value;
1603 addr_t addr_value = LLDB_INVALID_ADDRESS;
1604 bool success = true;
1605 bool saw_permissions = false;
1606 while (success && response.GetNameColonValue(name, value)) {
1607 if (name == "start") {
1608 if (!value.getAsInteger(16, addr_value))
1609 region_info.GetRange().SetRangeBase(addr_value);
1610 } else if (name == "size") {
1611 if (!value.getAsInteger(16, addr_value)) {
1612 region_info.GetRange().SetByteSize(addr_value);
1613 if (region_info.GetRange().GetRangeEnd() <
1614 region_info.GetRange().GetRangeBase()) {
1615 // Range size overflowed, truncate it.
1617 }
1618 }
1619 } else if (name == "permissions" && region_info.GetRange().IsValid()) {
1620 saw_permissions = true;
1621 if (region_info.GetRange().Contains(addr)) {
1622 if (value.contains('r'))
1623 region_info.SetReadable(eLazyBoolYes);
1624 else
1625 region_info.SetReadable(eLazyBoolNo);
1626
1627 if (value.contains('w'))
1628 region_info.SetWritable(eLazyBoolYes);
1629 else
1630 region_info.SetWritable(eLazyBoolNo);
1631
1632 if (value.contains('x'))
1633 region_info.SetExecutable(eLazyBoolYes);
1634 else
1635 region_info.SetExecutable(eLazyBoolNo);
1636
1637 region_info.SetMapped(eLazyBoolYes);
1638 } else {
1639 // The reported region does not contain this address -- we're
1640 // looking at an unmapped page
1641 region_info.SetReadable(eLazyBoolNo);
1642 region_info.SetWritable(eLazyBoolNo);
1643 region_info.SetExecutable(eLazyBoolNo);
1644 region_info.SetMapped(eLazyBoolNo);
1645 }
1646 } else if (name == "name") {
1647 StringExtractorGDBRemote name_extractor(value);
1648 std::string name;
1649 name_extractor.GetHexByteString(name);
1650 region_info.SetName(name.c_str());
1651 } else if (name == "flags") {
1652 region_info.SetMemoryTagged(eLazyBoolNo);
1653 region_info.SetIsShadowStack(eLazyBoolNo);
1654
1655 llvm::StringRef flags = value;
1656 llvm::StringRef flag;
1657 while (flags.size()) {
1658 flags = flags.ltrim();
1659 std::tie(flag, flags) = flags.split(' ');
1660 // To account for trailing whitespace
1661 if (flag.size()) {
1662 if (flag == "mt")
1663 region_info.SetMemoryTagged(eLazyBoolYes);
1664 else if (flag == "ss")
1665 region_info.SetIsShadowStack(eLazyBoolYes);
1666 }
1667 }
1668 } else if (name == "type") {
1669 for (llvm::StringRef entry : llvm::split(value, ',')) {
1670 if (entry == "stack")
1671 region_info.SetIsStackMemory(eLazyBoolYes);
1672 else if (entry == "heap")
1673 region_info.SetIsStackMemory(eLazyBoolNo);
1674 }
1675 } else if (name == "error") {
1676 StringExtractorGDBRemote error_extractor(value);
1677 std::string error_string;
1678 // Now convert the HEX bytes into a string value
1679 error_extractor.GetHexByteString(error_string);
1680 error = Status::FromErrorString(error_string.c_str());
1681 } else if (name == "dirty-pages") {
1682 std::vector<addr_t> dirty_page_list;
1683 for (llvm::StringRef x : llvm::split(value, ',')) {
1684 addr_t page;
1685 x.consume_front("0x");
1686 if (llvm::to_integer(x, page, 16))
1687 dirty_page_list.push_back(page);
1688 }
1689 region_info.SetDirtyPageList(dirty_page_list);
1690 } else if (name == "protection-key") {
1691 unsigned protection_key = 0;
1692 if (!value.getAsInteger(10, protection_key))
1693 region_info.SetProtectionKey(protection_key);
1694 }
1695 }
1696
1697 if (m_target_vm_page_size != 0)
1699
1700 if (region_info.GetRange().IsValid()) {
1701 // We got a valid address range back but no permissions -- which means
1702 // this is an unmapped page
1703 if (!saw_permissions) {
1704 region_info.SetReadable(eLazyBoolNo);
1705 region_info.SetWritable(eLazyBoolNo);
1706 region_info.SetExecutable(eLazyBoolNo);
1707 region_info.SetMapped(eLazyBoolNo);
1708 }
1709 } else {
1710 // We got an invalid address range back
1711 error = Status::FromErrorString("Server returned invalid range");
1712 }
1713 } else {
1715 }
1716 }
1717
1719 error = Status::FromErrorString("qMemoryRegionInfo is not supported");
1720 }
1721
1722 // Try qXfer:memory-map:read to get region information not included in
1723 // qMemoryRegionInfo
1724 MemoryRegionInfo qXfer_region_info;
1725 Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);
1726
1727 if (error.Fail()) {
1728 // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
1729 // the qXfer result as a fallback
1730 if (qXfer_error.Success()) {
1731 region_info = qXfer_region_info;
1732 error.Clear();
1733 } else {
1734 region_info.Clear();
1735 }
1736 } else if (qXfer_error.Success()) {
1737 // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
1738 // both regions are the same range, update the result to include the flash-
1739 // memory information that is specific to the qXfer result.
1740 if (region_info.GetRange() == qXfer_region_info.GetRange()) {
1741 region_info.SetFlash(qXfer_region_info.GetFlash());
1742 region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
1743 }
1744 }
1745 return error;
1746}
1747
1749 lldb::addr_t addr, MemoryRegionInfo &region) {
1751 if (!error.Success())
1752 return error;
1753 for (const auto &map_region : m_qXfer_memory_map) {
1754 if (map_region.GetRange().Contains(addr)) {
1755 region = map_region;
1756 return error;
1757 }
1758 }
1759 error = Status::FromErrorString("Region not found");
1760 return error;
1761}
1762
1764
1765 Status error;
1766
1768 // Already loaded, return success
1769 return error;
1770
1771 if (!XMLDocument::XMLEnabled()) {
1772 error = Status::FromErrorString("XML is not supported");
1773 return error;
1774 }
1775
1777 error = Status::FromErrorString("Memory map is not supported");
1778 return error;
1779 }
1780
1781 llvm::Expected<std::string> xml = ReadExtFeature("memory-map", "");
1782 if (!xml)
1783 return Status::FromError(xml.takeError());
1784
1785 XMLDocument xml_document;
1786
1787 if (!xml_document.ParseMemory(xml->c_str(), xml->size())) {
1788 error = Status::FromErrorString("Failed to parse memory map xml");
1789 return error;
1790 }
1791
1792 XMLNode map_node = xml_document.GetRootElement("memory-map");
1793 if (!map_node) {
1794 error = Status::FromErrorString("Invalid root node in memory map xml");
1795 return error;
1796 }
1797
1798 m_qXfer_memory_map.clear();
1799
1800 map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
1801 if (!memory_node.IsElement())
1802 return true;
1803 if (memory_node.GetName() != "memory")
1804 return true;
1805 auto type = memory_node.GetAttributeValue("type", "");
1806 uint64_t start;
1807 uint64_t length;
1808 if (!memory_node.GetAttributeValueAsUnsigned("start", start))
1809 return true;
1810 if (!memory_node.GetAttributeValueAsUnsigned("length", length))
1811 return true;
1812 MemoryRegionInfo region;
1813 region.GetRange().SetRangeBase(start);
1814 region.GetRange().SetByteSize(length);
1815 if (type == "rom") {
1816 region.SetReadable(eLazyBoolYes);
1817 this->m_qXfer_memory_map.push_back(region);
1818 } else if (type == "ram") {
1819 region.SetReadable(eLazyBoolYes);
1820 region.SetWritable(eLazyBoolYes);
1821 this->m_qXfer_memory_map.push_back(region);
1822 } else if (type == "flash") {
1823 region.SetFlash(eLazyBoolYes);
1824 memory_node.ForEachChildElement(
1825 [&region](const XMLNode &prop_node) -> bool {
1826 if (!prop_node.IsElement())
1827 return true;
1828 if (prop_node.GetName() != "property")
1829 return true;
1830 auto propname = prop_node.GetAttributeValue("name", "");
1831 if (propname == "blocksize") {
1832 uint64_t blocksize;
1833 if (prop_node.GetElementTextAsUnsigned(blocksize))
1834 region.SetBlocksize(blocksize);
1835 }
1836 return true;
1837 });
1838 this->m_qXfer_memory_map.push_back(region);
1839 }
1840 return true;
1841 });
1842
1844
1845 return error;
1846}
1847
1851 }
1852
1853 std::optional<uint32_t> num;
1855 StringExtractorGDBRemote response;
1856 if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) ==
1859 llvm::StringRef name;
1860 llvm::StringRef value;
1861 while (response.GetNameColonValue(name, value)) {
1862 if (name == "num") {
1863 value.getAsInteger(0, m_num_supported_hardware_watchpoints);
1865 }
1866 }
1867 if (!num) {
1869 }
1870 } else {
1872 }
1873 }
1874
1875 return num;
1876}
1877
1878WatchpointHardwareFeature
1882
1885 GetHostInfo();
1886
1887 // Process determines this by target CPU, but allow for the
1888 // remote stub to override it via the qHostInfo
1889 // watchpoint_exceptions_received key, if it is present.
1892 return false;
1894 return true;
1895 }
1896
1897 return std::nullopt;
1898}
1899
1901 if (file_spec) {
1902 std::string path{file_spec.GetPath(false)};
1903 StreamString packet;
1904 packet.PutCString("QSetSTDIN:");
1905 packet.PutStringAsRawHex8(path);
1906
1907 StringExtractorGDBRemote response;
1908 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1910 if (response.IsOKResponse())
1911 return 0;
1912 uint8_t error = response.GetError();
1913 if (error)
1914 return error;
1915 }
1916 }
1917 return -1;
1918}
1919
1921 if (file_spec) {
1922 std::string path{file_spec.GetPath(false)};
1923 StreamString packet;
1924 packet.PutCString("QSetSTDOUT:");
1925 packet.PutStringAsRawHex8(path);
1926
1927 StringExtractorGDBRemote response;
1928 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1930 if (response.IsOKResponse())
1931 return 0;
1932 uint8_t error = response.GetError();
1933 if (error)
1934 return error;
1935 }
1936 }
1937 return -1;
1938}
1939
1941 if (file_spec) {
1942 std::string path{file_spec.GetPath(false)};
1943 StreamString packet;
1944 packet.PutCString("QSetSTDERR:");
1945 packet.PutStringAsRawHex8(path);
1946
1947 StringExtractorGDBRemote response;
1948 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1950 if (response.IsOKResponse())
1951 return 0;
1952 uint8_t error = response.GetError();
1953 if (error)
1954 return error;
1955 }
1956 }
1957 return -1;
1958}
1959
1961 StringExtractorGDBRemote response;
1962 if (SendPacketAndWaitForResponse("qGetWorkingDir", response) ==
1964 if (response.IsUnsupportedResponse())
1965 return false;
1966 if (response.IsErrorResponse())
1967 return false;
1968 std::string cwd;
1969 response.GetHexByteString(cwd);
1970 working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
1971 return !cwd.empty();
1972 }
1973 return false;
1974}
1975
1977 if (working_dir) {
1978 std::string path{working_dir.GetPath(false)};
1979 StreamString packet;
1980 packet.PutCString("QSetWorkingDir:");
1981 packet.PutStringAsRawHex8(path);
1982
1983 StringExtractorGDBRemote response;
1984 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1986 if (response.IsOKResponse())
1987 return 0;
1988 uint8_t error = response.GetError();
1989 if (error)
1990 return error;
1991 }
1992 }
1993 return -1;
1994}
1995
1997 char packet[32];
1998 const int packet_len =
1999 ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
2000 assert(packet_len < (int)sizeof(packet));
2001 UNUSED_IF_ASSERT_DISABLED(packet_len);
2002 StringExtractorGDBRemote response;
2003 if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
2004 if (response.IsOKResponse())
2005 return 0;
2006 uint8_t error = response.GetError();
2007 if (error)
2008 return error;
2009 }
2010 return -1;
2011}
2012
2014 char packet[32];
2015 const int packet_len = ::snprintf(packet, sizeof(packet),
2016 "QSetDetachOnError:%i", enable ? 1 : 0);
2017 assert(packet_len < (int)sizeof(packet));
2018 UNUSED_IF_ASSERT_DISABLED(packet_len);
2019 StringExtractorGDBRemote response;
2020 if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
2021 if (response.IsOKResponse())
2022 return 0;
2023 uint8_t error = response.GetError();
2024 if (error)
2025 return error;
2026 }
2027 return -1;
2028}
2029
2031 StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
2032 if (response.IsNormalResponse()) {
2033 llvm::StringRef name;
2034 llvm::StringRef value;
2035 StringExtractor extractor;
2036
2037 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2038 uint32_t sub = 0;
2039 std::string vendor;
2040 std::string os_type;
2041
2042 while (response.GetNameColonValue(name, value)) {
2043 if (name == "pid") {
2045 value.getAsInteger(0, pid);
2046 process_info.SetProcessID(pid);
2047 } else if (name == "ppid") {
2049 value.getAsInteger(0, pid);
2050 process_info.SetParentProcessID(pid);
2051 } else if (name == "uid") {
2052 uint32_t uid = UINT32_MAX;
2053 value.getAsInteger(0, uid);
2054 process_info.SetUserID(uid);
2055 } else if (name == "euid") {
2056 uint32_t uid = UINT32_MAX;
2057 value.getAsInteger(0, uid);
2058 process_info.SetEffectiveUserID(uid);
2059 } else if (name == "gid") {
2060 uint32_t gid = UINT32_MAX;
2061 value.getAsInteger(0, gid);
2062 process_info.SetGroupID(gid);
2063 } else if (name == "egid") {
2064 uint32_t gid = UINT32_MAX;
2065 value.getAsInteger(0, gid);
2066 process_info.SetEffectiveGroupID(gid);
2067 } else if (name == "triple") {
2068 StringExtractor extractor(value);
2069 std::string triple;
2070 extractor.GetHexByteString(triple);
2071 process_info.GetArchitecture().SetTriple(triple.c_str());
2072 } else if (name == "name") {
2073 StringExtractor extractor(value);
2074 // The process name from ASCII hex bytes since we can't control the
2075 // characters in a process name
2076 std::string name;
2077 extractor.GetHexByteString(name);
2078 process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
2079 } else if (name == "args") {
2080 llvm::StringRef encoded_args(value), hex_arg;
2081
2082 bool is_arg0 = true;
2083 while (!encoded_args.empty()) {
2084 std::tie(hex_arg, encoded_args) = encoded_args.split('-');
2085 std::string arg;
2086 StringExtractor extractor(hex_arg);
2087 if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {
2088 // In case of wrong encoding, we discard all the arguments
2089 process_info.GetArguments().Clear();
2090 process_info.SetArg0("");
2091 break;
2092 }
2093 if (is_arg0)
2094 process_info.SetArg0(arg);
2095 else
2096 process_info.GetArguments().AppendArgument(arg);
2097 is_arg0 = false;
2098 }
2099 } else if (name == "cputype") {
2100 value.getAsInteger(0, cpu);
2101 } else if (name == "cpusubtype") {
2102 value.getAsInteger(0, sub);
2103 } else if (name == "vendor") {
2104 vendor = std::string(value);
2105 } else if (name == "ostype") {
2106 os_type = std::string(value);
2107 }
2108 }
2109
2110 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
2111 if (vendor == "apple") {
2113 sub);
2114 process_info.GetArchitecture().GetTriple().setVendorName(
2115 llvm::StringRef(vendor));
2116 process_info.GetArchitecture().GetTriple().setOSName(
2117 llvm::StringRef(os_type));
2118 }
2119 }
2120
2121 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
2122 return true;
2123 }
2124 return false;
2125}
2126
2128 lldb::pid_t pid, ProcessInstanceInfo &process_info) {
2129 process_info.Clear();
2130
2132 char packet[32];
2133 const int packet_len =
2134 ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
2135 assert(packet_len < (int)sizeof(packet));
2136 UNUSED_IF_ASSERT_DISABLED(packet_len);
2137 StringExtractorGDBRemote response;
2138 if (SendPacketAndWaitForResponse(packet, response) ==
2140 return DecodeProcessInfoResponse(response, process_info);
2141 } else {
2143 return false;
2144 }
2145 }
2146 return false;
2147}
2148
2151
2152 if (allow_lazy) {
2154 return true;
2156 return false;
2157 }
2158
2159 GetHostInfo();
2160
2161 StringExtractorGDBRemote response;
2162 if (SendPacketAndWaitForResponse("qProcessInfo", response) ==
2164 if (response.IsNormalResponse()) {
2165 llvm::StringRef name;
2166 llvm::StringRef value;
2167 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2168 uint32_t sub = 0;
2169 std::string os_name;
2170 std::string environment;
2171 std::string vendor_name;
2172 std::string triple;
2173 std::string elf_abi;
2174 uint32_t pointer_byte_size = 0;
2175 StringExtractor extractor;
2176 ByteOrder byte_order = eByteOrderInvalid;
2177 uint32_t num_keys_decoded = 0;
2179 while (response.GetNameColonValue(name, value)) {
2180 if (name == "cputype") {
2181 if (!value.getAsInteger(16, cpu))
2182 ++num_keys_decoded;
2183 } else if (name == "cpusubtype") {
2184 if (!value.getAsInteger(16, sub)) {
2185 ++num_keys_decoded;
2186 // Workaround for pre-2024 Apple debugserver, which always
2187 // returns arm64e on arm64e-capable hardware regardless of
2188 // what the process is. This can be deleted at some point
2189 // in the future.
2190 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2191 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2192 if (GetGDBServerVersion())
2193 if (m_gdb_server_version >= 1000 &&
2194 m_gdb_server_version <= 1504)
2195 sub = 0;
2196 }
2197 }
2198 } else if (name == "triple") {
2199 StringExtractor extractor(value);
2200 extractor.GetHexByteString(triple);
2201 ++num_keys_decoded;
2202 } else if (name == "ostype") {
2203 ParseOSType(value, os_name, environment);
2204 ++num_keys_decoded;
2205 } else if (name == "vendor") {
2206 vendor_name = std::string(value);
2207 ++num_keys_decoded;
2208 } else if (name == "endian") {
2209 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2210 .Case("little", eByteOrderLittle)
2211 .Case("big", eByteOrderBig)
2212 .Case("pdp", eByteOrderPDP)
2213 .Default(eByteOrderInvalid);
2214 if (byte_order != eByteOrderInvalid)
2215 ++num_keys_decoded;
2216 } else if (name == "ptrsize") {
2217 if (!value.getAsInteger(16, pointer_byte_size))
2218 ++num_keys_decoded;
2219 } else if (name == "pid") {
2220 if (!value.getAsInteger(16, pid))
2221 ++num_keys_decoded;
2222 } else if (name == "elf_abi") {
2223 elf_abi = std::string(value);
2224 ++num_keys_decoded;
2225 } else if (name == "main-binary-uuid") {
2226 m_process_standalone_uuid.SetFromStringRef(value);
2227 ++num_keys_decoded;
2228 } else if (name == "main-binary-slide") {
2229 StringExtractor extractor(value);
2231 extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
2234 ++num_keys_decoded;
2235 }
2236 } else if (name == "main-binary-address") {
2237 StringExtractor extractor(value);
2239 extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
2242 ++num_keys_decoded;
2243 }
2244 } else if (name == "binary-addresses") {
2245 m_binary_addresses.clear();
2246 ++num_keys_decoded;
2247 for (llvm::StringRef x : llvm::split(value, ',')) {
2248 addr_t vmaddr;
2249 x.consume_front("0x");
2250 if (llvm::to_integer(x, vmaddr, 16))
2251 m_binary_addresses.push_back(vmaddr);
2252 }
2253 }
2254 }
2255 if (num_keys_decoded > 0)
2257 if (pid != LLDB_INVALID_PROCESS_ID) {
2259 m_curr_pid_run = m_curr_pid = pid;
2260 }
2261
2262 // Set the ArchSpec from the triple if we have it.
2263 if (!triple.empty()) {
2264 m_process_arch.SetTriple(triple.c_str());
2265 m_process_arch.SetFlags(elf_abi);
2266 if (pointer_byte_size) {
2267 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2268 }
2269 } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
2270 !vendor_name.empty()) {
2271 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
2272 if (!environment.empty())
2273 triple.setEnvironmentName(environment);
2274
2275 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2276 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2277 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2278 switch (triple.getObjectFormat()) {
2279 case llvm::Triple::MachO:
2280 m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
2281 break;
2282 case llvm::Triple::ELF:
2283 m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
2284 break;
2285 case llvm::Triple::COFF:
2286 m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
2287 break;
2288 case llvm::Triple::GOFF:
2289 case llvm::Triple::SPIRV:
2290 case llvm::Triple::Wasm:
2291 case llvm::Triple::XCOFF:
2292 case llvm::Triple::DXContainer:
2293 LLDB_LOGF(log, "error: not supported target architecture");
2294 return false;
2295 case llvm::Triple::UnknownObjectFormat:
2296 LLDB_LOGF(log, "error: failed to determine target architecture");
2297 return false;
2298 }
2299
2300 if (pointer_byte_size) {
2301 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2302 }
2303 if (byte_order != eByteOrderInvalid) {
2304 assert(byte_order == m_process_arch.GetByteOrder());
2305 }
2306 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2307 m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2308 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2309 }
2310 return true;
2311 }
2312 } else {
2314 }
2315
2316 return false;
2317}
2318
2320 const ProcessInstanceInfoMatch &match_info,
2321 ProcessInstanceInfoList &process_infos) {
2322 process_infos.clear();
2323
2325 StreamString packet;
2326 packet.PutCString("qfProcessInfo");
2327 if (!match_info.MatchAllProcesses()) {
2328 packet.PutChar(':');
2329 const char *name = match_info.GetProcessInfo().GetName();
2330 bool has_name_match = false;
2331 if (name && name[0]) {
2332 has_name_match = true;
2333 NameMatch name_match_type = match_info.GetNameMatchType();
2334 switch (name_match_type) {
2335 case NameMatch::Ignore:
2336 has_name_match = false;
2337 break;
2338
2339 case NameMatch::Equals:
2340 packet.PutCString("name_match:equals;");
2341 break;
2342
2344 packet.PutCString("name_match:contains;");
2345 break;
2346
2348 packet.PutCString("name_match:starts_with;");
2349 break;
2350
2352 packet.PutCString("name_match:ends_with;");
2353 break;
2354
2356 packet.PutCString("name_match:regex;");
2357 break;
2358 }
2359 if (has_name_match) {
2360 packet.PutCString("name:");
2361 packet.PutBytesAsRawHex8(name, ::strlen(name));
2362 packet.PutChar(';');
2363 }
2364 }
2365
2366 if (match_info.GetProcessInfo().ProcessIDIsValid())
2367 packet.Printf("pid:%" PRIu64 ";",
2368 match_info.GetProcessInfo().GetProcessID());
2369 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2370 packet.Printf("parent_pid:%" PRIu64 ";",
2371 match_info.GetProcessInfo().GetParentProcessID());
2372 if (match_info.GetProcessInfo().UserIDIsValid())
2373 packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
2374 if (match_info.GetProcessInfo().GroupIDIsValid())
2375 packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
2376 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2377 packet.Printf("euid:%u;",
2378 match_info.GetProcessInfo().GetEffectiveUserID());
2379 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2380 packet.Printf("egid:%u;",
2381 match_info.GetProcessInfo().GetEffectiveGroupID());
2382 packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
2383 if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
2384 const ArchSpec &match_arch =
2385 match_info.GetProcessInfo().GetArchitecture();
2386 const llvm::Triple &triple = match_arch.GetTriple();
2387 packet.PutCString("triple:");
2388 packet.PutCString(triple.getTriple());
2389 packet.PutChar(';');
2390 }
2391 }
2392 StringExtractorGDBRemote response;
2393 // Increase timeout as the first qfProcessInfo packet takes a long time on
2394 // Android. The value of 1min was arrived at empirically.
2395 ScopedTimeout timeout(*this, minutes(1));
2396 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2398 do {
2399 ProcessInstanceInfo process_info;
2400 if (!DecodeProcessInfoResponse(response, process_info))
2401 break;
2402 process_infos.push_back(process_info);
2403 response = StringExtractorGDBRemote();
2404 } while (SendPacketAndWaitForResponse("qsProcessInfo", response) ==
2406 } else {
2408 return 0;
2409 }
2410 }
2411 return process_infos.size();
2412}
2413
2415 std::string &name) {
2417 char packet[32];
2418 const int packet_len =
2419 ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
2420 assert(packet_len < (int)sizeof(packet));
2421 UNUSED_IF_ASSERT_DISABLED(packet_len);
2422 StringExtractorGDBRemote response;
2423 if (SendPacketAndWaitForResponse(packet, response) ==
2425 if (response.IsNormalResponse()) {
2426 // Make sure we parsed the right number of characters. The response is
2427 // the hex encoded user name and should make up the entire packet. If
2428 // there are any non-hex ASCII bytes, the length won't match below..
2429 if (response.GetHexByteString(name) * 2 ==
2430 response.GetStringRef().size())
2431 return true;
2432 }
2433 } else {
2434 m_supports_qUserName = false;
2435 return false;
2436 }
2437 }
2438 return false;
2439}
2440
2442 std::string &name) {
2444 char packet[32];
2445 const int packet_len =
2446 ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
2447 assert(packet_len < (int)sizeof(packet));
2448 UNUSED_IF_ASSERT_DISABLED(packet_len);
2449 StringExtractorGDBRemote response;
2450 if (SendPacketAndWaitForResponse(packet, response) ==
2452 if (response.IsNormalResponse()) {
2453 // Make sure we parsed the right number of characters. The response is
2454 // the hex encoded group name and should make up the entire packet. If
2455 // there are any non-hex ASCII bytes, the length won't match below..
2456 if (response.GetHexByteString(name) * 2 ==
2457 response.GetStringRef().size())
2458 return true;
2459 }
2460 } else {
2461 m_supports_qGroupName = false;
2462 return false;
2463 }
2464 }
2465 return false;
2466}
2467
2468static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
2469 uint32_t recv_size) {
2470 packet.Clear();
2471 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2472 uint32_t bytes_left = send_size;
2473 while (bytes_left > 0) {
2474 if (bytes_left >= 26) {
2475 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2476 bytes_left -= 26;
2477 } else {
2478 packet.Printf("%*.*s;", bytes_left, bytes_left,
2479 "abcdefghijklmnopqrstuvwxyz");
2480 bytes_left = 0;
2481 }
2482 }
2483}
2484
2485duration<float>
2486calculate_standard_deviation(const std::vector<duration<float>> &v) {
2487 if (v.size() == 0)
2488 return duration<float>::zero();
2489 using Dur = duration<float>;
2490 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2491 Dur mean = sum / v.size();
2492 float accum = 0;
2493 for (auto d : v) {
2494 float delta = (d - mean).count();
2495 accum += delta * delta;
2496 };
2497
2498 return Dur(sqrtf(accum / (v.size() - 1)));
2499}
2500
2502 uint32_t max_send,
2503 uint32_t max_recv,
2504 uint64_t recv_amount,
2505 bool json, Stream &strm) {
2506
2507 if (SendSpeedTestPacket(0, 0)) {
2508 StreamString packet;
2509 if (json)
2510 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2511 "\"results\" : [",
2512 num_packets);
2513 else
2514 strm.Printf("Testing sending %u packets of various sizes:\n",
2515 num_packets);
2516 strm.Flush();
2517
2518 uint32_t result_idx = 0;
2519 uint32_t send_size;
2520 std::vector<duration<float>> packet_times;
2521
2522 for (send_size = 0; send_size <= max_send;
2523 send_size ? send_size *= 2 : send_size = 4) {
2524 for (uint32_t recv_size = 0; recv_size <= max_recv;
2525 recv_size ? recv_size *= 2 : recv_size = 4) {
2526 MakeSpeedTestPacket(packet, send_size, recv_size);
2527
2528 packet_times.clear();
2529 // Test how long it takes to send 'num_packets' packets
2530 const auto start_time = steady_clock::now();
2531 for (uint32_t i = 0; i < num_packets; ++i) {
2532 const auto packet_start_time = steady_clock::now();
2533 StringExtractorGDBRemote response;
2534 SendPacketAndWaitForResponse(packet.GetString(), response);
2535 const auto packet_end_time = steady_clock::now();
2536 packet_times.push_back(packet_end_time - packet_start_time);
2537 }
2538 const auto end_time = steady_clock::now();
2539 const auto total_time = end_time - start_time;
2540
2541 float packets_per_second =
2542 ((float)num_packets) / duration<float>(total_time).count();
2543 auto average_per_packet = num_packets > 0 ? total_time / num_packets
2544 : duration<float>::zero();
2545 const duration<float> standard_deviation =
2546 calculate_standard_deviation(packet_times);
2547 if (json) {
2548 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2549 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2550 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2551 result_idx > 0 ? "," : "", send_size, recv_size,
2552 total_time, standard_deviation);
2553 ++result_idx;
2554 } else {
2555 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2556 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2557 "standard deviation of {5,10:ms+f6}\n",
2558 send_size, recv_size, duration<float>(total_time),
2559 packets_per_second, duration<float>(average_per_packet),
2560 standard_deviation);
2561 }
2562 strm.Flush();
2563 }
2564 }
2565
2566 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2567 if (json)
2568 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2569 ": %" PRIu64 ",\n \"results\" : [",
2570 recv_amount);
2571 else
2572 strm.Printf("Testing receiving %2.1fMB of data using varying receive "
2573 "packet sizes:\n",
2574 k_recv_amount_mb);
2575 strm.Flush();
2576 send_size = 0;
2577 result_idx = 0;
2578 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2579 MakeSpeedTestPacket(packet, send_size, recv_size);
2580
2581 // If we have a receive size, test how long it takes to receive 4MB of
2582 // data
2583 if (recv_size > 0) {
2584 const auto start_time = steady_clock::now();
2585 uint32_t bytes_read = 0;
2586 uint32_t packet_count = 0;
2587 while (bytes_read < recv_amount) {
2588 StringExtractorGDBRemote response;
2589 SendPacketAndWaitForResponse(packet.GetString(), response);
2590 bytes_read += recv_size;
2591 ++packet_count;
2592 }
2593 const auto end_time = steady_clock::now();
2594 const auto total_time = end_time - start_time;
2595 float mb_second = ((float)recv_amount) /
2596 duration<float>(total_time).count() /
2597 (1024.0 * 1024.0);
2598 float packets_per_second =
2599 ((float)packet_count) / duration<float>(total_time).count();
2600 const auto average_per_packet = packet_count > 0
2601 ? total_time / packet_count
2602 : duration<float>::zero();
2603
2604 if (json) {
2605 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2606 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2607 result_idx > 0 ? "," : "", send_size, recv_size,
2608 total_time);
2609 ++result_idx;
2610 } else {
2611 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2612 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2613 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2614 send_size, recv_size, packet_count, k_recv_amount_mb,
2615 duration<float>(total_time), mb_second,
2616 packets_per_second, duration<float>(average_per_packet));
2617 }
2618 strm.Flush();
2619 }
2620 }
2621 if (json)
2622 strm.Printf("\n ]\n }\n}\n");
2623 else
2624 strm.EOL();
2625 }
2626}
2627
2629 uint32_t recv_size) {
2630 StreamString packet;
2631 MakeSpeedTestPacket(packet, send_size, recv_size);
2632
2633 StringExtractorGDBRemote response;
2634 return SendPacketAndWaitForResponse(packet.GetString(), response) ==
2636}
2637
2639 const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
2640 std::string &socket_name) {
2642 port = 0;
2643 socket_name.clear();
2644
2645 StringExtractorGDBRemote response;
2646 StreamString stream;
2647 stream.PutCString("qLaunchGDBServer;");
2648 std::string hostname;
2649 if (remote_accept_hostname && remote_accept_hostname[0])
2650 hostname = remote_accept_hostname;
2651 else {
2652 if (HostInfo::GetHostname(hostname)) {
2653 // Make the GDB server we launch only accept connections from this host
2654 stream.Printf("host:%s;", hostname.c_str());
2655 } else {
2656 // Make the GDB server we launch accept connections from any host since
2657 // we can't figure out the hostname
2658 stream.Printf("host:*;");
2659 }
2660 }
2661 // give the process a few seconds to startup
2662 ScopedTimeout timeout(*this, seconds(10));
2663
2664 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
2666 if (response.IsErrorResponse())
2667 return false;
2668
2669 llvm::StringRef name;
2670 llvm::StringRef value;
2671 while (response.GetNameColonValue(name, value)) {
2672 if (name == "port")
2673 value.getAsInteger(0, port);
2674 else if (name == "pid")
2675 value.getAsInteger(0, pid);
2676 else if (name.compare("socket_name") == 0) {
2677 StringExtractor extractor(value);
2678 extractor.GetHexByteString(socket_name);
2679 }
2680 }
2681 return true;
2682 }
2683 return false;
2684}
2685
2687 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2688 connection_urls.clear();
2689
2690 StringExtractorGDBRemote response;
2691 if (SendPacketAndWaitForResponse("qQueryGDBServer", response) !=
2693 return 0;
2694
2697 if (!data)
2698 return 0;
2699
2700 StructuredData::Array *array = data->GetAsArray();
2701 if (!array)
2702 return 0;
2703
2704 for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
2705 std::optional<StructuredData::Dictionary *> maybe_element =
2707 if (!maybe_element)
2708 continue;
2709
2710 StructuredData::Dictionary *element = *maybe_element;
2711 uint16_t port = 0;
2712 if (StructuredData::ObjectSP port_osp =
2713 element->GetValueForKey(llvm::StringRef("port")))
2714 port = port_osp->GetUnsignedIntegerValue(0);
2715
2716 std::string socket_name;
2717 if (StructuredData::ObjectSP socket_name_osp =
2718 element->GetValueForKey(llvm::StringRef("socket_name")))
2719 socket_name = std::string(socket_name_osp->GetStringValue());
2720
2721 if (port != 0 || !socket_name.empty())
2722 connection_urls.emplace_back(port, socket_name);
2723 }
2724 return connection_urls.size();
2725}
2726
2728 StreamString stream;
2729 stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
2730
2731 StringExtractorGDBRemote response;
2732 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
2734 if (response.IsOKResponse())
2735 return true;
2736 }
2737 return false;
2738}
2739
2741 uint64_t tid, uint64_t pid, char op) {
2743 packet.PutChar('H');
2744 packet.PutChar(op);
2745
2746 if (pid != LLDB_INVALID_PROCESS_ID)
2747 packet.Printf("p%" PRIx64 ".", pid);
2748
2749 if (tid == UINT64_MAX)
2750 packet.PutCString("-1");
2751 else
2752 packet.Printf("%" PRIx64, tid);
2753
2754 StringExtractorGDBRemote response;
2755 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2757 if (response.IsOKResponse())
2758 return {{pid, tid}};
2759
2760 /*
2761 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2762 * Hg packet.
2763 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2764 * which can
2765 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2766 */
2767 if (response.IsUnsupportedResponse() && IsConnected())
2768 return {{1, 1}};
2769 }
2770 return std::nullopt;
2771}
2772
2774 uint64_t pid) {
2775 if (m_curr_tid == tid &&
2776 (m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid))
2777 return true;
2778
2779 std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');
2780 if (ret) {
2781 if (ret->pid != LLDB_INVALID_PROCESS_ID)
2782 m_curr_pid = ret->pid;
2783 m_curr_tid = ret->tid;
2784 }
2785 return ret.has_value();
2786}
2787
2789 uint64_t pid) {
2790 if (m_curr_tid_run == tid &&
2791 (m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid))
2792 return true;
2793
2794 std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');
2795 if (ret) {
2796 if (ret->pid != LLDB_INVALID_PROCESS_ID)
2797 m_curr_pid_run = ret->pid;
2798 m_curr_tid_run = ret->tid;
2799 }
2800 return ret.has_value();
2801}
2802
2804 StringExtractorGDBRemote &response) {
2806 return response.IsNormalResponse();
2807 return false;
2808}
2809
2811 lldb::tid_t tid, StringExtractorGDBRemote &response) {
2813 char packet[256];
2814 int packet_len =
2815 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
2816 assert(packet_len < (int)sizeof(packet));
2817 UNUSED_IF_ASSERT_DISABLED(packet_len);
2818 if (SendPacketAndWaitForResponse(packet, response) ==
2820 if (response.IsUnsupportedResponse())
2822 else if (response.IsNormalResponse())
2823 return true;
2824 else
2825 return false;
2826 } else {
2828 }
2829 }
2830 return false;
2831}
2832
2834 GDBStoppointType type, bool insert, addr_t addr, uint32_t length,
2835 std::chrono::seconds timeout) {
2837 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2838 __FUNCTION__, insert ? "add" : "remove", addr);
2839
2840 // Check if the stub is known not to support this breakpoint type
2841 if (!SupportsGDBStoppointPacket(type))
2842 return UINT8_MAX;
2843 // Construct the breakpoint packet
2844 char packet[64];
2845 const int packet_len =
2846 ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
2847 insert ? 'Z' : 'z', type, addr, length);
2848 // Check we haven't overwritten the end of the packet buffer
2849 assert(packet_len + 1 < (int)sizeof(packet));
2850 UNUSED_IF_ASSERT_DISABLED(packet_len);
2851 StringExtractorGDBRemote response;
2852 // Make sure the response is either "OK", "EXX" where XX are two hex digits,
2853 // or "" (unsupported)
2855 // Try to send the breakpoint packet, and check that it was correctly sent
2856 if (SendPacketAndWaitForResponse(packet, response, timeout) ==
2858 // Receive and OK packet when the breakpoint successfully placed
2859 if (response.IsOKResponse())
2860 return 0;
2861
2862 // Status while setting breakpoint, send back specific error
2863 if (response.IsErrorResponse())
2864 return response.GetError();
2865
2866 // Empty packet informs us that breakpoint is not supported
2867 if (response.IsUnsupportedResponse()) {
2868 // Disable this breakpoint type since it is unsupported
2869 switch (type) {
2871 m_supports_z0 = false;
2872 break;
2874 m_supports_z1 = false;
2875 break;
2876 case eWatchpointWrite:
2877 m_supports_z2 = false;
2878 break;
2879 case eWatchpointRead:
2880 m_supports_z3 = false;
2881 break;
2883 m_supports_z4 = false;
2884 break;
2885 case eStoppointInvalid:
2886 return UINT8_MAX;
2887 }
2888 }
2889 }
2890 // Signal generic failure
2891 return UINT8_MAX;
2892}
2893
2894std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
2896 bool &sequence_mutex_unavailable) {
2897 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2898
2899 Lock lock(*this);
2900 if (lock) {
2901 sequence_mutex_unavailable = false;
2902 StringExtractorGDBRemote response;
2903
2904 PacketResult packet_result;
2905 for (packet_result =
2906 SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
2907 packet_result == PacketResult::Success && response.IsNormalResponse();
2908 packet_result =
2909 SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
2910 char ch = response.GetChar();
2911 if (ch == 'l')
2912 break;
2913 if (ch == 'm') {
2914 do {
2915 auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID);
2916 // If we get an invalid response, break out of the loop.
2917 // If there are valid tids, they have been added to ids.
2918 // If there are no valid tids, we'll fall through to the
2919 // bare-iron target handling below.
2920 if (!pid_tid)
2921 break;
2922
2923 ids.push_back(*pid_tid);
2924 ch = response.GetChar(); // Skip the command separator
2925 } while (ch == ','); // Make sure we got a comma separator
2926 }
2927 }
2928
2929 /*
2930 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2931 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
2932 * could
2933 * be as simple as 'S05'. There is no packet which can give us pid and/or
2934 * tid.
2935 * Assume pid=tid=1 in such cases.
2936 */
2937 if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
2938 ids.size() == 0 && IsConnected()) {
2939 ids.emplace_back(1, 1);
2940 }
2941 } else {
2943 LLDB_LOG(log, "error: failed to get packet sequence mutex, not sending "
2944 "packet 'qfThreadInfo'");
2945 sequence_mutex_unavailable = true;
2946 }
2947
2948 return ids;
2949}
2950
2952 std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
2954 thread_ids.clear();
2955
2956 auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
2957 if (ids.empty() || sequence_mutex_unavailable)
2958 return 0;
2959
2960 for (auto id : ids) {
2961 // skip threads that do not belong to the current process
2962 if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid)
2963 continue;
2964 if (id.second != LLDB_INVALID_THREAD_ID &&
2966 thread_ids.push_back(id.second);
2967 }
2968
2969 return thread_ids.size();
2970}
2971
2973 StringExtractorGDBRemote response;
2974 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) !=
2976 !response.IsNormalResponse())
2977 return LLDB_INVALID_ADDRESS;
2978 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2979}
2980
2982 llvm::StringRef command,
2983 const FileSpec &
2984 working_dir, // Pass empty FileSpec to use the current working directory
2985 int *status_ptr, // Pass NULL if you don't want the process exit status
2986 int *signo_ptr, // Pass NULL if you don't want the signal that caused the
2987 // process to exit
2988 std::string
2989 *command_output, // Pass nullptr if you don't want the command output
2990 std::string *separated_error_output, // Pass nullptr if you don't want the
2991 // command error output
2992 const Timeout<std::micro> &timeout) {
2994 stream.PutCString("qPlatform_shell:");
2995 stream.PutBytesAsRawHex8(command.data(), command.size());
2996 stream.PutChar(',');
2997 uint32_t timeout_sec = UINT32_MAX;
2998 if (timeout) {
2999 // TODO: Use chrono version of std::ceil once c++17 is available.
3000 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
3001 }
3002 stream.PutHex32(timeout_sec);
3003 if (working_dir) {
3004 std::string path{working_dir.GetPath(false)};
3005 stream.PutChar(',');
3006 stream.PutStringAsRawHex8(path);
3007 }
3008 StringExtractorGDBRemote response;
3009 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3011 if (response.GetChar() != 'F')
3012 return Status::FromErrorString("malformed reply");
3013 if (response.GetChar() != ',')
3014 return Status::FromErrorString("malformed reply");
3015 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
3016 if (exitcode == UINT32_MAX)
3017 return Status::FromErrorString("unable to run remote process");
3018 else if (status_ptr)
3019 *status_ptr = exitcode;
3020 if (response.GetChar() != ',')
3021 return Status::FromErrorString("malformed reply");
3022 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
3023 if (signo_ptr)
3024 *signo_ptr = signo;
3025 if (response.GetChar() != ',')
3026 return Status::FromErrorString("malformed reply");
3027 std::string output;
3028 response.GetEscapedBinaryData(output);
3029 if (command_output)
3030 command_output->assign(output);
3031 return Status();
3032 }
3033 return Status::FromErrorString("unable to send packet");
3034}
3035
3037 uint32_t file_permissions) {
3038 std::string path{file_spec.GetPath(false)};
3040 stream.PutCString("qPlatform_mkdir:");
3041 stream.PutHex32(file_permissions);
3042 stream.PutChar(',');
3043 stream.PutStringAsRawHex8(path);
3044 llvm::StringRef packet = stream.GetString();
3045 StringExtractorGDBRemote response;
3046
3047 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
3048 return Status::FromErrorStringWithFormat("failed to send '%s' packet",
3049 packet.str().c_str());
3050
3051 if (response.GetChar() != 'F')
3052 return Status::FromErrorStringWithFormat("invalid response to '%s' packet",
3053 packet.str().c_str());
3054
3055 return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
3056}
3057
3058Status
3060 uint32_t file_permissions) {
3061 std::string path{file_spec.GetPath(false)};
3063 stream.PutCString("qPlatform_chmod:");
3064 stream.PutHex32(file_permissions);
3065 stream.PutChar(',');
3066 stream.PutStringAsRawHex8(path);
3067 llvm::StringRef packet = stream.GetString();
3068 StringExtractorGDBRemote response;
3069
3070 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
3071 return Status::FromErrorStringWithFormat("failed to send '%s' packet",
3072 stream.GetData());
3073
3074 if (response.GetChar() != 'F')
3075 return Status::FromErrorStringWithFormat("invalid response to '%s' packet",
3076 stream.GetData());
3077
3078 return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
3079}
3080
3081static int gdb_errno_to_system(int err) {
3082 switch (err) {
3083#define HANDLE_ERRNO(name, value) \
3084 case GDB_##name: \
3085 return name;
3086#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3087 default:
3088 return -1;
3089 }
3090}
3091
3093 uint64_t fail_result, Status &error) {
3094 response.SetFilePos(0);
3095 if (response.GetChar() != 'F')
3096 return fail_result;
3097 int32_t result = response.GetS32(-2, 16);
3098 if (result == -2)
3099 return fail_result;
3100 if (response.GetChar() == ',') {
3101 int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3102 if (result_errno != -1)
3103 error = Status(result_errno, eErrorTypePOSIX);
3104 else
3106 } else
3107 error.Clear();
3108 return result;
3109}
3112 File::OpenOptions flags, mode_t mode,
3113 Status &error) {
3114 std::string path(file_spec.GetPath(false));
3116 stream.PutCString("vFile:open:");
3117 if (path.empty())
3118 return UINT64_MAX;
3119 stream.PutStringAsRawHex8(path);
3120 stream.PutChar(',');
3121 stream.PutHex32(flags);
3122 stream.PutChar(',');
3123 stream.PutHex32(mode);
3124 StringExtractorGDBRemote response;
3125 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3127 return ParseHostIOPacketResponse(response, UINT64_MAX, error);
3128 }
3129 return UINT64_MAX;
3130}
3131
3133 Status &error) {
3135 stream.Printf("vFile:close:%x", (int)fd);
3136 StringExtractorGDBRemote response;
3137 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3139 return ParseHostIOPacketResponse(response, -1, error) == 0;
3140 }
3141 return false;
3142}
3143
3144std::optional<GDBRemoteFStatData>
3147 stream.Printf("vFile:fstat:%" PRIx64, fd);
3148 StringExtractorGDBRemote response;
3149 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3151 if (response.GetChar() != 'F')
3152 return std::nullopt;
3153 int64_t size = response.GetS64(-1, 16);
3154 if (size > 0 && response.GetChar() == ';') {
3155 std::string buffer;
3156 if (response.GetEscapedBinaryData(buffer)) {
3158 if (buffer.size() != sizeof(out))
3159 return std::nullopt;
3160 memcpy(&out, buffer.data(), sizeof(out));
3161 return out;
3162 }
3163 }
3164 }
3165 return std::nullopt;
3166}
3167
3168std::optional<GDBRemoteFStatData>
3170 Status error;
3172 if (fd == UINT64_MAX)
3173 return std::nullopt;
3174 std::optional<GDBRemoteFStatData> st = FStat(fd);
3175 CloseFile(fd, error);
3176 return st;
3177}
3178
3179// Extension of host I/O packets to get the file size.
3181 const lldb_private::FileSpec &file_spec) {
3183 std::string path(file_spec.GetPath(false));
3185 stream.PutCString("vFile:size:");
3186 stream.PutStringAsRawHex8(path);
3187 StringExtractorGDBRemote response;
3188 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
3190 return UINT64_MAX;
3191
3192 if (!response.IsUnsupportedResponse()) {
3193 if (response.GetChar() != 'F')
3194 return UINT64_MAX;
3195 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
3196 return retcode;
3197 }
3198 m_supports_vFileSize = false;
3199 }
3200
3201 // Fallback to fstat.
3202 std::optional<GDBRemoteFStatData> st = Stat(file_spec);
3203 return st ? st->gdb_st_size : UINT64_MAX;
3204}
3205
3207 CompletionRequest &request, bool only_dir) {
3209 stream.PutCString("qPathComplete:");
3210 stream.PutHex32(only_dir ? 1 : 0);
3211 stream.PutChar(',');
3213 StringExtractorGDBRemote response;
3214 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3216 StreamString strm;
3217 char ch = response.GetChar();
3218 if (ch != 'M')
3219 return;
3220 while (response.Peek()) {
3221 strm.Clear();
3222 while ((ch = response.GetHexU8(0, false)) != '\0')
3223 strm.PutChar(ch);
3224 request.AddCompletion(strm.GetString());
3225 if (response.GetChar() != ',')
3226 break;
3227 }
3228 }
3229}
3230
3231Status
3233 uint32_t &file_permissions) {
3235 std::string path{file_spec.GetPath(false)};
3236 Status error;
3238 stream.PutCString("vFile:mode:");
3239 stream.PutStringAsRawHex8(path);
3240 StringExtractorGDBRemote response;
3241 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
3243 error = Status::FromErrorStringWithFormat("failed to send '%s' packet",
3244 stream.GetData());
3245 return error;
3246 }
3247 if (!response.IsUnsupportedResponse()) {
3248 if (response.GetChar() != 'F') {
3250 "invalid response to '%s' packet", stream.GetData());
3251 } else {
3252 const uint32_t mode = response.GetS32(-1, 16);
3253 if (static_cast<int32_t>(mode) == -1) {
3254 if (response.GetChar() == ',') {
3255 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3256 if (response_errno > 0)
3257 error = Status(response_errno, lldb::eErrorTypePOSIX);
3258 else
3259 error = Status::FromErrorString("unknown error");
3260 } else
3261 error = Status::FromErrorString("unknown error");
3262 } else {
3263 file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
3264 }
3265 }
3266 return error;
3267 } else { // response.IsUnsupportedResponse()
3268 m_supports_vFileMode = false;
3269 }
3270 }
3271
3272 // Fallback to fstat.
3273 if (std::optional<GDBRemoteFStatData> st = Stat(file_spec)) {
3274 file_permissions = st->gdb_st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
3275 return Status();
3276 }
3277 return Status::FromErrorString("fstat failed");
3278}
3279
3281 uint64_t offset, void *dst,
3282 uint64_t dst_len,
3283 Status &error) {
3285 stream.Printf("vFile:pread:%x,%" PRIx64 ",%" PRIx64, (int)fd, dst_len,
3286 offset);
3287 StringExtractorGDBRemote response;
3288 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3290 if (response.GetChar() != 'F')
3291 return 0;
3292 int64_t retcode = response.GetS64(-1, 16);
3293 if (retcode == -1) {
3294 error = Status::FromErrorString("unknown error");
3295 if (response.GetChar() == ',') {
3296 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3297 if (response_errno > 0)
3298 error = Status(response_errno, lldb::eErrorTypePOSIX);
3299 }
3300 return -1;
3301 }
3302 const char next = (response.Peek() ? *response.Peek() : 0);
3303 if (next == ',')
3304 return 0;
3305 if (next == ';') {
3306 response.GetChar(); // skip the semicolon
3307 std::string buffer;
3308 if (response.GetEscapedBinaryData(buffer)) {
3309 const uint64_t data_to_write =
3310 std::min<uint64_t>(dst_len, buffer.size());
3311 if (data_to_write > 0)
3312 memcpy(dst, &buffer[0], data_to_write);
3313 return data_to_write;
3314 }
3315 }
3316 }
3317 return 0;
3318}
3319
3321 uint64_t offset,
3322 const void *src,
3323 uint64_t src_len,
3324 Status &error) {
3326 stream.Printf("vFile:pwrite:%x,%" PRIx64 ",", (int)fd, offset);
3327 stream.PutEscapedBytes(src, src_len);
3328 StringExtractorGDBRemote response;
3329 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3331 if (response.GetChar() != 'F') {
3332 error = Status::FromErrorStringWithFormat("write file failed");
3333 return 0;
3334 }
3335 int64_t bytes_written = response.GetS64(-1, 16);
3336 if (bytes_written == -1) {
3337 error = Status::FromErrorString("unknown error");
3338 if (response.GetChar() == ',') {
3339 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3340 if (response_errno > 0)
3341 error = Status(response_errno, lldb::eErrorTypePOSIX);
3342 }
3343 return -1;
3344 }
3345 return bytes_written;
3346 } else {
3347 error = Status::FromErrorString("failed to send vFile:pwrite packet");
3348 }
3349 return 0;
3350}
3351
3353 const FileSpec &dst) {
3354 std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
3355 Status error;
3357 stream.PutCString("vFile:symlink:");
3358 // the unix symlink() command reverses its parameters where the dst if first,
3359 // so we follow suit here
3360 stream.PutStringAsRawHex8(dst_path);
3361 stream.PutChar(',');
3362 stream.PutStringAsRawHex8(src_path);
3363 StringExtractorGDBRemote response;
3364 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3366 if (response.GetChar() == 'F') {
3367 uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);
3368 if (result != 0) {
3369 error = Status::FromErrorString("unknown error");
3370 if (response.GetChar() == ',') {
3371 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3372 if (response_errno > 0)
3373 error = Status(response_errno, lldb::eErrorTypePOSIX);
3374 }
3375 }
3376 } else {
3377 // Should have returned with 'F<result>[,<errno>]'
3378 error = Status::FromErrorStringWithFormat("symlink failed");
3379 }
3380 } else {
3381 error = Status::FromErrorString("failed to send vFile:symlink packet");
3382 }
3383 return error;
3384}
3385
3387 std::string path{file_spec.GetPath(false)};
3388 Status error;
3390 stream.PutCString("vFile:unlink:");
3391 // the unix symlink() command reverses its parameters where the dst if first,
3392 // so we follow suit here
3393 stream.PutStringAsRawHex8(path);
3394 StringExtractorGDBRemote response;
3395 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3397 if (response.GetChar() == 'F') {
3398 uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);
3399 if (result != 0) {
3400 error = Status::FromErrorString("unknown error");
3401 if (response.GetChar() == ',') {
3402 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
3403 if (response_errno > 0)
3404 error = Status(response_errno, lldb::eErrorTypePOSIX);
3405 }
3406 }
3407 } else {
3408 // Should have returned with 'F<result>[,<errno>]'
3409 error = Status::FromErrorStringWithFormat("unlink failed");
3410 }
3411 } else {
3412 error = Status::FromErrorString("failed to send vFile:unlink packet");
3413 }
3414 return error;
3415}
3416
3417// Extension of host I/O packets to get whether a file exists.
3419 const lldb_private::FileSpec &file_spec) {
3421 std::string path(file_spec.GetPath(false));
3423 stream.PutCString("vFile:exists:");
3424 stream.PutStringAsRawHex8(path);
3425 StringExtractorGDBRemote response;
3426 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
3428 return false;
3429 if (!response.IsUnsupportedResponse()) {
3430 if (response.GetChar() != 'F')
3431 return false;
3432 if (response.GetChar() != ',')
3433 return false;
3434 bool retcode = (response.GetChar() != '0');
3435 return retcode;
3436 } else
3437 m_supports_vFileExists = false;
3438 }
3439
3440 // Fallback to open.
3441 Status error;
3443 if (fd == UINT64_MAX)
3444 return false;
3445 CloseFile(fd, error);
3446 return true;
3447}
3448
3449llvm::ErrorOr<llvm::MD5::MD5Result> GDBRemoteCommunicationClient::CalculateMD5(
3450 const lldb_private::FileSpec &file_spec) {
3451 std::string path(file_spec.GetPath(false));
3453 stream.PutCString("vFile:MD5:");
3454 stream.PutStringAsRawHex8(path);
3455 StringExtractorGDBRemote response;
3456 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3458 if (response.GetChar() != 'F')
3459 return std::make_error_code(std::errc::illegal_byte_sequence);
3460 if (response.GetChar() != ',')
3461 return std::make_error_code(std::errc::illegal_byte_sequence);
3462 if (response.Peek() && *response.Peek() == 'x')
3463 return std::make_error_code(std::errc::no_such_file_or_directory);
3464
3465 // GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 concatenates low and
3466 // high hex strings. We can't use response.GetHexMaxU64 because that can't
3467 // handle the concatenated hex string. What would happen is parsing the low
3468 // would consume the whole response packet which would give incorrect
3469 // results. Instead, we get the byte string for each low and high hex
3470 // separately, and parse them.
3471 //
3472 // An alternate way to handle this is to change the server to put a
3473 // delimiter between the low/high parts, and change the client to parse the
3474 // delimiter. However, we choose not to do this so existing lldb-servers
3475 // don't have to be patched
3476
3477 // The checksum is 128 bits encoded as hex
3478 // This means low/high are halves of 64 bits each, in otherwords, 8 bytes.
3479 // Each byte takes 2 hex characters in the response.
3480 const size_t MD5_HALF_LENGTH = sizeof(uint64_t) * 2;
3481
3482 // Get low part
3483 auto part =
3484 response.GetStringRef().substr(response.GetFilePos(), MD5_HALF_LENGTH);
3485 if (part.size() != MD5_HALF_LENGTH)
3486 return std::make_error_code(std::errc::illegal_byte_sequence);
3487 response.SetFilePos(response.GetFilePos() + part.size());
3488
3489 uint64_t low;
3490 if (part.getAsInteger(/*radix=*/16, low))
3491 return std::make_error_code(std::errc::illegal_byte_sequence);
3492
3493 // Get high part
3494 part =
3495 response.GetStringRef().substr(response.GetFilePos(), MD5_HALF_LENGTH);
3496 if (part.size() != MD5_HALF_LENGTH)
3497 return std::make_error_code(std::errc::illegal_byte_sequence);
3498 response.SetFilePos(response.GetFilePos() + part.size());
3499
3500 uint64_t high;
3501 if (part.getAsInteger(/*radix=*/16, high))
3502 return std::make_error_code(std::errc::illegal_byte_sequence);
3503
3504 llvm::MD5::MD5Result result;
3505 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3506 result.data(), low);
3507 llvm::support::endian::write<uint64_t, llvm::endianness::little>(
3508 result.data() + 8, high);
3509
3510 return result;
3511 }
3512 return std::make_error_code(std::errc::operation_canceled);
3513}
3514
3516 // Some targets have issues with g/G packets and we need to avoid using them
3518 if (process) {
3520 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3521 if (arch.IsValid() &&
3522 arch.GetTriple().getVendor() == llvm::Triple::Apple &&
3523 arch.GetTriple().getOS() == llvm::Triple::IOS &&
3524 (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
3525 arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3527 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3528 if (gdb_server_version != 0) {
3529 const char *gdb_server_name = GetGDBServerProgramName();
3530 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
3531 if (gdb_server_version >= 310)
3533 }
3534 }
3535 }
3536 }
3537 }
3539}
3540
3542 uint32_t reg) {
3543 StreamString payload;
3544 payload.Printf("p%x", reg);
3545 StringExtractorGDBRemote response;
3547 tid, std::move(payload), response) != PacketResult::Success ||
3548 !response.IsNormalResponse())
3549 return nullptr;
3550
3551 WritableDataBufferSP buffer_sp(
3552 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3553 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3554 return buffer_sp;
3555}
3556
3558 StreamString payload;
3559 payload.PutChar('g');
3560 StringExtractorGDBRemote response;
3562 tid, std::move(payload), response) != PacketResult::Success ||
3563 !response.IsNormalResponse())
3564 return nullptr;
3565
3566 WritableDataBufferSP buffer_sp(
3567 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3568 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3569 return buffer_sp;
3570}
3571
3573 uint32_t reg_num,
3574 llvm::ArrayRef<uint8_t> data) {
3575 StreamString payload;
3576 payload.Printf("P%x=", reg_num);
3577 payload.PutBytesAsRawHex8(data.data(), data.size(),
3580 StringExtractorGDBRemote response;
3582 tid, std::move(payload), response) == PacketResult::Success &&
3583 response.IsOKResponse();
3584}
3585
3587 lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
3588 StreamString payload;
3589 payload.PutChar('G');
3590 payload.PutBytesAsRawHex8(data.data(), data.size(),
3593 StringExtractorGDBRemote response;
3595 tid, std::move(payload), response) == PacketResult::Success &&
3596 response.IsOKResponse();
3597}
3598
3600 uint32_t &save_id) {
3601 save_id = 0; // Set to invalid save ID
3603 return false;
3604
3606 StreamString payload;
3607 payload.PutCString("QSaveRegisterState");
3608 StringExtractorGDBRemote response;
3610 tid, std::move(payload), response) != PacketResult::Success)
3611 return false;
3612
3613 if (response.IsUnsupportedResponse())
3615
3616 const uint32_t response_save_id = response.GetU32(0);
3617 if (response_save_id == 0)
3618 return false;
3619
3620 save_id = response_save_id;
3621 return true;
3622}
3623
3625 uint32_t save_id) {
3626 // We use the "m_supports_QSaveRegisterState" variable here because the
3627 // QSaveRegisterState and QRestoreRegisterState packets must both be
3628 // supported in order to be useful
3630 return false;
3631
3632 StreamString payload;
3633 payload.Printf("QRestoreRegisterState:%u", save_id);
3634 StringExtractorGDBRemote response;
3636 tid, std::move(payload), response) != PacketResult::Success)
3637 return false;
3638
3639 if (response.IsOKResponse())
3640 return true;
3641
3642 if (response.IsUnsupportedResponse())
3644 return false;
3645}
3646
3649 return false;
3650
3651 StreamString packet;
3652 StringExtractorGDBRemote response;
3653 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3654 return SendPacketAndWaitForResponse(packet.GetString(), response) ==
3656 response.IsOKResponse();
3657}
3658
3659llvm::Expected<TraceSupportedResponse>
3661 Log *log = GetLog(GDBRLog::Process);
3662
3663 StreamGDBRemote escaped_packet;
3664 escaped_packet.PutCString("jLLDBTraceSupported");
3665
3666 StringExtractorGDBRemote response;
3667 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3668 timeout) ==
3670 if (response.IsErrorResponse())
3671 return response.GetStatus().ToError();
3672 if (response.IsUnsupportedResponse())
3673 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3674 "jLLDBTraceSupported is unsupported");
3675
3676 return llvm::json::parse<TraceSupportedResponse>(response.Peek(),
3677 "TraceSupportedResponse");
3678 }
3679 LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported");
3680 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3681 "failed to send packet: jLLDBTraceSupported");
3682}
3683
3684llvm::Error
3686 std::chrono::seconds timeout) {
3687 Log *log = GetLog(GDBRLog::Process);
3688
3689 StreamGDBRemote escaped_packet;
3690 escaped_packet.PutCString("jLLDBTraceStop:");
3691
3692 std::string json_string;
3693 llvm::raw_string_ostream os(json_string);
3694 os << toJSON(request);
3695
3696 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3697
3698 StringExtractorGDBRemote response;
3699 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3700 timeout) ==
3702 if (response.IsErrorResponse())
3703 return response.GetStatus().ToError();
3704 if (response.IsUnsupportedResponse())
3705 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3706 "jLLDBTraceStop is unsupported");
3707 if (response.IsOKResponse())
3708 return llvm::Error::success();
3709 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3710 "Invalid jLLDBTraceStart response");
3711 }
3712 LLDB_LOG(log, "failed to send packet: jLLDBTraceStop");
3713 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3714 "failed to send packet: jLLDBTraceStop '%s'",
3715 escaped_packet.GetData());
3716}
3717
3718llvm::Error
3719GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value &params,
3720 std::chrono::seconds timeout) {
3721 Log *log = GetLog(GDBRLog::Process);
3722
3723 StreamGDBRemote escaped_packet;
3724 escaped_packet.PutCString("jLLDBTraceStart:");
3725
3726 std::string json_string;
3727 llvm::raw_string_ostream os(json_string);
3728 os << params;
3729
3730 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3731
3732 StringExtractorGDBRemote response;
3733 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3734 timeout) ==
3736 if (response.IsErrorResponse())
3737 return response.GetStatus().ToError();
3738 if (response.IsUnsupportedResponse())
3739 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3740 "jLLDBTraceStart is unsupported");
3741 if (response.IsOKResponse())
3742 return llvm::Error::success();
3743 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3744 "Invalid jLLDBTraceStart response");
3745 }
3746 LLDB_LOG(log, "failed to send packet: jLLDBTraceStart");
3747 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3748 "failed to send packet: jLLDBTraceStart '%s'",
3749 escaped_packet.GetData());
3750}
3751
3752llvm::Expected<std::string>
3754 std::chrono::seconds timeout) {
3755 Log *log = GetLog(GDBRLog::Process);
3756
3757 StreamGDBRemote escaped_packet;
3758 escaped_packet.PutCString("jLLDBTraceGetState:");
3759
3760 std::string json_string;
3761 llvm::raw_string_ostream os(json_string);
3762 os << toJSON(TraceGetStateRequest{type.str()});
3763
3764 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3765
3766 StringExtractorGDBRemote response;
3767 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3768 timeout) ==
3770 if (response.IsErrorResponse())
3771 return response.GetStatus().ToError();
3772 if (response.IsUnsupportedResponse())
3773 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3774 "jLLDBTraceGetState is unsupported");
3775 return std::string(response.Peek());
3776 }
3777
3778 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState");
3779 return llvm::createStringError(
3780 llvm::inconvertibleErrorCode(),
3781 "failed to send packet: jLLDBTraceGetState '%s'",
3782 escaped_packet.GetData());
3783}
3784
3785llvm::Expected<std::vector<uint8_t>>
3787 const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {
3788 Log *log = GetLog(GDBRLog::Process);
3789
3790 StreamGDBRemote escaped_packet;
3791 escaped_packet.PutCString("jLLDBTraceGetBinaryData:");
3792
3793 std::string json_string;
3794 llvm::raw_string_ostream os(json_string);
3795 os << toJSON(request);
3796
3797 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3798
3799 StringExtractorGDBRemote response;
3800 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3801 timeout) ==
3803 if (response.IsErrorResponse())
3804 return response.GetStatus().ToError();
3805 std::string data;
3806 response.GetEscapedBinaryData(data);
3807 return std::vector<uint8_t>(data.begin(), data.end());
3808 }
3809 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData");
3810 return llvm::createStringError(
3811 llvm::inconvertibleErrorCode(),
3812 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3813 escaped_packet.GetData());
3814}
3815
3817 StringExtractorGDBRemote response;
3818 if (SendPacketAndWaitForResponse("qOffsets", response) !=
3820 return std::nullopt;
3821 if (!response.IsNormalResponse())
3822 return std::nullopt;
3823
3824 QOffsets result;
3825 llvm::StringRef ref = response.GetStringRef();
3826 const auto &GetOffset = [&] {
3827 addr_t offset;
3828 if (ref.consumeInteger(16, offset))
3829 return false;
3830 result.offsets.push_back(offset);
3831 return true;
3832 };
3833
3834 if (ref.consume_front("Text=")) {
3835 result.segments = false;
3836 if (!GetOffset())
3837 return std::nullopt;
3838 if (!ref.consume_front(";Data=") || !GetOffset())
3839 return std::nullopt;
3840 if (ref.empty())
3841 return result;
3842 if (ref.consume_front(";Bss=") && GetOffset() && ref.empty())
3843 return result;
3844 } else if (ref.consume_front("TextSeg=")) {
3845 result.segments = true;
3846 if (!GetOffset())
3847 return std::nullopt;
3848 if (ref.empty())
3849 return result;
3850 if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty())
3851 return result;
3852 }
3853 return std::nullopt;
3854}
3855
3857 const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
3858 ModuleSpec &module_spec) {
3860 return false;
3861
3862 std::string module_path = module_file_spec.GetPath(false);
3863 if (module_path.empty())
3864 return false;
3865
3866 StreamString packet;
3867 packet.PutCString("qModuleInfo:");
3868 packet.PutStringAsRawHex8(module_path);
3869 packet.PutCString(";");
3870 const auto &triple = arch_spec.GetTriple().getTriple();
3871 packet.PutStringAsRawHex8(triple);
3872
3873 StringExtractorGDBRemote response;
3874 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
3876 return false;
3877
3878 if (response.IsErrorResponse())
3879 return false;
3880
3881 if (response.IsUnsupportedResponse()) {
3882 m_supports_qModuleInfo = false;
3883 return false;
3884 }
3885
3886 llvm::StringRef name;
3887 llvm::StringRef value;
3888
3889 module_spec.Clear();
3890 module_spec.GetFileSpec() = module_file_spec;
3891
3892 while (response.GetNameColonValue(name, value)) {
3893 if (name == "uuid" || name == "md5") {
3894 StringExtractor extractor(value);
3895 std::string uuid;
3896 extractor.GetHexByteString(uuid);
3897 module_spec.GetUUID().SetFromStringRef(uuid);
3898 } else if (name == "triple") {
3899 StringExtractor extractor(value);
3900 std::string triple;
3901 extractor.GetHexByteString(triple);
3902 module_spec.GetArchitecture().SetTriple(triple.c_str());
3903 } else if (name == "file_offset") {
3904 uint64_t ival = 0;
3905 if (!value.getAsInteger(16, ival))
3906 module_spec.SetObjectOffset(ival);
3907 } else if (name == "file_size") {
3908 uint64_t ival = 0;
3909 if (!value.getAsInteger(16, ival))
3910 module_spec.SetObjectSize(ival);
3911 } else if (name == "file_path") {
3912 StringExtractor extractor(value);
3913 std::string path;
3914 extractor.GetHexByteString(path);
3915 module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
3916 }
3917 }
3918
3919 return true;
3920}
3921
3922static std::optional<ModuleSpec>
3924 ModuleSpec result;
3925 if (!dict)
3926 return std::nullopt;
3927
3928 llvm::StringRef string;
3929 uint64_t integer;
3930
3931 if (!dict->GetValueForKeyAsString("uuid", string))
3932 return std::nullopt;
3933 if (!result.GetUUID().SetFromStringRef(string))
3934 return std::nullopt;
3935
3936 if (!dict->GetValueForKeyAsInteger("file_offset", integer))
3937 return std::nullopt;
3938 result.SetObjectOffset(integer);
3939
3940 if (!dict->GetValueForKeyAsInteger("file_size", integer))
3941 return std::nullopt;
3942 result.SetObjectSize(integer);
3943
3944 if (!dict->GetValueForKeyAsString("triple", string))
3945 return std::nullopt;
3946 result.GetArchitecture().SetTriple(string);
3947
3948 if (!dict->GetValueForKeyAsString("file_path", string))
3949 return std::nullopt;
3950 result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());
3951
3952 return result;
3953}
3954
3955std::optional<std::vector<ModuleSpec>>
3957 llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
3958 namespace json = llvm::json;
3959
3961 return std::nullopt;
3962
3963 json::Array module_array;
3964 for (const FileSpec &module_file_spec : module_file_specs) {
3965 module_array.push_back(
3966 json::Object{{"file", module_file_spec.GetPath(false)},
3967 {"triple", triple.getTriple()}});
3968 }
3969 StreamString unescaped_payload;
3970 unescaped_payload.PutCString("jModulesInfo:");
3971 unescaped_payload.AsRawOstream() << std::move(module_array);
3972
3973 StreamGDBRemote payload;
3974 payload.PutEscapedBytes(unescaped_payload.GetString().data(),
3975 unescaped_payload.GetSize());
3976
3977 // Increase the timeout for jModulesInfo since this packet can take longer.
3978 ScopedTimeout timeout(*this, std::chrono::seconds(10));
3979
3980 StringExtractorGDBRemote response;
3981 if (SendPacketAndWaitForResponse(payload.GetString(), response) !=
3983 response.IsErrorResponse())
3984 return std::nullopt;
3985
3986 if (response.IsUnsupportedResponse()) {
3988 return std::nullopt;
3989 }
3990
3991 StructuredData::ObjectSP response_object_sp =
3993 if (!response_object_sp)
3994 return std::nullopt;
3995
3996 StructuredData::Array *response_array = response_object_sp->GetAsArray();
3997 if (!response_array)
3998 return std::nullopt;
3999
4000 std::vector<ModuleSpec> result;
4001 for (size_t i = 0; i < response_array->GetSize(); ++i) {
4002 if (std::optional<ModuleSpec> module_spec = ParseModuleSpec(
4003 response_array->GetItemAtIndex(i)->GetAsDictionary()))
4004 result.push_back(*module_spec);
4005 }
4006
4007 return result;
4008}
4009
4010// query the target remote for extended information using the qXfer packet
4011//
4012// example: object='features', annex='target.xml'
4013// return: <xml output> or error
4014llvm::Expected<std::string>
4016 llvm::StringRef annex) {
4017
4018 std::string output;
4019 llvm::raw_string_ostream output_stream(output);
4021
4022 uint64_t size = GetRemoteMaxPacketSize();
4023 if (size == 0)
4024 size = 0x1000;
4025 size = size - 1; // Leave space for the 'm' or 'l' character in the response
4026 int offset = 0;
4027 bool active = true;
4028
4029 // loop until all data has been read
4030 while (active) {
4031
4032 // send query extended feature packet
4033 std::string packet =
4034 ("qXfer:" + object + ":read:" + annex + ":" +
4035 llvm::Twine::utohexstr(offset) + "," + llvm::Twine::utohexstr(size))
4036 .str();
4037
4039 SendPacketAndWaitForResponse(packet, chunk);
4040
4042 chunk.GetStringRef().empty()) {
4043 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4044 "Error sending $qXfer packet");
4045 }
4046
4047 // check packet code
4048 switch (chunk.GetStringRef()[0]) {
4049 // last chunk
4050 case ('l'):
4051 active = false;
4052 [[fallthrough]];
4053
4054 // more chunks
4055 case ('m'):
4056 output_stream << chunk.GetStringRef().drop_front();
4057 offset += chunk.GetStringRef().size() - 1;
4058 break;
4059
4060 // unknown chunk
4061 default:
4062 return llvm::createStringError(
4063 llvm::inconvertibleErrorCode(),
4064 "Invalid continuation code from $qXfer packet");
4065 }
4066 }
4067
4068 return output;
4069}
4070
4071// Notify the target that gdb is prepared to serve symbol lookup requests.
4072// packet: "qSymbol::"
4073// reply:
4074// OK The target does not need to look up any (more) symbols.
4075// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
4076// encoded).
4077// LLDB may provide the value by sending another qSymbol
4078// packet
4079// in the form of"qSymbol:<sym_value>:<sym_name>".
4080//
4081// Three examples:
4082//
4083// lldb sends: qSymbol::
4084// lldb receives: OK
4085// Remote gdb stub does not need to know the addresses of any symbols, lldb
4086// does not
4087// need to ask again in this session.
4088//
4089// lldb sends: qSymbol::
4090// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
4091// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
4092// lldb receives: OK
4093// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
4094// not know
4095// the address at this time. lldb needs to send qSymbol:: again when it has
4096// more
4097// solibs loaded.
4098//
4099// lldb sends: qSymbol::
4100// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
4101// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
4102// lldb receives: OK
4103// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
4104// that it
4105// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
4106// does not
4107// need any more symbols. lldb does not need to ask again in this session.
4108
4110 lldb_private::Process *process) {
4111 // Set to true once we've resolved a symbol to an address for the remote
4112 // stub. If we get an 'OK' response after this, the remote stub doesn't need
4113 // any more symbols and we can stop asking.
4114 bool symbol_response_provided = false;
4115
4116 // Is this the initial qSymbol:: packet?
4117 bool first_qsymbol_query = true;
4118
4120 Lock lock(*this);
4121 if (lock) {
4122 StreamString packet;
4123 packet.PutCString("qSymbol::");
4124 StringExtractorGDBRemote response;
4125 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
4127 if (response.IsOKResponse()) {
4128 if (symbol_response_provided || first_qsymbol_query) {
4130 }
4131
4132 // We are done serving symbols requests
4133 return;
4134 }
4135 first_qsymbol_query = false;
4136
4137 if (response.IsUnsupportedResponse()) {
4138 // qSymbol is not supported by the current GDB server we are
4139 // connected to
4140 m_supports_qSymbol = false;
4141 return;
4142 } else {
4143 llvm::StringRef response_str(response.GetStringRef());
4144 if (response_str.starts_with("qSymbol:")) {
4145 response.SetFilePos(strlen("qSymbol:"));
4146 std::string symbol_name;
4147 if (response.GetHexByteString(symbol_name)) {
4148 if (symbol_name.empty())
4149 return;
4150
4151 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
4154 ConstString(symbol_name), eSymbolTypeAny, sc_list);
4155 for (const SymbolContext &sc : sc_list) {
4156 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
4157 break;
4158 if (sc.symbol) {
4159 switch (sc.symbol->GetType()) {
4160 case eSymbolTypeInvalid:
4167 case eSymbolTypeBlock:
4168 case eSymbolTypeLocal:
4169 case eSymbolTypeParam:
4180 break;
4181
4182 case eSymbolTypeCode:
4184 case eSymbolTypeData:
4185 case eSymbolTypeRuntime:
4191 symbol_load_addr =
4192 sc.symbol->GetLoadAddress(&process->GetTarget());
4193 break;
4194 }
4195 }
4196 }
4197 // This is the normal path where our symbol lookup was successful
4198 // and we want to send a packet with the new symbol value and see
4199 // if another lookup needs to be done.
4200
4201 // Change "packet" to contain the requested symbol value and name
4202 packet.Clear();
4203 packet.PutCString("qSymbol:");
4204 if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
4205 packet.Printf("%" PRIx64, symbol_load_addr);
4206 symbol_response_provided = true;
4207 } else {
4208 symbol_response_provided = false;
4209 }
4210 packet.PutCString(":");
4211 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
4212 continue; // go back to the while loop and send "packet" and wait
4213 // for another response
4214 }
4215 }
4216 }
4217 }
4218 // If we make it here, the symbol request packet response wasn't valid or
4219 // our symbol lookup failed so we must abort
4220 return;
4221
4222 } else if (Log *log = GetLog(GDBRLog::Process | GDBRLog::Packets)) {
4223 LLDB_LOGF(log,
4224 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4225 __FUNCTION__);
4226 }
4227 }
4228}
4229
4233 // Query the server for the array of supported asynchronous JSON packets.
4235
4236 Log *log = GetLog(GDBRLog::Process);
4237
4238 // Poll it now.
4239 StringExtractorGDBRemote response;
4240 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) ==
4245 !m_supported_async_json_packets_sp->GetAsArray()) {
4246 // We were returned something other than a JSON array. This is
4247 // invalid. Clear it out.
4248 LLDB_LOGF(log,
4249 "GDBRemoteCommunicationClient::%s(): "
4250 "QSupportedAsyncJSONPackets returned invalid "
4251 "result: %s",
4252 __FUNCTION__, response.GetStringRef().data());
4254 }
4255 } else {
4256 LLDB_LOGF(log,
4257 "GDBRemoteCommunicationClient::%s(): "
4258 "QSupportedAsyncJSONPackets unsupported",
4259 __FUNCTION__);
4260 }
4261
4263 StreamString stream;
4265 LLDB_LOGF(log,
4266 "GDBRemoteCommunicationClient::%s(): supported async "
4267 "JSON packets: %s",
4268 __FUNCTION__, stream.GetData());
4269 }
4270 }
4271
4273 ? m_supported_async_json_packets_sp->GetAsArray()
4274 : nullptr;
4275}
4276
4278 llvm::ArrayRef<int32_t> signals) {
4279 // Format packet:
4280 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
4281 auto range = llvm::make_range(signals.begin(), signals.end());
4282 std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
4283
4284 StringExtractorGDBRemote response;
4285 auto send_status = SendPacketAndWaitForResponse(packet, response);
4286
4288 return Status::FromErrorString("Sending QPassSignals packet failed");
4289
4290 if (response.IsOKResponse()) {
4291 return Status();
4292 } else {
4294 "Unknown error happened during sending QPassSignals packet.");
4295 }
4296}
4297
4299 llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) {
4300 Status error;
4301
4302 if (type_name.empty()) {
4303 error = Status::FromErrorString("invalid type_name argument");
4304 return error;
4305 }
4306
4307 // Build command: Configure{type_name}: serialized config data.
4308 StreamGDBRemote stream;
4309 stream.PutCString("QConfigure");
4310 stream.PutCString(type_name);
4311 stream.PutChar(':');
4312 if (config_sp) {
4313 // Gather the plain-text version of the configuration data.
4314 StreamString unescaped_stream;
4315 config_sp->Dump(unescaped_stream);
4316 unescaped_stream.Flush();
4317
4318 // Add it to the stream in escaped fashion.
4319 stream.PutEscapedBytes(unescaped_stream.GetString().data(),
4320 unescaped_stream.GetSize());
4321 }
4322 stream.Flush();
4323
4324 // Send the packet.
4325 StringExtractorGDBRemote response;
4326 auto result = SendPacketAndWaitForResponse(stream.GetString(), response);
4327 if (result == PacketResult::Success) {
4328 // We failed if the config result comes back other than OK.
4329 if (response.GetStringRef() == "OK") {
4330 // Okay!
4331 error.Clear();
4332 } else {
4334 "configuring StructuredData feature {0} failed with error {1}",
4335 type_name, response.GetStringRef());
4336 }
4337 } else {
4338 // Can we get more data here on the failure?
4340 "configuring StructuredData feature {0} failed when sending packet: "
4341 "PacketResult={1}",
4342 type_name, (int)result);
4343 }
4344 return error;
4345}
4346
4351
4356 return true;
4357
4358 // If the remote didn't indicate native-signal support explicitly,
4359 // check whether it is an old version of lldb-server.
4360 return GetThreadSuffixSupported();
4361}
4362
4364 StringExtractorGDBRemote response;
4365 GDBRemoteCommunication::ScopedTimeout timeout(*this, seconds(3));
4366
4367 // LLDB server typically sends no response for "k", so we shouldn't try
4368 // to sync on timeout.
4369 if (SendPacketAndWaitForResponse("k", response, GetPacketTimeout(), false) !=
4371 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4372 "failed to send k packet");
4373
4374 char packet_cmd = response.GetChar(0);
4375 if (packet_cmd == 'W' || packet_cmd == 'X')
4376 return response.GetHexU8();
4377
4378 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4379 "unexpected response to k packet: %s",
4380 response.GetStringRef().str().c_str());
4381}
static llvm::raw_ostream & error(Stream &strm)
#define integer
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.
Definition Log.h:364
#define LLDB_LOGF(log,...)
Definition Log.h:378
static constexpr lldb::tid_t AllThreads
size_t GetEscapedBinaryData(std::string &str)
static constexpr lldb::pid_t AllProcesses
std::optional< std::pair< lldb::pid_t, lldb::tid_t > > GetPidTid(lldb::pid_t default_pid)
void SetFilePos(uint32_t idx)
int64_t GetS64(int64_t fail_value, int base=0)
uint32_t GetHexMaxU32(bool little_endian, uint32_t fail_value)
uint64_t GetHexMaxU64(bool little_endian, uint64_t fail_value)
bool GetNameColonValue(llvm::StringRef &name, llvm::StringRef &value)
uint64_t GetU64(uint64_t fail_value, int base=0)
size_t GetHexBytesAvail(llvm::MutableArrayRef< uint8_t > dest)
size_t GetHexByteString(std::string &str)
uint8_t GetHexU8(uint8_t fail_value=0, bool set_eof_on_fail=true)
char GetChar(char fail_value='\0')
const char * Peek()
int32_t GetS32(int32_t fail_value, int base=0)
size_t GetHexBytes(llvm::MutableArrayRef< uint8_t > dest, uint8_t fail_fill_value)
uint64_t GetFilePos() const
llvm::StringRef GetStringRef() const
uint32_t GetU32(uint32_t fail_value, int base=0)
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.
Definition ArchSpec.h:32
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:370
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:460
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition ArchSpec.cpp:748
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.
Definition ArchSpec.cpp:852
A command line argument class.
Definition Args.h:33
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
Definition Args.cpp:332
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
void Clear()
Clear the arguments.
Definition Args.cpp:388
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.
Definition ConstString.h:40
A subclass of DataBuffer that stores a data buffer on the heap.
A file utility class.
Definition FileSpec.h:57
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
MemoryRegionInfo & SetMemoryTagged(LazyBool val)
void SetBlocksize(lldb::offset_t blocksize)
void SetName(const char *name)
MemoryRegionInfo & SetIsShadowStack(LazyBool val)
lldb::offset_t GetBlocksize() const
void SetDirtyPageList(std::vector< lldb::addr_t > pagelist)
MemoryRegionInfo & SetProtectionKey(std::optional< unsigned > key)
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
void SetObjectSize(uint64_t object_size)
Definition ModuleSpec.h:119
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
void SetObjectOffset(uint64_t object_offset)
Definition ModuleSpec.h:113
void SetGroupID(uint32_t gid)
Definition ProcessInfo.h:60
bool ProcessIDIsValid() const
Definition ProcessInfo.h:72
void SetArg0(llvm::StringRef arg)
const char * GetName() const
lldb::pid_t GetProcessID() const
Definition ProcessInfo.h:68
void SetProcessID(lldb::pid_t pid)
Definition ProcessInfo.h:70
FileSpec & GetExecutableFile()
Definition ProcessInfo.h:43
uint32_t GetUserID() const
Definition ProcessInfo.h:50
uint32_t GetGroupID() const
Definition ProcessInfo.h:52
void SetUserID(uint32_t uid)
Definition ProcessInfo.h:58
bool GroupIDIsValid() const
Definition ProcessInfo.h:56
ArchSpec & GetArchitecture()
Definition ProcessInfo.h:62
ProcessInstanceInfo & GetProcessInfo()
void SetEffectiveGroupID(uint32_t gid)
lldb::pid_t GetParentProcessID() const
void SetParentProcessID(lldb::pid_t pid)
void SetEffectiveUserID(uint32_t uid)
A plug-in interface definition class for debugging a process.
Definition Process.h:357
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1256
An error handling class.
Definition Status.h:118
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
Definition Status.cpp:138
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
bool Success() const
Test for success condition.
Definition Status.cpp:303
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
Definition GDBRemote.cpp:31
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.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:405
size_t PutStringAsRawHex8(llvm::StringRef s)
Definition Stream.cpp:418
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:307
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
size_t PutChar(char ch)
Definition Stream.cpp:131
size_t PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:291
virtual void Flush()=0
Flush the stream.
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:391
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.
Definition Target.h:1241
const ArchSpec & GetArchitecture() const
Definition Target.h:1283
Represents UUID's of various sizes.
Definition UUID.h:27
bool SetFromStringRef(llvm::StringRef str)
Definition UUID.cpp:101
static bool XMLEnabled()
Definition XML.cpp:83
XMLNode GetRootElement(const char *required_name=nullptr)
Definition XML.cpp:65
bool ParseMemory(const char *xml, size_t xml_length, const char *url="untitled.xml")
Definition XML.cpp:54
void ForEachChildElement(NodeCallback const &callback) const
Definition XML.cpp:169
llvm::StringRef GetName() const
Definition XML.cpp:268
std::string GetAttributeValue(const char *name, const char *fail_value=nullptr) const
Definition XML.cpp:135
bool GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value=0, int base=0) const
Definition XML.cpp:299
bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value, uint64_t fail_value=0, int base=0) const
Definition XML.cpp:156
bool IsElement() const
Definition XML.cpp:345
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)
lldb::DataBufferSP ReadRegister(lldb::tid_t tid, uint32_t reg_num)
PacketResult SendThreadSpecificPacketAndWaitForResponse(lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response)
bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
lldb_private::StructuredData::Array * GetSupportedStructuredDataPlugins()
Return the array of async JSON packet types supported by the remote.
lldb::tid_t m_curr_tid_run
Current gdb remote protocol thread identifier for continue, step, etc.
int SendLaunchEventDataPacket(const char *data, bool *was_supported=nullptr)
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)
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)
llvm::Error SendTraceStop(const TraceStopRequest &request, std::chrono::seconds interrupt_timeout)
void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm)
bool LaunchGDBServer(const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port, std::string &socket_name)
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)
uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error)
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)
std::optional< GDBRemoteFStatData > FStat(lldb::user_id_t fd)
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)
llvm::Expected< std::string > SendTraceGetState(llvm::StringRef type, std::chrono::seconds interrupt_timeout)
llvm::Error LaunchProcess(const Args &args)
Launch the process using the provided arguments.
Status ConfigureRemoteStructuredData(llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp)
Configure a StructuredData feature on the remote end.
uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error)
bool SetCurrentThread(uint64_t tid, lldb::pid_t pid=LLDB_INVALID_PROCESS_ID)
lldb::tid_t m_curr_tid
Current gdb remote protocol thread identifier for all other operations.
bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef< uint8_t > data)
bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info)
Status SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
Status GetQXferMemoryMapRegionInfo(lldb::addr_t addr, MemoryRegionInfo &region)
int SetDetachOnError(bool enable)
Sets the DetachOnError flag to enable for the process controlled by the stub.
LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr)
bool WriteRegister(lldb::tid_t tid, uint32_t reg_num, llvm::ArrayRef< uint8_t > data)
llvm::Expected< std::vector< uint8_t > > SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request, std::chrono::seconds interrupt_timeout)
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.
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)
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)
int SetDisableASLR(bool enable)
Sets the disable ASLR flag to enable for a process that will be launched with the 'A' packet.
Status GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info)
int SendStdinNotification(const char *data, size_t data_len)
Sends a GDB remote protocol 'I' packet that delivers stdin data to the remote process.
void AutoCompleteDiskFileOrDirectory(CompletionRequest &request, bool only_dir)
lldb::pid_t m_curr_pid_run
Current gdb remote protocol process identifier for continue, step, etc.
void MaybeEnableCompression(llvm::ArrayRef< llvm::StringRef > supported_compressions)
llvm::Expected< TraceSupportedResponse > SendTraceSupported(std::chrono::seconds interrupt_timeout)
llvm::ErrorOr< llvm::MD5::MD5Result > CalculateMD5(const FileSpec &file_spec)
llvm::Error SendTraceStart(const llvm::json::Value &request, std::chrono::seconds interrupt_timeout)
bool GetModuleInfo(const FileSpec &module_file_spec, const ArchSpec &arch_spec, ModuleSpec &module_spec)
std::optional< PidTid > SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid, char op)
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)
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...
std::vector< std::pair< lldb::pid_t, lldb::tid_t > > GetCurrentProcessAndThreadIDs(bool &sequence_mutex_unavailable)
bool GetThreadStopInfo(lldb::tid_t tid, StringExtractorGDBRemote &response)
bool GetProcessStandaloneBinary(UUID &uuid, lldb::addr_t &value, bool &value_is_offset)
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)
#define UINT64_MAX
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_CPUTYPE
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
#define LLDB_INVALID_PROCESS_ID
lldb::ByteOrder InlHostByteOrder()
Definition Endian.h:25
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.
Definition Log.h:327
llvm::json::Value toJSON(const SymbolValue &data)
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
Definition Host.h:32
@ eErrorTypeGeneric
Generic errors that can be any value.
@ eErrorTypePOSIX
POSIX error codes.
@ eSymbolTypeUndefined
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeReExported
@ eSymbolTypeObjCClass
@ eSymbolTypeObjectFile
@ eSymbolTypeTrampoline
@ eSymbolTypeResolver
@ eSymbolTypeSourceFile
@ eSymbolTypeException
@ eSymbolTypeVariable
@ eSymbolTypeAbsolute
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
@ eSymbolTypeHeaderFile
@ eSymbolTypeCommonBlock
@ eSymbolTypeCompiler
@ eSymbolTypeLineHeader
@ eSymbolTypeObjCIVar
@ eSymbolTypeLineEntry
@ eSymbolTypeScopeBegin
@ eSymbolTypeScopeEnd
uint64_t pid_t
Definition lldb-types.h:83
ByteOrder
Byte ordering definitions.
uint64_t user_id_t
Definition lldb-types.h:82
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
uint64_t tid_t
Definition lldb-types.h:84
bool Contains(BaseType r) const
Definition RangeMap.h:93
BaseType GetRangeBase() const
Definition RangeMap.h:45
bool IsValid() const
Definition RangeMap.h:91
void SetRangeEnd(BaseType end)
Definition RangeMap.h:80
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
Definition RangeMap.h:48
BaseType GetRangeEnd() const
Definition RangeMap.h:78
void SetByteSize(SizeType s)
Definition RangeMap.h:89
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.
#define S_IRWXG
#define S_IRWXO
#define S_IRWXU