1 //===-- GDBRemoteCommunicationClient.cpp ----------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "GDBRemoteCommunicationClient.h"
18 #include "lldb/Core/ModuleSpec.h"
19 #include "lldb/Host/HostInfo.h"
20 #include "lldb/Host/SafeMachO.h"
21 #include "lldb/Host/XML.h"
22 #include "lldb/Symbol/Symbol.h"
23 #include "lldb/Target/MemoryRegionInfo.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/UnixSignals.h"
26 #include "lldb/Utility/Args.h"
27 #include "lldb/Utility/DataBufferHeap.h"
28 #include "lldb/Utility/LLDBAssert.h"
29 #include "lldb/Utility/LLDBLog.h"
30 #include "lldb/Utility/Log.h"
31 #include "lldb/Utility/State.h"
32 #include "lldb/Utility/StreamString.h"
34 #include "ProcessGDBRemote.h"
35 #include "ProcessGDBRemoteLog.h"
36 #include "lldb/Host/Config.h"
37 #include "lldb/Utility/StringExtractorGDBRemote.h"
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"
44 #if defined(HAVE_LIBCOMPRESSION)
45 #include <compression.h>
49 using namespace lldb_private::process_gdb_remote
;
50 using namespace lldb_private
;
51 using namespace std::chrono
;
53 llvm::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()));
60 // GDBRemoteCommunicationClient constructor
61 GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
62 : GDBRemoteClientBase("gdb-remote.client"),
64 m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
65 m_supports_qUserName(true), m_supports_qGroupName(true),
66 m_supports_qThreadStopInfo(true), m_supports_z0(true),
67 m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
68 m_supports_z4(true), m_supports_QEnvironment(true),
69 m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
70 m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
71 m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
72 m_supports_vFileSize(true), m_supports_vFileMode(true),
73 m_supports_vFileExists(true), m_supports_vRun(true),
75 m_host_arch(), m_host_distribution_id(), m_process_arch(), m_os_build(),
76 m_os_kernel(), m_hostname(), m_gdb_server_name(),
77 m_default_packet_timeout(0), m_qSupported_response(),
78 m_supported_async_json_packets_sp(), m_qXfer_memory_map() {}
81 GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
86 bool GDBRemoteCommunicationClient::HandshakeWithServer(Status
*error_ptr
) {
87 ResetDiscoverableSettings(false);
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();
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...
98 if (QueryNoAckModeSupported()) {
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
)
109 Status::FromErrorString("Connection shut down by remote side "
110 "while waiting for reply to initial "
113 *error_ptr
= Status::FromErrorStringWithFormat(
114 "failed to get reply to handshake packet within timeout of "
121 *error_ptr
= Status::FromErrorString("failed to send the handshake ack");
126 bool GDBRemoteCommunicationClient::GetEchoSupported() {
127 if (m_supports_qEcho
== eLazyBoolCalculate
) {
128 GetRemoteQSupported();
130 return m_supports_qEcho
== eLazyBoolYes
;
133 bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
134 if (m_supports_QPassSignals
== eLazyBoolCalculate
) {
135 GetRemoteQSupported();
137 return m_supports_QPassSignals
== eLazyBoolYes
;
140 bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
141 if (m_supports_augmented_libraries_svr4_read
== eLazyBoolCalculate
) {
142 GetRemoteQSupported();
144 return m_supports_augmented_libraries_svr4_read
== eLazyBoolYes
;
147 bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
148 if (m_supports_qXfer_libraries_svr4_read
== eLazyBoolCalculate
) {
149 GetRemoteQSupported();
151 return m_supports_qXfer_libraries_svr4_read
== eLazyBoolYes
;
154 bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
155 if (m_supports_qXfer_libraries_read
== eLazyBoolCalculate
) {
156 GetRemoteQSupported();
158 return m_supports_qXfer_libraries_read
== eLazyBoolYes
;
161 bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
162 if (m_supports_qXfer_auxv_read
== eLazyBoolCalculate
) {
163 GetRemoteQSupported();
165 return m_supports_qXfer_auxv_read
== eLazyBoolYes
;
168 bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
169 if (m_supports_qXfer_features_read
== eLazyBoolCalculate
) {
170 GetRemoteQSupported();
172 return m_supports_qXfer_features_read
== eLazyBoolYes
;
175 bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
176 if (m_supports_qXfer_memory_map_read
== eLazyBoolCalculate
) {
177 GetRemoteQSupported();
179 return m_supports_qXfer_memory_map_read
== eLazyBoolYes
;
182 bool GDBRemoteCommunicationClient::GetQXferSigInfoReadSupported() {
183 if (m_supports_qXfer_siginfo_read
== eLazyBoolCalculate
) {
184 GetRemoteQSupported();
186 return m_supports_qXfer_siginfo_read
== eLazyBoolYes
;
189 bool GDBRemoteCommunicationClient::GetMultiprocessSupported() {
190 if (m_supports_memory_tagging
== eLazyBoolCalculate
)
191 GetRemoteQSupported();
192 return m_supports_multiprocess
== eLazyBoolYes
;
195 uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
196 if (m_max_packet_size
== 0) {
197 GetRemoteQSupported();
199 return m_max_packet_size
;
202 bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
203 if (m_supports_not_sending_acks
== eLazyBoolCalculate
) {
205 m_supports_not_sending_acks
= eLazyBoolNo
;
207 // This is the first real packet that we'll send in a debug session and it
208 // may take a little longer than normal to receive a reply. Wait at least
209 // 6 seconds for a reply to this packet.
211 ScopedTimeout
timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
213 StringExtractorGDBRemote response
;
214 if (SendPacketAndWaitForResponse("QStartNoAckMode", response
) ==
215 PacketResult::Success
) {
216 if (response
.IsOKResponse()) {
218 m_supports_not_sending_acks
= eLazyBoolYes
;
226 void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
227 if (m_supports_threads_in_stop_reply
== eLazyBoolCalculate
) {
228 m_supports_threads_in_stop_reply
= eLazyBoolNo
;
230 StringExtractorGDBRemote response
;
231 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response
) ==
232 PacketResult::Success
) {
233 if (response
.IsOKResponse())
234 m_supports_threads_in_stop_reply
= eLazyBoolYes
;
239 bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
240 if (m_attach_or_wait_reply
== eLazyBoolCalculate
) {
241 m_attach_or_wait_reply
= eLazyBoolNo
;
243 StringExtractorGDBRemote response
;
244 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response
) ==
245 PacketResult::Success
) {
246 if (response
.IsOKResponse())
247 m_attach_or_wait_reply
= eLazyBoolYes
;
250 return m_attach_or_wait_reply
== eLazyBoolYes
;
253 bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
254 if (m_prepare_for_reg_writing_reply
== eLazyBoolCalculate
) {
255 m_prepare_for_reg_writing_reply
= eLazyBoolNo
;
257 StringExtractorGDBRemote response
;
258 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response
) ==
259 PacketResult::Success
) {
260 if (response
.IsOKResponse())
261 m_prepare_for_reg_writing_reply
= eLazyBoolYes
;
264 return m_prepare_for_reg_writing_reply
== eLazyBoolYes
;
267 void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec
) {
269 // Hard reset everything, this is when we first connect to a GDB server
270 m_supports_not_sending_acks
= eLazyBoolCalculate
;
271 m_supports_thread_suffix
= eLazyBoolCalculate
;
272 m_supports_threads_in_stop_reply
= eLazyBoolCalculate
;
273 m_supports_vCont_c
= eLazyBoolCalculate
;
274 m_supports_vCont_C
= eLazyBoolCalculate
;
275 m_supports_vCont_s
= eLazyBoolCalculate
;
276 m_supports_vCont_S
= eLazyBoolCalculate
;
277 m_supports_p
= eLazyBoolCalculate
;
278 m_supports_x
= eLazyBoolCalculate
;
279 m_supports_QSaveRegisterState
= eLazyBoolCalculate
;
280 m_qHostInfo_is_valid
= eLazyBoolCalculate
;
281 m_curr_pid_is_valid
= eLazyBoolCalculate
;
282 m_qGDBServerVersion_is_valid
= eLazyBoolCalculate
;
283 m_supports_alloc_dealloc_memory
= eLazyBoolCalculate
;
284 m_supports_memory_region_info
= eLazyBoolCalculate
;
285 m_prepare_for_reg_writing_reply
= eLazyBoolCalculate
;
286 m_attach_or_wait_reply
= eLazyBoolCalculate
;
287 m_avoid_g_packets
= eLazyBoolCalculate
;
288 m_supports_multiprocess
= eLazyBoolCalculate
;
289 m_supports_qSaveCore
= eLazyBoolCalculate
;
290 m_supports_qXfer_auxv_read
= eLazyBoolCalculate
;
291 m_supports_qXfer_libraries_read
= eLazyBoolCalculate
;
292 m_supports_qXfer_libraries_svr4_read
= eLazyBoolCalculate
;
293 m_supports_qXfer_features_read
= eLazyBoolCalculate
;
294 m_supports_qXfer_memory_map_read
= eLazyBoolCalculate
;
295 m_supports_qXfer_siginfo_read
= eLazyBoolCalculate
;
296 m_supports_augmented_libraries_svr4_read
= eLazyBoolCalculate
;
297 m_uses_native_signals
= eLazyBoolCalculate
;
298 m_supports_qProcessInfoPID
= true;
299 m_supports_qfProcessInfo
= true;
300 m_supports_qUserName
= true;
301 m_supports_qGroupName
= true;
302 m_supports_qThreadStopInfo
= true;
303 m_supports_z0
= true;
304 m_supports_z1
= true;
305 m_supports_z2
= true;
306 m_supports_z3
= true;
307 m_supports_z4
= true;
308 m_supports_QEnvironment
= true;
309 m_supports_QEnvironmentHexEncoded
= true;
310 m_supports_qSymbol
= true;
311 m_qSymbol_requests_done
= false;
312 m_supports_qModuleInfo
= true;
314 m_host_distribution_id
.clear();
315 m_os_version
= llvm::VersionTuple();
319 m_gdb_server_name
.clear();
320 m_gdb_server_version
= UINT32_MAX
;
321 m_default_packet_timeout
= seconds(0);
322 m_target_vm_page_size
= 0;
323 m_max_packet_size
= 0;
324 m_qSupported_response
.clear();
325 m_supported_async_json_packets_is_valid
= false;
326 m_supported_async_json_packets_sp
.reset();
327 m_supports_jModulesInfo
= true;
330 // These flags should be reset when we first connect to a GDB server and when
331 // our inferior process execs
332 m_qProcessInfo_is_valid
= eLazyBoolCalculate
;
333 m_process_arch
.Clear();
336 void GDBRemoteCommunicationClient::GetRemoteQSupported() {
337 // Clear out any capabilities we expect to see in the qSupported response
338 m_supports_qXfer_auxv_read
= eLazyBoolNo
;
339 m_supports_qXfer_libraries_read
= eLazyBoolNo
;
340 m_supports_qXfer_libraries_svr4_read
= eLazyBoolNo
;
341 m_supports_augmented_libraries_svr4_read
= eLazyBoolNo
;
342 m_supports_qXfer_features_read
= eLazyBoolNo
;
343 m_supports_qXfer_memory_map_read
= eLazyBoolNo
;
344 m_supports_qXfer_siginfo_read
= eLazyBoolNo
;
345 m_supports_multiprocess
= eLazyBoolNo
;
346 m_supports_qEcho
= eLazyBoolNo
;
347 m_supports_QPassSignals
= eLazyBoolNo
;
348 m_supports_memory_tagging
= eLazyBoolNo
;
349 m_supports_qSaveCore
= eLazyBoolNo
;
350 m_uses_native_signals
= eLazyBoolNo
;
352 m_max_packet_size
= UINT64_MAX
; // It's supposed to always be there, but if
353 // not, we assume no limit
355 // build the qSupported packet
356 std::vector
<std::string
> features
= {"xmlRegisters=i386,arm,mips,arc",
363 packet
.PutCString("qSupported");
364 for (uint32_t i
= 0; i
< features
.size(); ++i
) {
365 packet
.PutCString(i
== 0 ? ":" : ";");
366 packet
.PutCString(features
[i
]);
369 StringExtractorGDBRemote response
;
370 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
371 PacketResult::Success
) {
372 // Hang on to the qSupported packet, so that platforms can do custom
373 // configuration of the transport before attaching/launching the process.
374 m_qSupported_response
= response
.GetStringRef().str();
376 for (llvm::StringRef x
: llvm::split(response
.GetStringRef(), ';')) {
377 if (x
== "qXfer:auxv:read+")
378 m_supports_qXfer_auxv_read
= eLazyBoolYes
;
379 else if (x
== "qXfer:libraries-svr4:read+")
380 m_supports_qXfer_libraries_svr4_read
= eLazyBoolYes
;
381 else if (x
== "augmented-libraries-svr4-read") {
382 m_supports_qXfer_libraries_svr4_read
= eLazyBoolYes
; // implied
383 m_supports_augmented_libraries_svr4_read
= eLazyBoolYes
;
384 } else if (x
== "qXfer:libraries:read+")
385 m_supports_qXfer_libraries_read
= eLazyBoolYes
;
386 else if (x
== "qXfer:features:read+")
387 m_supports_qXfer_features_read
= eLazyBoolYes
;
388 else if (x
== "qXfer:memory-map:read+")
389 m_supports_qXfer_memory_map_read
= eLazyBoolYes
;
390 else if (x
== "qXfer:siginfo:read+")
391 m_supports_qXfer_siginfo_read
= eLazyBoolYes
;
392 else if (x
== "qEcho")
393 m_supports_qEcho
= eLazyBoolYes
;
394 else if (x
== "QPassSignals+")
395 m_supports_QPassSignals
= eLazyBoolYes
;
396 else if (x
== "multiprocess+")
397 m_supports_multiprocess
= eLazyBoolYes
;
398 else if (x
== "memory-tagging+")
399 m_supports_memory_tagging
= eLazyBoolYes
;
400 else if (x
== "qSaveCore+")
401 m_supports_qSaveCore
= eLazyBoolYes
;
402 else if (x
== "native-signals+")
403 m_uses_native_signals
= eLazyBoolYes
;
404 // Look for a list of compressions in the features list e.g.
405 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
407 else if (x
.consume_front("SupportedCompressions=")) {
408 llvm::SmallVector
<llvm::StringRef
, 4> compressions
;
409 x
.split(compressions
, ',');
410 if (!compressions
.empty())
411 MaybeEnableCompression(compressions
);
412 } else if (x
.consume_front("SupportedWatchpointTypes=")) {
413 llvm::SmallVector
<llvm::StringRef
, 4> watchpoint_types
;
414 x
.split(watchpoint_types
, ',');
415 m_watchpoint_types
= eWatchpointHardwareFeatureUnknown
;
416 for (auto wp_type
: watchpoint_types
) {
417 if (wp_type
== "x86_64")
418 m_watchpoint_types
|= eWatchpointHardwareX86
;
419 if (wp_type
== "aarch64-mask")
420 m_watchpoint_types
|= eWatchpointHardwareArmMASK
;
421 if (wp_type
== "aarch64-bas")
422 m_watchpoint_types
|= eWatchpointHardwareArmBAS
;
424 } else if (x
.consume_front("PacketSize=")) {
425 StringExtractorGDBRemote
packet_response(x
);
427 packet_response
.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX
);
428 if (m_max_packet_size
== 0) {
429 m_max_packet_size
= UINT64_MAX
; // Must have been a garbled response
430 Log
*log(GetLog(GDBRLog::Process
));
431 LLDB_LOGF(log
, "Garbled PacketSize spec in qSupported response");
438 bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
439 if (m_supports_thread_suffix
== eLazyBoolCalculate
) {
440 StringExtractorGDBRemote response
;
441 m_supports_thread_suffix
= eLazyBoolNo
;
442 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response
) ==
443 PacketResult::Success
) {
444 if (response
.IsOKResponse())
445 m_supports_thread_suffix
= eLazyBoolYes
;
448 return m_supports_thread_suffix
;
450 bool GDBRemoteCommunicationClient::GetVContSupported(char flavor
) {
451 if (m_supports_vCont_c
== eLazyBoolCalculate
) {
452 StringExtractorGDBRemote response
;
453 m_supports_vCont_any
= eLazyBoolNo
;
454 m_supports_vCont_all
= eLazyBoolNo
;
455 m_supports_vCont_c
= eLazyBoolNo
;
456 m_supports_vCont_C
= eLazyBoolNo
;
457 m_supports_vCont_s
= eLazyBoolNo
;
458 m_supports_vCont_S
= eLazyBoolNo
;
459 if (SendPacketAndWaitForResponse("vCont?", response
) ==
460 PacketResult::Success
) {
461 const char *response_cstr
= response
.GetStringRef().data();
462 if (::strstr(response_cstr
, ";c"))
463 m_supports_vCont_c
= eLazyBoolYes
;
465 if (::strstr(response_cstr
, ";C"))
466 m_supports_vCont_C
= eLazyBoolYes
;
468 if (::strstr(response_cstr
, ";s"))
469 m_supports_vCont_s
= eLazyBoolYes
;
471 if (::strstr(response_cstr
, ";S"))
472 m_supports_vCont_S
= eLazyBoolYes
;
474 if (m_supports_vCont_c
== eLazyBoolYes
&&
475 m_supports_vCont_C
== eLazyBoolYes
&&
476 m_supports_vCont_s
== eLazyBoolYes
&&
477 m_supports_vCont_S
== eLazyBoolYes
) {
478 m_supports_vCont_all
= eLazyBoolYes
;
481 if (m_supports_vCont_c
== eLazyBoolYes
||
482 m_supports_vCont_C
== eLazyBoolYes
||
483 m_supports_vCont_s
== eLazyBoolYes
||
484 m_supports_vCont_S
== eLazyBoolYes
) {
485 m_supports_vCont_any
= eLazyBoolYes
;
492 return m_supports_vCont_any
;
494 return m_supports_vCont_all
;
496 return m_supports_vCont_c
;
498 return m_supports_vCont_C
;
500 return m_supports_vCont_s
;
502 return m_supports_vCont_S
;
509 GDBRemoteCommunication::PacketResult
510 GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
511 lldb::tid_t tid
, StreamString
&&payload
,
512 StringExtractorGDBRemote
&response
) {
515 if (Log
*log
= GetLog(GDBRLog::Process
| GDBRLog::Packets
))
517 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
519 __FUNCTION__
, payload
.GetData());
520 return PacketResult::ErrorNoSequenceLock
;
523 if (GetThreadSuffixSupported())
524 payload
.Printf(";thread:%4.4" PRIx64
";", tid
);
526 if (!SetCurrentThread(tid
))
527 return PacketResult::ErrorSendFailed
;
530 return SendPacketAndWaitForResponseNoLock(payload
.GetString(), response
);
533 // Check if the target supports 'p' packet. It sends out a 'p' packet and
534 // checks the response. A normal packet will tell us that support is available.
536 // Takes a valid thread ID because p needs to apply to a thread.
537 bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid
) {
538 if (m_supports_p
== eLazyBoolCalculate
)
539 m_supports_p
= GetThreadPacketSupported(tid
, "p0");
543 LazyBool
GDBRemoteCommunicationClient::GetThreadPacketSupported(
544 lldb::tid_t tid
, llvm::StringRef packetStr
) {
545 StreamString payload
;
546 payload
.PutCString(packetStr
);
547 StringExtractorGDBRemote response
;
548 if (SendThreadSpecificPacketAndWaitForResponse(
549 tid
, std::move(payload
), response
) == PacketResult::Success
&&
550 response
.IsNormalResponse()) {
556 bool GDBRemoteCommunicationClient::GetSaveCoreSupported() const {
557 return m_supports_qSaveCore
== eLazyBoolYes
;
560 StructuredData::ObjectSP
GDBRemoteCommunicationClient::GetThreadsInfo() {
561 // Get information on all threads at one using the "jThreadsInfo" packet
562 StructuredData::ObjectSP object_sp
;
564 if (m_supports_jThreadsInfo
) {
565 StringExtractorGDBRemote response
;
566 response
.SetResponseValidatorToJSON();
567 if (SendPacketAndWaitForResponse("jThreadsInfo", response
) ==
568 PacketResult::Success
) {
569 if (response
.IsUnsupportedResponse()) {
570 m_supports_jThreadsInfo
= false;
571 } else if (!response
.Empty()) {
572 object_sp
= StructuredData::ParseJSON(response
.GetStringRef());
579 bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
580 if (m_supports_jThreadExtendedInfo
== eLazyBoolCalculate
) {
581 StringExtractorGDBRemote response
;
582 m_supports_jThreadExtendedInfo
= eLazyBoolNo
;
583 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response
) ==
584 PacketResult::Success
) {
585 if (response
.IsOKResponse()) {
586 m_supports_jThreadExtendedInfo
= eLazyBoolYes
;
590 return m_supports_jThreadExtendedInfo
;
593 void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
594 if (m_supports_error_string_reply
== eLazyBoolCalculate
) {
595 StringExtractorGDBRemote response
;
596 // We try to enable error strings in remote packets but if we fail, we just
597 // work in the older way.
598 m_supports_error_string_reply
= eLazyBoolNo
;
599 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response
) ==
600 PacketResult::Success
) {
601 if (response
.IsOKResponse()) {
602 m_supports_error_string_reply
= eLazyBoolYes
;
608 bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
609 if (m_supports_jLoadedDynamicLibrariesInfos
== eLazyBoolCalculate
) {
610 StringExtractorGDBRemote response
;
611 m_supports_jLoadedDynamicLibrariesInfos
= eLazyBoolNo
;
612 if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
613 response
) == PacketResult::Success
) {
614 if (response
.IsOKResponse()) {
615 m_supports_jLoadedDynamicLibrariesInfos
= eLazyBoolYes
;
619 return m_supports_jLoadedDynamicLibrariesInfos
;
622 bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
623 if (m_supports_jGetSharedCacheInfo
== eLazyBoolCalculate
) {
624 StringExtractorGDBRemote response
;
625 m_supports_jGetSharedCacheInfo
= eLazyBoolNo
;
626 if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response
) ==
627 PacketResult::Success
) {
628 if (response
.IsOKResponse()) {
629 m_supports_jGetSharedCacheInfo
= eLazyBoolYes
;
633 return m_supports_jGetSharedCacheInfo
;
636 bool GDBRemoteCommunicationClient::GetDynamicLoaderProcessStateSupported() {
637 if (m_supports_jGetDyldProcessState
== eLazyBoolCalculate
) {
638 StringExtractorGDBRemote response
;
639 m_supports_jGetDyldProcessState
= eLazyBoolNo
;
640 if (SendPacketAndWaitForResponse("jGetDyldProcessState", response
) ==
641 PacketResult::Success
) {
642 if (!response
.IsUnsupportedResponse())
643 m_supports_jGetDyldProcessState
= eLazyBoolYes
;
646 return m_supports_jGetDyldProcessState
;
649 bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {
650 if (m_supports_memory_tagging
== eLazyBoolCalculate
) {
651 GetRemoteQSupported();
653 return m_supports_memory_tagging
== eLazyBoolYes
;
656 DataBufferSP
GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr
,
660 packet
.Printf("qMemTags:%" PRIx64
",%zx:%" PRIx32
, addr
, len
, type
);
661 StringExtractorGDBRemote response
;
663 Log
*log
= GetLog(GDBRLog::Memory
);
665 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) !=
666 PacketResult::Success
||
667 !response
.IsNormalResponse()) {
668 LLDB_LOGF(log
, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",
674 // m<hex encoded bytes>
676 if (response
.GetChar() != 'm') {
678 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
684 size_t expected_bytes
= response
.GetBytesLeft() / 2;
685 WritableDataBufferSP
buffer_sp(new DataBufferHeap(expected_bytes
, 0));
686 size_t got_bytes
= response
.GetHexBytesAvail(buffer_sp
->GetData());
687 // Check both because in some situations chars are consumed even
688 // if the decoding fails.
689 if (response
.GetBytesLeft() || (expected_bytes
!= got_bytes
)) {
692 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
700 Status
GDBRemoteCommunicationClient::WriteMemoryTags(
701 lldb::addr_t addr
, size_t len
, int32_t type
,
702 const std::vector
<uint8_t> &tags
) {
703 // Format QMemTags:address,length:type:tags
705 packet
.Printf("QMemTags:%" PRIx64
",%zx:%" PRIx32
":", addr
, len
, type
);
706 packet
.PutBytesAsRawHex8(tags
.data(), tags
.size());
709 StringExtractorGDBRemote response
;
710 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) !=
711 PacketResult::Success
||
712 !response
.IsOKResponse()) {
713 status
= Status::FromErrorString("QMemTags packet failed");
718 bool GDBRemoteCommunicationClient::GetxPacketSupported() {
719 if (m_supports_x
== eLazyBoolCalculate
) {
720 StringExtractorGDBRemote response
;
721 m_supports_x
= eLazyBoolNo
;
723 snprintf(packet
, sizeof(packet
), "x0,0");
724 if (SendPacketAndWaitForResponse(packet
, response
) ==
725 PacketResult::Success
) {
726 if (response
.IsOKResponse())
727 m_supports_x
= eLazyBoolYes
;
733 lldb::pid_t
GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy
) {
734 if (allow_lazy
&& m_curr_pid_is_valid
== eLazyBoolYes
)
737 // First try to retrieve the pid via the qProcessInfo request.
738 GetCurrentProcessInfo(allow_lazy
);
739 if (m_curr_pid_is_valid
== eLazyBoolYes
) {
743 // If we don't get a response for qProcessInfo, check if $qC gives us a
744 // result. $qC only returns a real process id on older debugserver and
745 // lldb-platform stubs. The gdb remote protocol documents $qC as returning
746 // the thread id, which newer debugserver and lldb-gdbserver stubs return
748 StringExtractorGDBRemote response
;
749 if (SendPacketAndWaitForResponse("qC", response
) == PacketResult::Success
) {
750 if (response
.GetChar() == 'Q') {
751 if (response
.GetChar() == 'C') {
752 m_curr_pid_run
= m_curr_pid
=
753 response
.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID
);
754 if (m_curr_pid
!= LLDB_INVALID_PROCESS_ID
) {
755 m_curr_pid_is_valid
= eLazyBoolYes
;
762 // If we don't get a response for $qC, check if $qfThreadID gives us a
764 if (m_curr_pid
== LLDB_INVALID_PROCESS_ID
) {
765 bool sequence_mutex_unavailable
;
766 auto ids
= GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable
);
767 if (!ids
.empty() && !sequence_mutex_unavailable
) {
768 // If server returned an explicit PID, use that.
769 m_curr_pid_run
= m_curr_pid
= ids
.front().first
;
770 // Otherwise, use the TID of the first thread (Linux hack).
771 if (m_curr_pid
== LLDB_INVALID_PROCESS_ID
)
772 m_curr_pid_run
= m_curr_pid
= ids
.front().second
;
773 m_curr_pid_is_valid
= eLazyBoolYes
;
779 return LLDB_INVALID_PROCESS_ID
;
782 llvm::Error
GDBRemoteCommunicationClient::LaunchProcess(const Args
&args
) {
783 if (!args
.GetArgumentAtIndex(0))
784 return llvm::createStringError(llvm::inconvertibleErrorCode(),
785 "Nothing to launch");
787 if (m_supports_vRun
) {
789 packet
.PutCString("vRun");
790 for (const Args::ArgEntry
&arg
: args
) {
792 packet
.PutStringAsRawHex8(arg
.ref());
795 StringExtractorGDBRemote response
;
796 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) !=
797 PacketResult::Success
)
798 return llvm::createStringError(llvm::inconvertibleErrorCode(),
799 "Sending vRun packet failed");
801 if (response
.IsErrorResponse())
802 return response
.GetStatus().ToError();
804 // vRun replies with a stop reason packet
805 // FIXME: right now we just discard the packet and LLDB queries
806 // for stop reason again
807 if (!response
.IsUnsupportedResponse())
808 return llvm::Error::success();
810 m_supports_vRun
= false;
816 llvm::ListSeparator
LS(",");
817 for (const auto &arg
: llvm::enumerate(args
)) {
819 packet
.Format("{0},{1},", arg
.value().ref().size() * 2, arg
.index());
820 packet
.PutStringAsRawHex8(arg
.value().ref());
823 StringExtractorGDBRemote response
;
824 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) !=
825 PacketResult::Success
) {
826 return llvm::createStringError(llvm::inconvertibleErrorCode(),
827 "Sending A packet failed");
829 if (!response
.IsOKResponse())
830 return response
.GetStatus().ToError();
832 if (SendPacketAndWaitForResponse("qLaunchSuccess", response
) !=
833 PacketResult::Success
) {
834 return llvm::createStringError(llvm::inconvertibleErrorCode(),
835 "Sending qLaunchSuccess packet failed");
837 if (response
.IsOKResponse())
838 return llvm::Error::success();
839 if (response
.GetChar() == 'E') {
840 return llvm::createStringError(llvm::inconvertibleErrorCode(),
841 response
.GetStringRef().substr(1));
843 return llvm::createStringError(llvm::inconvertibleErrorCode(),
844 "unknown error occurred launching process");
847 int GDBRemoteCommunicationClient::SendEnvironment(const Environment
&env
) {
848 llvm::SmallVector
<std::pair
<llvm::StringRef
, llvm::StringRef
>, 0> vec
;
849 for (const auto &kv
: env
)
850 vec
.emplace_back(kv
.first(), kv
.second
);
851 llvm::sort(vec
, llvm::less_first());
852 for (const auto &[k
, v
] : vec
) {
853 int r
= SendEnvironmentPacket((k
+ "=" + v
).str().c_str());
860 int GDBRemoteCommunicationClient::SendEnvironmentPacket(
861 char const *name_equal_value
) {
862 if (name_equal_value
&& name_equal_value
[0]) {
863 bool send_hex_encoding
= false;
864 for (const char *p
= name_equal_value
; *p
!= '\0' && !send_hex_encoding
;
866 if (llvm::isPrint(*p
)) {
872 send_hex_encoding
= true;
878 // We have non printable characters, lets hex encode this...
879 send_hex_encoding
= true;
883 StringExtractorGDBRemote response
;
884 // Prefer sending unencoded, if possible and the server supports it.
885 if (!send_hex_encoding
&& m_supports_QEnvironment
) {
887 packet
.Printf("QEnvironment:%s", name_equal_value
);
888 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) !=
889 PacketResult::Success
)
892 if (response
.IsOKResponse())
894 if (response
.IsUnsupportedResponse())
895 m_supports_QEnvironment
= false;
897 uint8_t error
= response
.GetError();
904 if (m_supports_QEnvironmentHexEncoded
) {
906 packet
.PutCString("QEnvironmentHexEncoded:");
907 packet
.PutBytesAsRawHex8(name_equal_value
, strlen(name_equal_value
));
908 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) !=
909 PacketResult::Success
)
912 if (response
.IsOKResponse())
914 if (response
.IsUnsupportedResponse())
915 m_supports_QEnvironmentHexEncoded
= false;
917 uint8_t error
= response
.GetError();
927 int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch
) {
928 if (arch
&& arch
[0]) {
930 packet
.Printf("QLaunchArch:%s", arch
);
931 StringExtractorGDBRemote response
;
932 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
933 PacketResult::Success
) {
934 if (response
.IsOKResponse())
936 uint8_t error
= response
.GetError();
944 int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
945 char const *data
, bool *was_supported
) {
946 if (data
&& *data
!= '\0') {
948 packet
.Printf("QSetProcessEvent:%s", data
);
949 StringExtractorGDBRemote response
;
950 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
951 PacketResult::Success
) {
952 if (response
.IsOKResponse()) {
954 *was_supported
= true;
956 } else if (response
.IsUnsupportedResponse()) {
958 *was_supported
= false;
961 uint8_t error
= response
.GetError();
963 *was_supported
= true;
972 llvm::VersionTuple
GDBRemoteCommunicationClient::GetOSVersion() {
977 llvm::VersionTuple
GDBRemoteCommunicationClient::GetMacCatalystVersion() {
979 return m_maccatalyst_version
;
982 std::optional
<std::string
> GDBRemoteCommunicationClient::GetOSBuildString() {
984 if (!m_os_build
.empty())
990 std::optional
<std::string
>
991 GDBRemoteCommunicationClient::GetOSKernelDescription() {
993 if (!m_os_kernel
.empty())
999 bool GDBRemoteCommunicationClient::GetHostname(std::string
&s
) {
1000 if (GetHostInfo()) {
1001 if (!m_hostname
.empty()) {
1010 ArchSpec
GDBRemoteCommunicationClient::GetSystemArchitecture() {
1016 const lldb_private::ArchSpec
&
1017 GDBRemoteCommunicationClient::GetProcessArchitecture() {
1018 if (m_qProcessInfo_is_valid
== eLazyBoolCalculate
)
1019 GetCurrentProcessInfo();
1020 return m_process_arch
;
1023 bool GDBRemoteCommunicationClient::GetProcessStandaloneBinary(
1024 UUID
&uuid
, addr_t
&value
, bool &value_is_offset
) {
1025 if (m_qProcessInfo_is_valid
== eLazyBoolCalculate
)
1026 GetCurrentProcessInfo();
1028 // Return true if we have a UUID or an address/offset of the
1029 // main standalone / firmware binary being used.
1030 if (!m_process_standalone_uuid
.IsValid() &&
1031 m_process_standalone_value
== LLDB_INVALID_ADDRESS
)
1034 uuid
= m_process_standalone_uuid
;
1035 value
= m_process_standalone_value
;
1036 value_is_offset
= m_process_standalone_value_is_offset
;
1041 GDBRemoteCommunicationClient::GetProcessStandaloneBinaries() {
1042 if (m_qProcessInfo_is_valid
== eLazyBoolCalculate
)
1043 GetCurrentProcessInfo();
1044 return m_binary_addresses
;
1047 bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
1048 if (m_qGDBServerVersion_is_valid
== eLazyBoolCalculate
) {
1049 m_gdb_server_name
.clear();
1050 m_gdb_server_version
= 0;
1051 m_qGDBServerVersion_is_valid
= eLazyBoolNo
;
1053 StringExtractorGDBRemote response
;
1054 if (SendPacketAndWaitForResponse("qGDBServerVersion", response
) ==
1055 PacketResult::Success
) {
1056 if (response
.IsNormalResponse()) {
1057 llvm::StringRef name
, value
;
1058 bool success
= false;
1059 while (response
.GetNameColonValue(name
, value
)) {
1060 if (name
== "name") {
1062 m_gdb_server_name
= std::string(value
);
1063 } else if (name
== "version") {
1064 llvm::StringRef major
, minor
;
1065 std::tie(major
, minor
) = value
.split('.');
1066 if (!major
.getAsInteger(0, m_gdb_server_version
))
1071 m_qGDBServerVersion_is_valid
= eLazyBoolYes
;
1075 return m_qGDBServerVersion_is_valid
== eLazyBoolYes
;
1078 void GDBRemoteCommunicationClient::MaybeEnableCompression(
1079 llvm::ArrayRef
<llvm::StringRef
> supported_compressions
) {
1080 CompressionType avail_type
= CompressionType::None
;
1081 llvm::StringRef avail_name
;
1083 #if defined(HAVE_LIBCOMPRESSION)
1084 if (avail_type
== CompressionType::None
) {
1085 for (auto compression
: supported_compressions
) {
1086 if (compression
== "lzfse") {
1087 avail_type
= CompressionType::LZFSE
;
1088 avail_name
= compression
;
1095 #if defined(HAVE_LIBCOMPRESSION)
1096 if (avail_type
== CompressionType::None
) {
1097 for (auto compression
: supported_compressions
) {
1098 if (compression
== "zlib-deflate") {
1099 avail_type
= CompressionType::ZlibDeflate
;
1100 avail_name
= compression
;
1107 #if LLVM_ENABLE_ZLIB
1108 if (avail_type
== CompressionType::None
) {
1109 for (auto compression
: supported_compressions
) {
1110 if (compression
== "zlib-deflate") {
1111 avail_type
= CompressionType::ZlibDeflate
;
1112 avail_name
= compression
;
1119 #if defined(HAVE_LIBCOMPRESSION)
1120 if (avail_type
== CompressionType::None
) {
1121 for (auto compression
: supported_compressions
) {
1122 if (compression
== "lz4") {
1123 avail_type
= CompressionType::LZ4
;
1124 avail_name
= compression
;
1131 #if defined(HAVE_LIBCOMPRESSION)
1132 if (avail_type
== CompressionType::None
) {
1133 for (auto compression
: supported_compressions
) {
1134 if (compression
== "lzma") {
1135 avail_type
= CompressionType::LZMA
;
1136 avail_name
= compression
;
1143 if (avail_type
!= CompressionType::None
) {
1144 StringExtractorGDBRemote response
;
1145 std::string packet
= "QEnableCompression:type:" + avail_name
.str() + ";";
1146 if (SendPacketAndWaitForResponse(packet
, response
) != PacketResult::Success
)
1149 if (response
.IsOKResponse()) {
1150 m_compression_type
= avail_type
;
1155 const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
1156 if (GetGDBServerVersion()) {
1157 if (!m_gdb_server_name
.empty())
1158 return m_gdb_server_name
.c_str();
1163 uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
1164 if (GetGDBServerVersion())
1165 return m_gdb_server_version
;
1169 bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t
&tid
) {
1170 StringExtractorGDBRemote response
;
1171 if (SendPacketAndWaitForResponse("qC", response
) != PacketResult::Success
)
1174 if (!response
.IsNormalResponse())
1177 if (response
.GetChar() == 'Q' && response
.GetChar() == 'C') {
1178 auto pid_tid
= response
.GetPidTid(0);
1182 lldb::pid_t pid
= pid_tid
->first
;
1184 if (pid
== StringExtractorGDBRemote::AllProcesses
)
1187 // if we get pid as well, update m_curr_pid
1189 m_curr_pid_run
= m_curr_pid
= pid
;
1190 m_curr_pid_is_valid
= eLazyBoolYes
;
1192 tid
= pid_tid
->second
;
1198 static void ParseOSType(llvm::StringRef value
, std::string
&os_name
,
1199 std::string
&environment
) {
1200 if (value
== "iossimulator" || value
== "tvossimulator" ||
1201 value
== "watchossimulator" || value
== "xrossimulator" ||
1202 value
== "visionossimulator") {
1203 environment
= "simulator";
1204 os_name
= value
.drop_back(environment
.size()).str();
1205 } else if (value
== "maccatalyst") {
1207 environment
= "macabi";
1209 os_name
= value
.str();
1213 bool GDBRemoteCommunicationClient::GetHostInfo(bool force
) {
1214 Log
*log
= GetLog(GDBRLog::Process
);
1216 if (force
|| m_qHostInfo_is_valid
== eLazyBoolCalculate
) {
1217 // host info computation can require DNS traffic and shelling out to external processes.
1218 // Increase the timeout to account for that.
1219 ScopedTimeout
timeout(*this, seconds(10));
1220 m_qHostInfo_is_valid
= eLazyBoolNo
;
1221 StringExtractorGDBRemote response
;
1222 if (SendPacketAndWaitForResponse("qHostInfo", response
) ==
1223 PacketResult::Success
) {
1224 if (response
.IsNormalResponse()) {
1225 llvm::StringRef name
;
1226 llvm::StringRef value
;
1227 uint32_t cpu
= LLDB_INVALID_CPUTYPE
;
1229 std::string arch_name
;
1230 std::string os_name
;
1231 std::string environment
;
1232 std::string vendor_name
;
1234 uint32_t pointer_byte_size
= 0;
1235 ByteOrder byte_order
= eByteOrderInvalid
;
1236 uint32_t num_keys_decoded
= 0;
1237 while (response
.GetNameColonValue(name
, value
)) {
1238 if (name
== "cputype") {
1239 // exception type in big endian hex
1240 if (!value
.getAsInteger(0, cpu
))
1242 } else if (name
== "cpusubtype") {
1243 // exception count in big endian hex
1244 if (!value
.getAsInteger(0, sub
))
1246 } else if (name
== "arch") {
1247 arch_name
= std::string(value
);
1249 } else if (name
== "triple") {
1250 StringExtractor
extractor(value
);
1251 extractor
.GetHexByteString(triple
);
1253 } else if (name
== "distribution_id") {
1254 StringExtractor
extractor(value
);
1255 extractor
.GetHexByteString(m_host_distribution_id
);
1257 } else if (name
== "os_build") {
1258 StringExtractor
extractor(value
);
1259 extractor
.GetHexByteString(m_os_build
);
1261 } else if (name
== "hostname") {
1262 StringExtractor
extractor(value
);
1263 extractor
.GetHexByteString(m_hostname
);
1265 } else if (name
== "os_kernel") {
1266 StringExtractor
extractor(value
);
1267 extractor
.GetHexByteString(m_os_kernel
);
1269 } else if (name
== "ostype") {
1270 ParseOSType(value
, os_name
, environment
);
1272 } else if (name
== "vendor") {
1273 vendor_name
= std::string(value
);
1275 } else if (name
== "endian") {
1276 byte_order
= llvm::StringSwitch
<lldb::ByteOrder
>(value
)
1277 .Case("little", eByteOrderLittle
)
1278 .Case("big", eByteOrderBig
)
1279 .Case("pdp", eByteOrderPDP
)
1280 .Default(eByteOrderInvalid
);
1281 if (byte_order
!= eByteOrderInvalid
)
1283 } else if (name
== "ptrsize") {
1284 if (!value
.getAsInteger(0, pointer_byte_size
))
1286 } else if (name
== "addressing_bits") {
1287 if (!value
.getAsInteger(0, m_low_mem_addressing_bits
)) {
1290 } else if (name
== "high_mem_addressing_bits") {
1291 if (!value
.getAsInteger(0, m_high_mem_addressing_bits
))
1293 } else if (name
== "low_mem_addressing_bits") {
1294 if (!value
.getAsInteger(0, m_low_mem_addressing_bits
))
1296 } else if (name
== "os_version" ||
1297 name
== "version") // Older debugserver binaries used
1298 // the "version" key instead of
1301 if (!m_os_version
.tryParse(value
))
1303 } else if (name
== "maccatalyst_version") {
1304 if (!m_maccatalyst_version
.tryParse(value
))
1306 } else if (name
== "watchpoint_exceptions_received") {
1307 m_watchpoints_trigger_after_instruction
=
1308 llvm::StringSwitch
<LazyBool
>(value
)
1309 .Case("before", eLazyBoolNo
)
1310 .Case("after", eLazyBoolYes
)
1311 .Default(eLazyBoolCalculate
);
1312 if (m_watchpoints_trigger_after_instruction
!= eLazyBoolCalculate
)
1314 } else if (name
== "default_packet_timeout") {
1315 uint32_t timeout_seconds
;
1316 if (!value
.getAsInteger(0, timeout_seconds
)) {
1317 m_default_packet_timeout
= seconds(timeout_seconds
);
1318 SetPacketTimeout(m_default_packet_timeout
);
1321 } else if (name
== "vm-page-size") {
1323 if (!value
.getAsInteger(0, page_size
)) {
1324 m_target_vm_page_size
= page_size
;
1330 if (num_keys_decoded
> 0)
1331 m_qHostInfo_is_valid
= eLazyBoolYes
;
1333 if (triple
.empty()) {
1334 if (arch_name
.empty()) {
1335 if (cpu
!= LLDB_INVALID_CPUTYPE
) {
1336 m_host_arch
.SetArchitecture(eArchTypeMachO
, cpu
, sub
);
1337 if (pointer_byte_size
) {
1338 assert(pointer_byte_size
== m_host_arch
.GetAddressByteSize());
1340 if (byte_order
!= eByteOrderInvalid
) {
1341 assert(byte_order
== m_host_arch
.GetByteOrder());
1344 if (!vendor_name
.empty())
1345 m_host_arch
.GetTriple().setVendorName(
1346 llvm::StringRef(vendor_name
));
1347 if (!os_name
.empty())
1348 m_host_arch
.GetTriple().setOSName(llvm::StringRef(os_name
));
1349 if (!environment
.empty())
1350 m_host_arch
.GetTriple().setEnvironmentName(environment
);
1354 triple
+= arch_name
;
1355 if (!vendor_name
.empty() || !os_name
.empty()) {
1357 if (vendor_name
.empty())
1358 triple
+= "unknown";
1360 triple
+= vendor_name
;
1362 if (os_name
.empty())
1363 triple
+= "unknown";
1367 m_host_arch
.SetTriple(triple
.c_str());
1369 llvm::Triple
&host_triple
= m_host_arch
.GetTriple();
1370 if (host_triple
.getVendor() == llvm::Triple::Apple
&&
1371 host_triple
.getOS() == llvm::Triple::Darwin
) {
1372 switch (m_host_arch
.GetMachine()) {
1373 case llvm::Triple::aarch64
:
1374 case llvm::Triple::aarch64_32
:
1375 case llvm::Triple::arm
:
1376 case llvm::Triple::thumb
:
1377 host_triple
.setOS(llvm::Triple::IOS
);
1380 host_triple
.setOS(llvm::Triple::MacOSX
);
1384 if (pointer_byte_size
) {
1385 assert(pointer_byte_size
== m_host_arch
.GetAddressByteSize());
1387 if (byte_order
!= eByteOrderInvalid
) {
1388 assert(byte_order
== m_host_arch
.GetByteOrder());
1392 m_host_arch
.SetTriple(triple
.c_str());
1393 if (pointer_byte_size
) {
1394 assert(pointer_byte_size
== m_host_arch
.GetAddressByteSize());
1396 if (byte_order
!= eByteOrderInvalid
) {
1397 assert(byte_order
== m_host_arch
.GetByteOrder());
1401 "GDBRemoteCommunicationClient::%s parsed host "
1402 "architecture as %s, triple as %s from triple text %s",
1404 m_host_arch
.GetArchitectureName()
1405 ? m_host_arch
.GetArchitectureName()
1406 : "<null-arch-name>",
1407 m_host_arch
.GetTriple().getTriple().c_str(),
1413 return m_qHostInfo_is_valid
== eLazyBoolYes
;
1416 int GDBRemoteCommunicationClient::SendStdinNotification(const char *data
,
1418 StreamString packet
;
1419 packet
.PutCString("I");
1420 packet
.PutBytesAsRawHex8(data
, data_len
);
1421 StringExtractorGDBRemote response
;
1422 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
1423 PacketResult::Success
) {
1426 return response
.GetError();
1429 const lldb_private::ArchSpec
&
1430 GDBRemoteCommunicationClient::GetHostArchitecture() {
1431 if (m_qHostInfo_is_valid
== eLazyBoolCalculate
)
1436 AddressableBits
GDBRemoteCommunicationClient::GetAddressableBits() {
1437 AddressableBits addressable_bits
;
1438 if (m_qHostInfo_is_valid
== eLazyBoolCalculate
)
1441 if (m_low_mem_addressing_bits
== m_high_mem_addressing_bits
)
1442 addressable_bits
.SetAddressableBits(m_low_mem_addressing_bits
);
1444 addressable_bits
.SetAddressableBits(m_low_mem_addressing_bits
,
1445 m_high_mem_addressing_bits
);
1446 return addressable_bits
;
1449 seconds
GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
1450 if (m_qHostInfo_is_valid
== eLazyBoolCalculate
)
1452 return m_default_packet_timeout
;
1455 addr_t
GDBRemoteCommunicationClient::AllocateMemory(size_t size
,
1456 uint32_t permissions
) {
1457 if (m_supports_alloc_dealloc_memory
!= eLazyBoolNo
) {
1458 m_supports_alloc_dealloc_memory
= eLazyBoolYes
;
1460 const int packet_len
= ::snprintf(
1461 packet
, sizeof(packet
), "_M%" PRIx64
",%s%s%s", (uint64_t)size
,
1462 permissions
& lldb::ePermissionsReadable
? "r" : "",
1463 permissions
& lldb::ePermissionsWritable
? "w" : "",
1464 permissions
& lldb::ePermissionsExecutable
? "x" : "");
1465 assert(packet_len
< (int)sizeof(packet
));
1466 UNUSED_IF_ASSERT_DISABLED(packet_len
);
1467 StringExtractorGDBRemote response
;
1468 if (SendPacketAndWaitForResponse(packet
, response
) ==
1469 PacketResult::Success
) {
1470 if (response
.IsUnsupportedResponse())
1471 m_supports_alloc_dealloc_memory
= eLazyBoolNo
;
1472 else if (!response
.IsErrorResponse())
1473 return response
.GetHexMaxU64(false, LLDB_INVALID_ADDRESS
);
1475 m_supports_alloc_dealloc_memory
= eLazyBoolNo
;
1478 return LLDB_INVALID_ADDRESS
;
1481 bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr
) {
1482 if (m_supports_alloc_dealloc_memory
!= eLazyBoolNo
) {
1483 m_supports_alloc_dealloc_memory
= eLazyBoolYes
;
1485 const int packet_len
=
1486 ::snprintf(packet
, sizeof(packet
), "_m%" PRIx64
, (uint64_t)addr
);
1487 assert(packet_len
< (int)sizeof(packet
));
1488 UNUSED_IF_ASSERT_DISABLED(packet_len
);
1489 StringExtractorGDBRemote response
;
1490 if (SendPacketAndWaitForResponse(packet
, response
) ==
1491 PacketResult::Success
) {
1492 if (response
.IsUnsupportedResponse())
1493 m_supports_alloc_dealloc_memory
= eLazyBoolNo
;
1494 else if (response
.IsOKResponse())
1497 m_supports_alloc_dealloc_memory
= eLazyBoolNo
;
1503 Status
GDBRemoteCommunicationClient::Detach(bool keep_stopped
,
1506 lldb_private::StreamString packet
;
1508 packet
.PutChar('D');
1510 if (m_supports_detach_stay_stopped
== eLazyBoolCalculate
) {
1512 const int packet_len
=
1513 ::snprintf(packet
, sizeof(packet
), "qSupportsDetachAndStayStopped:");
1514 assert(packet_len
< (int)sizeof(packet
));
1515 UNUSED_IF_ASSERT_DISABLED(packet_len
);
1516 StringExtractorGDBRemote response
;
1517 if (SendPacketAndWaitForResponse(packet
, response
) ==
1518 PacketResult::Success
&&
1519 response
.IsOKResponse()) {
1520 m_supports_detach_stay_stopped
= eLazyBoolYes
;
1522 m_supports_detach_stay_stopped
= eLazyBoolNo
;
1526 if (m_supports_detach_stay_stopped
== eLazyBoolNo
) {
1527 error
= Status::FromErrorString(
1528 "Stays stopped not supported by this target.");
1531 packet
.PutChar('1');
1535 if (GetMultiprocessSupported()) {
1536 // Some servers (e.g. qemu) require specifying the PID even if only a single
1537 // process is running.
1538 if (pid
== LLDB_INVALID_PROCESS_ID
)
1539 pid
= GetCurrentProcessID();
1540 packet
.PutChar(';');
1541 packet
.PutHex64(pid
);
1542 } else if (pid
!= LLDB_INVALID_PROCESS_ID
) {
1543 error
= Status::FromErrorString(
1544 "Multiprocess extension not supported by the server.");
1548 StringExtractorGDBRemote response
;
1549 PacketResult packet_result
=
1550 SendPacketAndWaitForResponse(packet
.GetString(), response
);
1551 if (packet_result
!= PacketResult::Success
)
1552 error
= Status::FromErrorString("Sending isconnect packet failed.");
1556 Status
GDBRemoteCommunicationClient::GetMemoryRegionInfo(
1557 lldb::addr_t addr
, lldb_private::MemoryRegionInfo
®ion_info
) {
1559 region_info
.Clear();
1561 if (m_supports_memory_region_info
!= eLazyBoolNo
) {
1562 m_supports_memory_region_info
= eLazyBoolYes
;
1564 const int packet_len
= ::snprintf(
1565 packet
, sizeof(packet
), "qMemoryRegionInfo:%" PRIx64
, (uint64_t)addr
);
1566 assert(packet_len
< (int)sizeof(packet
));
1567 UNUSED_IF_ASSERT_DISABLED(packet_len
);
1568 StringExtractorGDBRemote response
;
1569 if (SendPacketAndWaitForResponse(packet
, response
) ==
1570 PacketResult::Success
&&
1571 response
.GetResponseType() == StringExtractorGDBRemote::eResponse
) {
1572 llvm::StringRef name
;
1573 llvm::StringRef value
;
1574 addr_t addr_value
= LLDB_INVALID_ADDRESS
;
1575 bool success
= true;
1576 bool saw_permissions
= false;
1577 while (success
&& response
.GetNameColonValue(name
, value
)) {
1578 if (name
== "start") {
1579 if (!value
.getAsInteger(16, addr_value
))
1580 region_info
.GetRange().SetRangeBase(addr_value
);
1581 } else if (name
== "size") {
1582 if (!value
.getAsInteger(16, addr_value
)) {
1583 region_info
.GetRange().SetByteSize(addr_value
);
1584 if (region_info
.GetRange().GetRangeEnd() <
1585 region_info
.GetRange().GetRangeBase()) {
1586 // Range size overflowed, truncate it.
1587 region_info
.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS
);
1590 } else if (name
== "permissions" && region_info
.GetRange().IsValid()) {
1591 saw_permissions
= true;
1592 if (region_info
.GetRange().Contains(addr
)) {
1593 if (value
.contains('r'))
1594 region_info
.SetReadable(MemoryRegionInfo::eYes
);
1596 region_info
.SetReadable(MemoryRegionInfo::eNo
);
1598 if (value
.contains('w'))
1599 region_info
.SetWritable(MemoryRegionInfo::eYes
);
1601 region_info
.SetWritable(MemoryRegionInfo::eNo
);
1603 if (value
.contains('x'))
1604 region_info
.SetExecutable(MemoryRegionInfo::eYes
);
1606 region_info
.SetExecutable(MemoryRegionInfo::eNo
);
1608 region_info
.SetMapped(MemoryRegionInfo::eYes
);
1610 // The reported region does not contain this address -- we're
1611 // looking at an unmapped page
1612 region_info
.SetReadable(MemoryRegionInfo::eNo
);
1613 region_info
.SetWritable(MemoryRegionInfo::eNo
);
1614 region_info
.SetExecutable(MemoryRegionInfo::eNo
);
1615 region_info
.SetMapped(MemoryRegionInfo::eNo
);
1617 } else if (name
== "name") {
1618 StringExtractorGDBRemote
name_extractor(value
);
1620 name_extractor
.GetHexByteString(name
);
1621 region_info
.SetName(name
.c_str());
1622 } else if (name
== "flags") {
1623 region_info
.SetMemoryTagged(MemoryRegionInfo::eNo
);
1624 region_info
.SetIsShadowStack(MemoryRegionInfo::eNo
);
1626 llvm::StringRef flags
= value
;
1627 llvm::StringRef flag
;
1628 while (flags
.size()) {
1629 flags
= flags
.ltrim();
1630 std::tie(flag
, flags
) = flags
.split(' ');
1631 // To account for trailing whitespace
1634 region_info
.SetMemoryTagged(MemoryRegionInfo::eYes
);
1635 else if (flag
== "ss")
1636 region_info
.SetIsShadowStack(MemoryRegionInfo::eYes
);
1639 } else if (name
== "type") {
1640 for (llvm::StringRef entry
: llvm::split(value
, ',')) {
1641 if (entry
== "stack")
1642 region_info
.SetIsStackMemory(MemoryRegionInfo::eYes
);
1643 else if (entry
== "heap")
1644 region_info
.SetIsStackMemory(MemoryRegionInfo::eNo
);
1646 } else if (name
== "error") {
1647 StringExtractorGDBRemote
error_extractor(value
);
1648 std::string error_string
;
1649 // Now convert the HEX bytes into a string value
1650 error_extractor
.GetHexByteString(error_string
);
1651 error
= Status::FromErrorString(error_string
.c_str());
1652 } else if (name
== "dirty-pages") {
1653 std::vector
<addr_t
> dirty_page_list
;
1654 for (llvm::StringRef x
: llvm::split(value
, ',')) {
1656 x
.consume_front("0x");
1657 if (llvm::to_integer(x
, page
, 16))
1658 dirty_page_list
.push_back(page
);
1660 region_info
.SetDirtyPageList(dirty_page_list
);
1664 if (m_target_vm_page_size
!= 0)
1665 region_info
.SetPageSize(m_target_vm_page_size
);
1667 if (region_info
.GetRange().IsValid()) {
1668 // We got a valid address range back but no permissions -- which means
1669 // this is an unmapped page
1670 if (!saw_permissions
) {
1671 region_info
.SetReadable(MemoryRegionInfo::eNo
);
1672 region_info
.SetWritable(MemoryRegionInfo::eNo
);
1673 region_info
.SetExecutable(MemoryRegionInfo::eNo
);
1674 region_info
.SetMapped(MemoryRegionInfo::eNo
);
1677 // We got an invalid address range back
1678 error
= Status::FromErrorString("Server returned invalid range");
1681 m_supports_memory_region_info
= eLazyBoolNo
;
1685 if (m_supports_memory_region_info
== eLazyBoolNo
) {
1686 error
= Status::FromErrorString("qMemoryRegionInfo is not supported");
1689 // Try qXfer:memory-map:read to get region information not included in
1690 // qMemoryRegionInfo
1691 MemoryRegionInfo qXfer_region_info
;
1692 Status qXfer_error
= GetQXferMemoryMapRegionInfo(addr
, qXfer_region_info
);
1695 // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
1696 // the qXfer result as a fallback
1697 if (qXfer_error
.Success()) {
1698 region_info
= qXfer_region_info
;
1701 region_info
.Clear();
1703 } else if (qXfer_error
.Success()) {
1704 // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
1705 // both regions are the same range, update the result to include the flash-
1706 // memory information that is specific to the qXfer result.
1707 if (region_info
.GetRange() == qXfer_region_info
.GetRange()) {
1708 region_info
.SetFlash(qXfer_region_info
.GetFlash());
1709 region_info
.SetBlocksize(qXfer_region_info
.GetBlocksize());
1715 Status
GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
1716 lldb::addr_t addr
, MemoryRegionInfo
®ion
) {
1717 Status error
= LoadQXferMemoryMap();
1718 if (!error
.Success())
1720 for (const auto &map_region
: m_qXfer_memory_map
) {
1721 if (map_region
.GetRange().Contains(addr
)) {
1722 region
= map_region
;
1726 error
= Status::FromErrorString("Region not found");
1730 Status
GDBRemoteCommunicationClient::LoadQXferMemoryMap() {
1734 if (m_qXfer_memory_map_loaded
)
1735 // Already loaded, return success
1738 if (!XMLDocument::XMLEnabled()) {
1739 error
= Status::FromErrorString("XML is not supported");
1743 if (!GetQXferMemoryMapReadSupported()) {
1744 error
= Status::FromErrorString("Memory map is not supported");
1748 llvm::Expected
<std::string
> xml
= ReadExtFeature("memory-map", "");
1750 return Status::FromError(xml
.takeError());
1752 XMLDocument xml_document
;
1754 if (!xml_document
.ParseMemory(xml
->c_str(), xml
->size())) {
1755 error
= Status::FromErrorString("Failed to parse memory map xml");
1759 XMLNode map_node
= xml_document
.GetRootElement("memory-map");
1761 error
= Status::FromErrorString("Invalid root node in memory map xml");
1765 m_qXfer_memory_map
.clear();
1767 map_node
.ForEachChildElement([this](const XMLNode
&memory_node
) -> bool {
1768 if (!memory_node
.IsElement())
1770 if (memory_node
.GetName() != "memory")
1772 auto type
= memory_node
.GetAttributeValue("type", "");
1775 if (!memory_node
.GetAttributeValueAsUnsigned("start", start
))
1777 if (!memory_node
.GetAttributeValueAsUnsigned("length", length
))
1779 MemoryRegionInfo region
;
1780 region
.GetRange().SetRangeBase(start
);
1781 region
.GetRange().SetByteSize(length
);
1782 if (type
== "rom") {
1783 region
.SetReadable(MemoryRegionInfo::eYes
);
1784 this->m_qXfer_memory_map
.push_back(region
);
1785 } else if (type
== "ram") {
1786 region
.SetReadable(MemoryRegionInfo::eYes
);
1787 region
.SetWritable(MemoryRegionInfo::eYes
);
1788 this->m_qXfer_memory_map
.push_back(region
);
1789 } else if (type
== "flash") {
1790 region
.SetFlash(MemoryRegionInfo::eYes
);
1791 memory_node
.ForEachChildElement(
1792 [®ion
](const XMLNode
&prop_node
) -> bool {
1793 if (!prop_node
.IsElement())
1795 if (prop_node
.GetName() != "property")
1797 auto propname
= prop_node
.GetAttributeValue("name", "");
1798 if (propname
== "blocksize") {
1800 if (prop_node
.GetElementTextAsUnsigned(blocksize
))
1801 region
.SetBlocksize(blocksize
);
1805 this->m_qXfer_memory_map
.push_back(region
);
1810 m_qXfer_memory_map_loaded
= true;
1815 std::optional
<uint32_t> GDBRemoteCommunicationClient::GetWatchpointSlotCount() {
1816 if (m_supports_watchpoint_support_info
== eLazyBoolYes
) {
1817 return m_num_supported_hardware_watchpoints
;
1820 std::optional
<uint32_t> num
;
1821 if (m_supports_watchpoint_support_info
!= eLazyBoolNo
) {
1822 StringExtractorGDBRemote response
;
1823 if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response
) ==
1824 PacketResult::Success
) {
1825 m_supports_watchpoint_support_info
= eLazyBoolYes
;
1826 llvm::StringRef name
;
1827 llvm::StringRef value
;
1828 while (response
.GetNameColonValue(name
, value
)) {
1829 if (name
== "num") {
1830 value
.getAsInteger(0, m_num_supported_hardware_watchpoints
);
1831 num
= m_num_supported_hardware_watchpoints
;
1835 m_supports_watchpoint_support_info
= eLazyBoolNo
;
1838 m_supports_watchpoint_support_info
= eLazyBoolNo
;
1845 WatchpointHardwareFeature
1846 GDBRemoteCommunicationClient::GetSupportedWatchpointTypes() {
1847 return m_watchpoint_types
;
1850 std::optional
<bool> GDBRemoteCommunicationClient::GetWatchpointReportedAfter() {
1851 if (m_qHostInfo_is_valid
== eLazyBoolCalculate
)
1854 // Process determines this by target CPU, but allow for the
1855 // remote stub to override it via the qHostInfo
1856 // watchpoint_exceptions_received key, if it is present.
1857 if (m_qHostInfo_is_valid
== eLazyBoolYes
) {
1858 if (m_watchpoints_trigger_after_instruction
== eLazyBoolNo
)
1860 if (m_watchpoints_trigger_after_instruction
== eLazyBoolYes
)
1864 return std::nullopt
;
1867 int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec
&file_spec
) {
1869 std::string path
{file_spec
.GetPath(false)};
1870 StreamString packet
;
1871 packet
.PutCString("QSetSTDIN:");
1872 packet
.PutStringAsRawHex8(path
);
1874 StringExtractorGDBRemote response
;
1875 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
1876 PacketResult::Success
) {
1877 if (response
.IsOKResponse())
1879 uint8_t error
= response
.GetError();
1887 int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec
&file_spec
) {
1889 std::string path
{file_spec
.GetPath(false)};
1890 StreamString packet
;
1891 packet
.PutCString("QSetSTDOUT:");
1892 packet
.PutStringAsRawHex8(path
);
1894 StringExtractorGDBRemote response
;
1895 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
1896 PacketResult::Success
) {
1897 if (response
.IsOKResponse())
1899 uint8_t error
= response
.GetError();
1907 int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec
&file_spec
) {
1909 std::string path
{file_spec
.GetPath(false)};
1910 StreamString packet
;
1911 packet
.PutCString("QSetSTDERR:");
1912 packet
.PutStringAsRawHex8(path
);
1914 StringExtractorGDBRemote response
;
1915 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
1916 PacketResult::Success
) {
1917 if (response
.IsOKResponse())
1919 uint8_t error
= response
.GetError();
1927 bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec
&working_dir
) {
1928 StringExtractorGDBRemote response
;
1929 if (SendPacketAndWaitForResponse("qGetWorkingDir", response
) ==
1930 PacketResult::Success
) {
1931 if (response
.IsUnsupportedResponse())
1933 if (response
.IsErrorResponse())
1936 response
.GetHexByteString(cwd
);
1937 working_dir
.SetFile(cwd
, GetHostArchitecture().GetTriple());
1938 return !cwd
.empty();
1943 int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec
&working_dir
) {
1945 std::string path
{working_dir
.GetPath(false)};
1946 StreamString packet
;
1947 packet
.PutCString("QSetWorkingDir:");
1948 packet
.PutStringAsRawHex8(path
);
1950 StringExtractorGDBRemote response
;
1951 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
1952 PacketResult::Success
) {
1953 if (response
.IsOKResponse())
1955 uint8_t error
= response
.GetError();
1963 int GDBRemoteCommunicationClient::SetDisableASLR(bool enable
) {
1965 const int packet_len
=
1966 ::snprintf(packet
, sizeof(packet
), "QSetDisableASLR:%i", enable
? 1 : 0);
1967 assert(packet_len
< (int)sizeof(packet
));
1968 UNUSED_IF_ASSERT_DISABLED(packet_len
);
1969 StringExtractorGDBRemote response
;
1970 if (SendPacketAndWaitForResponse(packet
, response
) == PacketResult::Success
) {
1971 if (response
.IsOKResponse())
1973 uint8_t error
= response
.GetError();
1980 int GDBRemoteCommunicationClient::SetDetachOnError(bool enable
) {
1982 const int packet_len
= ::snprintf(packet
, sizeof(packet
),
1983 "QSetDetachOnError:%i", enable
? 1 : 0);
1984 assert(packet_len
< (int)sizeof(packet
));
1985 UNUSED_IF_ASSERT_DISABLED(packet_len
);
1986 StringExtractorGDBRemote response
;
1987 if (SendPacketAndWaitForResponse(packet
, response
) == PacketResult::Success
) {
1988 if (response
.IsOKResponse())
1990 uint8_t error
= response
.GetError();
1997 bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
1998 StringExtractorGDBRemote
&response
, ProcessInstanceInfo
&process_info
) {
1999 if (response
.IsNormalResponse()) {
2000 llvm::StringRef name
;
2001 llvm::StringRef value
;
2002 StringExtractor extractor
;
2004 uint32_t cpu
= LLDB_INVALID_CPUTYPE
;
2007 std::string os_type
;
2009 while (response
.GetNameColonValue(name
, value
)) {
2010 if (name
== "pid") {
2011 lldb::pid_t pid
= LLDB_INVALID_PROCESS_ID
;
2012 value
.getAsInteger(0, pid
);
2013 process_info
.SetProcessID(pid
);
2014 } else if (name
== "ppid") {
2015 lldb::pid_t pid
= LLDB_INVALID_PROCESS_ID
;
2016 value
.getAsInteger(0, pid
);
2017 process_info
.SetParentProcessID(pid
);
2018 } else if (name
== "uid") {
2019 uint32_t uid
= UINT32_MAX
;
2020 value
.getAsInteger(0, uid
);
2021 process_info
.SetUserID(uid
);
2022 } else if (name
== "euid") {
2023 uint32_t uid
= UINT32_MAX
;
2024 value
.getAsInteger(0, uid
);
2025 process_info
.SetEffectiveUserID(uid
);
2026 } else if (name
== "gid") {
2027 uint32_t gid
= UINT32_MAX
;
2028 value
.getAsInteger(0, gid
);
2029 process_info
.SetGroupID(gid
);
2030 } else if (name
== "egid") {
2031 uint32_t gid
= UINT32_MAX
;
2032 value
.getAsInteger(0, gid
);
2033 process_info
.SetEffectiveGroupID(gid
);
2034 } else if (name
== "triple") {
2035 StringExtractor
extractor(value
);
2037 extractor
.GetHexByteString(triple
);
2038 process_info
.GetArchitecture().SetTriple(triple
.c_str());
2039 } else if (name
== "name") {
2040 StringExtractor
extractor(value
);
2041 // The process name from ASCII hex bytes since we can't control the
2042 // characters in a process name
2044 extractor
.GetHexByteString(name
);
2045 process_info
.GetExecutableFile().SetFile(name
, FileSpec::Style::native
);
2046 } else if (name
== "args") {
2047 llvm::StringRef
encoded_args(value
), hex_arg
;
2049 bool is_arg0
= true;
2050 while (!encoded_args
.empty()) {
2051 std::tie(hex_arg
, encoded_args
) = encoded_args
.split('-');
2053 StringExtractor
extractor(hex_arg
);
2054 if (extractor
.GetHexByteString(arg
) * 2 != hex_arg
.size()) {
2055 // In case of wrong encoding, we discard all the arguments
2056 process_info
.GetArguments().Clear();
2057 process_info
.SetArg0("");
2061 process_info
.SetArg0(arg
);
2063 process_info
.GetArguments().AppendArgument(arg
);
2066 } else if (name
== "cputype") {
2067 value
.getAsInteger(0, cpu
);
2068 } else if (name
== "cpusubtype") {
2069 value
.getAsInteger(0, sub
);
2070 } else if (name
== "vendor") {
2071 vendor
= std::string(value
);
2072 } else if (name
== "ostype") {
2073 os_type
= std::string(value
);
2077 if (cpu
!= LLDB_INVALID_CPUTYPE
&& !vendor
.empty() && !os_type
.empty()) {
2078 if (vendor
== "apple") {
2079 process_info
.GetArchitecture().SetArchitecture(eArchTypeMachO
, cpu
,
2081 process_info
.GetArchitecture().GetTriple().setVendorName(
2082 llvm::StringRef(vendor
));
2083 process_info
.GetArchitecture().GetTriple().setOSName(
2084 llvm::StringRef(os_type
));
2088 if (process_info
.GetProcessID() != LLDB_INVALID_PROCESS_ID
)
2094 bool GDBRemoteCommunicationClient::GetProcessInfo(
2095 lldb::pid_t pid
, ProcessInstanceInfo
&process_info
) {
2096 process_info
.Clear();
2098 if (m_supports_qProcessInfoPID
) {
2100 const int packet_len
=
2101 ::snprintf(packet
, sizeof(packet
), "qProcessInfoPID:%" PRIu64
, pid
);
2102 assert(packet_len
< (int)sizeof(packet
));
2103 UNUSED_IF_ASSERT_DISABLED(packet_len
);
2104 StringExtractorGDBRemote response
;
2105 if (SendPacketAndWaitForResponse(packet
, response
) ==
2106 PacketResult::Success
) {
2107 return DecodeProcessInfoResponse(response
, process_info
);
2109 m_supports_qProcessInfoPID
= false;
2116 bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy
) {
2117 Log
*log(GetLog(GDBRLog::Process
| GDBRLog::Packets
));
2120 if (m_qProcessInfo_is_valid
== eLazyBoolYes
)
2122 if (m_qProcessInfo_is_valid
== eLazyBoolNo
)
2128 StringExtractorGDBRemote response
;
2129 if (SendPacketAndWaitForResponse("qProcessInfo", response
) ==
2130 PacketResult::Success
) {
2131 if (response
.IsNormalResponse()) {
2132 llvm::StringRef name
;
2133 llvm::StringRef value
;
2134 uint32_t cpu
= LLDB_INVALID_CPUTYPE
;
2136 std::string arch_name
;
2137 std::string os_name
;
2138 std::string environment
;
2139 std::string vendor_name
;
2141 std::string elf_abi
;
2142 uint32_t pointer_byte_size
= 0;
2143 StringExtractor extractor
;
2144 ByteOrder byte_order
= eByteOrderInvalid
;
2145 uint32_t num_keys_decoded
= 0;
2146 lldb::pid_t pid
= LLDB_INVALID_PROCESS_ID
;
2147 while (response
.GetNameColonValue(name
, value
)) {
2148 if (name
== "cputype") {
2149 if (!value
.getAsInteger(16, cpu
))
2151 } else if (name
== "cpusubtype") {
2152 if (!value
.getAsInteger(16, sub
)) {
2154 // Workaround for pre-2024 Apple debugserver, which always
2155 // returns arm64e on arm64e-capable hardware regardless of
2156 // what the process is. This can be deleted at some point
2158 if (cpu
== llvm::MachO::CPU_TYPE_ARM64
&&
2159 sub
== llvm::MachO::CPU_SUBTYPE_ARM64E
) {
2160 if (GetGDBServerVersion())
2161 if (m_gdb_server_version
>= 1000 &&
2162 m_gdb_server_version
<= 1504)
2166 } else if (name
== "triple") {
2167 StringExtractor
extractor(value
);
2168 extractor
.GetHexByteString(triple
);
2170 } else if (name
== "ostype") {
2171 ParseOSType(value
, os_name
, environment
);
2173 } else if (name
== "vendor") {
2174 vendor_name
= std::string(value
);
2176 } else if (name
== "endian") {
2177 byte_order
= llvm::StringSwitch
<lldb::ByteOrder
>(value
)
2178 .Case("little", eByteOrderLittle
)
2179 .Case("big", eByteOrderBig
)
2180 .Case("pdp", eByteOrderPDP
)
2181 .Default(eByteOrderInvalid
);
2182 if (byte_order
!= eByteOrderInvalid
)
2184 } else if (name
== "ptrsize") {
2185 if (!value
.getAsInteger(16, pointer_byte_size
))
2187 } else if (name
== "pid") {
2188 if (!value
.getAsInteger(16, pid
))
2190 } else if (name
== "elf_abi") {
2191 elf_abi
= std::string(value
);
2193 } else if (name
== "main-binary-uuid") {
2194 m_process_standalone_uuid
.SetFromStringRef(value
);
2196 } else if (name
== "main-binary-slide") {
2197 StringExtractor
extractor(value
);
2198 m_process_standalone_value
=
2199 extractor
.GetU64(LLDB_INVALID_ADDRESS
, 16);
2200 if (m_process_standalone_value
!= LLDB_INVALID_ADDRESS
) {
2201 m_process_standalone_value_is_offset
= true;
2204 } else if (name
== "main-binary-address") {
2205 StringExtractor
extractor(value
);
2206 m_process_standalone_value
=
2207 extractor
.GetU64(LLDB_INVALID_ADDRESS
, 16);
2208 if (m_process_standalone_value
!= LLDB_INVALID_ADDRESS
) {
2209 m_process_standalone_value_is_offset
= false;
2212 } else if (name
== "binary-addresses") {
2213 m_binary_addresses
.clear();
2215 for (llvm::StringRef x
: llvm::split(value
, ',')) {
2217 x
.consume_front("0x");
2218 if (llvm::to_integer(x
, vmaddr
, 16))
2219 m_binary_addresses
.push_back(vmaddr
);
2223 if (num_keys_decoded
> 0)
2224 m_qProcessInfo_is_valid
= eLazyBoolYes
;
2225 if (pid
!= LLDB_INVALID_PROCESS_ID
) {
2226 m_curr_pid_is_valid
= eLazyBoolYes
;
2227 m_curr_pid_run
= m_curr_pid
= pid
;
2230 // Set the ArchSpec from the triple if we have it.
2231 if (!triple
.empty()) {
2232 m_process_arch
.SetTriple(triple
.c_str());
2233 m_process_arch
.SetFlags(elf_abi
);
2234 if (pointer_byte_size
) {
2235 assert(pointer_byte_size
== m_process_arch
.GetAddressByteSize());
2237 } else if (cpu
!= LLDB_INVALID_CPUTYPE
&& !os_name
.empty() &&
2238 !vendor_name
.empty()) {
2239 llvm::Triple
triple(llvm::Twine("-") + vendor_name
+ "-" + os_name
);
2240 if (!environment
.empty())
2241 triple
.setEnvironmentName(environment
);
2243 assert(triple
.getObjectFormat() != llvm::Triple::UnknownObjectFormat
);
2244 assert(triple
.getObjectFormat() != llvm::Triple::Wasm
);
2245 assert(triple
.getObjectFormat() != llvm::Triple::XCOFF
);
2246 switch (triple
.getObjectFormat()) {
2247 case llvm::Triple::MachO
:
2248 m_process_arch
.SetArchitecture(eArchTypeMachO
, cpu
, sub
);
2250 case llvm::Triple::ELF
:
2251 m_process_arch
.SetArchitecture(eArchTypeELF
, cpu
, sub
);
2253 case llvm::Triple::COFF
:
2254 m_process_arch
.SetArchitecture(eArchTypeCOFF
, cpu
, sub
);
2256 case llvm::Triple::GOFF
:
2257 case llvm::Triple::SPIRV
:
2258 case llvm::Triple::Wasm
:
2259 case llvm::Triple::XCOFF
:
2260 case llvm::Triple::DXContainer
:
2261 LLDB_LOGF(log
, "error: not supported target architecture");
2263 case llvm::Triple::UnknownObjectFormat
:
2264 LLDB_LOGF(log
, "error: failed to determine target architecture");
2268 if (pointer_byte_size
) {
2269 assert(pointer_byte_size
== m_process_arch
.GetAddressByteSize());
2271 if (byte_order
!= eByteOrderInvalid
) {
2272 assert(byte_order
== m_process_arch
.GetByteOrder());
2274 m_process_arch
.GetTriple().setVendorName(llvm::StringRef(vendor_name
));
2275 m_process_arch
.GetTriple().setOSName(llvm::StringRef(os_name
));
2276 m_process_arch
.GetTriple().setEnvironmentName(llvm::StringRef(environment
));
2281 m_qProcessInfo_is_valid
= eLazyBoolNo
;
2287 uint32_t GDBRemoteCommunicationClient::FindProcesses(
2288 const ProcessInstanceInfoMatch
&match_info
,
2289 ProcessInstanceInfoList
&process_infos
) {
2290 process_infos
.clear();
2292 if (m_supports_qfProcessInfo
) {
2293 StreamString packet
;
2294 packet
.PutCString("qfProcessInfo");
2295 if (!match_info
.MatchAllProcesses()) {
2296 packet
.PutChar(':');
2297 const char *name
= match_info
.GetProcessInfo().GetName();
2298 bool has_name_match
= false;
2299 if (name
&& name
[0]) {
2300 has_name_match
= true;
2301 NameMatch name_match_type
= match_info
.GetNameMatchType();
2302 switch (name_match_type
) {
2303 case NameMatch::Ignore
:
2304 has_name_match
= false;
2307 case NameMatch::Equals
:
2308 packet
.PutCString("name_match:equals;");
2311 case NameMatch::Contains
:
2312 packet
.PutCString("name_match:contains;");
2315 case NameMatch::StartsWith
:
2316 packet
.PutCString("name_match:starts_with;");
2319 case NameMatch::EndsWith
:
2320 packet
.PutCString("name_match:ends_with;");
2323 case NameMatch::RegularExpression
:
2324 packet
.PutCString("name_match:regex;");
2327 if (has_name_match
) {
2328 packet
.PutCString("name:");
2329 packet
.PutBytesAsRawHex8(name
, ::strlen(name
));
2330 packet
.PutChar(';');
2334 if (match_info
.GetProcessInfo().ProcessIDIsValid())
2335 packet
.Printf("pid:%" PRIu64
";",
2336 match_info
.GetProcessInfo().GetProcessID());
2337 if (match_info
.GetProcessInfo().ParentProcessIDIsValid())
2338 packet
.Printf("parent_pid:%" PRIu64
";",
2339 match_info
.GetProcessInfo().GetParentProcessID());
2340 if (match_info
.GetProcessInfo().UserIDIsValid())
2341 packet
.Printf("uid:%u;", match_info
.GetProcessInfo().GetUserID());
2342 if (match_info
.GetProcessInfo().GroupIDIsValid())
2343 packet
.Printf("gid:%u;", match_info
.GetProcessInfo().GetGroupID());
2344 if (match_info
.GetProcessInfo().EffectiveUserIDIsValid())
2345 packet
.Printf("euid:%u;",
2346 match_info
.GetProcessInfo().GetEffectiveUserID());
2347 if (match_info
.GetProcessInfo().EffectiveGroupIDIsValid())
2348 packet
.Printf("egid:%u;",
2349 match_info
.GetProcessInfo().GetEffectiveGroupID());
2350 packet
.Printf("all_users:%u;", match_info
.GetMatchAllUsers() ? 1 : 0);
2351 if (match_info
.GetProcessInfo().GetArchitecture().IsValid()) {
2352 const ArchSpec
&match_arch
=
2353 match_info
.GetProcessInfo().GetArchitecture();
2354 const llvm::Triple
&triple
= match_arch
.GetTriple();
2355 packet
.PutCString("triple:");
2356 packet
.PutCString(triple
.getTriple());
2357 packet
.PutChar(';');
2360 StringExtractorGDBRemote response
;
2361 // Increase timeout as the first qfProcessInfo packet takes a long time on
2362 // Android. The value of 1min was arrived at empirically.
2363 ScopedTimeout
timeout(*this, minutes(1));
2364 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
2365 PacketResult::Success
) {
2367 ProcessInstanceInfo process_info
;
2368 if (!DecodeProcessInfoResponse(response
, process_info
))
2370 process_infos
.push_back(process_info
);
2371 response
= StringExtractorGDBRemote();
2372 } while (SendPacketAndWaitForResponse("qsProcessInfo", response
) ==
2373 PacketResult::Success
);
2375 m_supports_qfProcessInfo
= false;
2379 return process_infos
.size();
2382 bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid
,
2383 std::string
&name
) {
2384 if (m_supports_qUserName
) {
2386 const int packet_len
=
2387 ::snprintf(packet
, sizeof(packet
), "qUserName:%i", uid
);
2388 assert(packet_len
< (int)sizeof(packet
));
2389 UNUSED_IF_ASSERT_DISABLED(packet_len
);
2390 StringExtractorGDBRemote response
;
2391 if (SendPacketAndWaitForResponse(packet
, response
) ==
2392 PacketResult::Success
) {
2393 if (response
.IsNormalResponse()) {
2394 // Make sure we parsed the right number of characters. The response is
2395 // the hex encoded user name and should make up the entire packet. If
2396 // there are any non-hex ASCII bytes, the length won't match below..
2397 if (response
.GetHexByteString(name
) * 2 ==
2398 response
.GetStringRef().size())
2402 m_supports_qUserName
= false;
2409 bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid
,
2410 std::string
&name
) {
2411 if (m_supports_qGroupName
) {
2413 const int packet_len
=
2414 ::snprintf(packet
, sizeof(packet
), "qGroupName:%i", gid
);
2415 assert(packet_len
< (int)sizeof(packet
));
2416 UNUSED_IF_ASSERT_DISABLED(packet_len
);
2417 StringExtractorGDBRemote response
;
2418 if (SendPacketAndWaitForResponse(packet
, response
) ==
2419 PacketResult::Success
) {
2420 if (response
.IsNormalResponse()) {
2421 // Make sure we parsed the right number of characters. The response is
2422 // the hex encoded group name and should make up the entire packet. If
2423 // there are any non-hex ASCII bytes, the length won't match below..
2424 if (response
.GetHexByteString(name
) * 2 ==
2425 response
.GetStringRef().size())
2429 m_supports_qGroupName
= false;
2436 static void MakeSpeedTestPacket(StreamString
&packet
, uint32_t send_size
,
2437 uint32_t recv_size
) {
2439 packet
.Printf("qSpeedTest:response_size:%i;data:", recv_size
);
2440 uint32_t bytes_left
= send_size
;
2441 while (bytes_left
> 0) {
2442 if (bytes_left
>= 26) {
2443 packet
.PutCString("abcdefghijklmnopqrstuvwxyz");
2446 packet
.Printf("%*.*s;", bytes_left
, bytes_left
,
2447 "abcdefghijklmnopqrstuvwxyz");
2454 calculate_standard_deviation(const std::vector
<duration
<float>> &v
) {
2456 return duration
<float>::zero();
2457 using Dur
= duration
<float>;
2458 Dur sum
= std::accumulate(std::begin(v
), std::end(v
), Dur());
2459 Dur mean
= sum
/ v
.size();
2462 float delta
= (d
- mean
).count();
2463 accum
+= delta
* delta
;
2466 return Dur(sqrtf(accum
/ (v
.size() - 1)));
2469 void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets
,
2472 uint64_t recv_amount
,
2473 bool json
, Stream
&strm
) {
2475 if (SendSpeedTestPacket(0, 0)) {
2476 StreamString packet
;
2478 strm
.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2482 strm
.Printf("Testing sending %u packets of various sizes:\n",
2486 uint32_t result_idx
= 0;
2488 std::vector
<duration
<float>> packet_times
;
2490 for (send_size
= 0; send_size
<= max_send
;
2491 send_size
? send_size
*= 2 : send_size
= 4) {
2492 for (uint32_t recv_size
= 0; recv_size
<= max_recv
;
2493 recv_size
? recv_size
*= 2 : recv_size
= 4) {
2494 MakeSpeedTestPacket(packet
, send_size
, recv_size
);
2496 packet_times
.clear();
2497 // Test how long it takes to send 'num_packets' packets
2498 const auto start_time
= steady_clock::now();
2499 for (uint32_t i
= 0; i
< num_packets
; ++i
) {
2500 const auto packet_start_time
= steady_clock::now();
2501 StringExtractorGDBRemote response
;
2502 SendPacketAndWaitForResponse(packet
.GetString(), response
);
2503 const auto packet_end_time
= steady_clock::now();
2504 packet_times
.push_back(packet_end_time
- packet_start_time
);
2506 const auto end_time
= steady_clock::now();
2507 const auto total_time
= end_time
- start_time
;
2509 float packets_per_second
=
2510 ((float)num_packets
) / duration
<float>(total_time
).count();
2511 auto average_per_packet
= num_packets
> 0 ? total_time
/ num_packets
2512 : duration
<float>::zero();
2513 const duration
<float> standard_deviation
=
2514 calculate_standard_deviation(packet_times
);
2516 strm
.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2517 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2518 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2519 result_idx
> 0 ? "," : "", send_size
, recv_size
,
2520 total_time
, standard_deviation
);
2523 strm
.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2524 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2525 "standard deviation of {5,10:ms+f6}\n",
2526 send_size
, recv_size
, duration
<float>(total_time
),
2527 packets_per_second
, duration
<float>(average_per_packet
),
2528 standard_deviation
);
2534 const float k_recv_amount_mb
= (float)recv_amount
/ (1024.0f
* 1024.0f
);
2536 strm
.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2537 ": %" PRIu64
",\n \"results\" : [",
2540 strm
.Printf("Testing receiving %2.1fMB of data using varying receive "
2546 for (uint32_t recv_size
= 32; recv_size
<= max_recv
; recv_size
*= 2) {
2547 MakeSpeedTestPacket(packet
, send_size
, recv_size
);
2549 // If we have a receive size, test how long it takes to receive 4MB of
2551 if (recv_size
> 0) {
2552 const auto start_time
= steady_clock::now();
2553 uint32_t bytes_read
= 0;
2554 uint32_t packet_count
= 0;
2555 while (bytes_read
< recv_amount
) {
2556 StringExtractorGDBRemote response
;
2557 SendPacketAndWaitForResponse(packet
.GetString(), response
);
2558 bytes_read
+= recv_size
;
2561 const auto end_time
= steady_clock::now();
2562 const auto total_time
= end_time
- start_time
;
2563 float mb_second
= ((float)recv_amount
) /
2564 duration
<float>(total_time
).count() /
2566 float packets_per_second
=
2567 ((float)packet_count
) / duration
<float>(total_time
).count();
2568 const auto average_per_packet
= packet_count
> 0
2569 ? total_time
/ packet_count
2570 : duration
<float>::zero();
2573 strm
.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2574 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2575 result_idx
> 0 ? "," : "", send_size
, recv_size
,
2579 strm
.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2580 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2581 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2582 send_size
, recv_size
, packet_count
, k_recv_amount_mb
,
2583 duration
<float>(total_time
), mb_second
,
2584 packets_per_second
, duration
<float>(average_per_packet
));
2590 strm
.Printf("\n ]\n }\n}\n");
2596 bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size
,
2597 uint32_t recv_size
) {
2598 StreamString packet
;
2599 packet
.Printf("qSpeedTest:response_size:%i;data:", recv_size
);
2600 uint32_t bytes_left
= send_size
;
2601 while (bytes_left
> 0) {
2602 if (bytes_left
>= 26) {
2603 packet
.PutCString("abcdefghijklmnopqrstuvwxyz");
2606 packet
.Printf("%*.*s;", bytes_left
, bytes_left
,
2607 "abcdefghijklmnopqrstuvwxyz");
2612 StringExtractorGDBRemote response
;
2613 return SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
2614 PacketResult::Success
;
2617 bool GDBRemoteCommunicationClient::LaunchGDBServer(
2618 const char *remote_accept_hostname
, lldb::pid_t
&pid
, uint16_t &port
,
2619 std::string
&socket_name
) {
2620 pid
= LLDB_INVALID_PROCESS_ID
;
2622 socket_name
.clear();
2624 StringExtractorGDBRemote response
;
2625 StreamString stream
;
2626 stream
.PutCString("qLaunchGDBServer;");
2627 std::string hostname
;
2628 if (remote_accept_hostname
&& remote_accept_hostname
[0])
2629 hostname
= remote_accept_hostname
;
2631 if (HostInfo::GetHostname(hostname
)) {
2632 // Make the GDB server we launch only accept connections from this host
2633 stream
.Printf("host:%s;", hostname
.c_str());
2635 // Make the GDB server we launch accept connections from any host since
2636 // we can't figure out the hostname
2637 stream
.Printf("host:*;");
2640 // give the process a few seconds to startup
2641 ScopedTimeout
timeout(*this, seconds(10));
2643 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
2644 PacketResult::Success
) {
2645 if (response
.IsErrorResponse())
2648 llvm::StringRef name
;
2649 llvm::StringRef value
;
2650 while (response
.GetNameColonValue(name
, value
)) {
2652 value
.getAsInteger(0, port
);
2653 else if (name
== "pid")
2654 value
.getAsInteger(0, pid
);
2655 else if (name
.compare("socket_name") == 0) {
2656 StringExtractor
extractor(value
);
2657 extractor
.GetHexByteString(socket_name
);
2665 size_t GDBRemoteCommunicationClient::QueryGDBServer(
2666 std::vector
<std::pair
<uint16_t, std::string
>> &connection_urls
) {
2667 connection_urls
.clear();
2669 StringExtractorGDBRemote response
;
2670 if (SendPacketAndWaitForResponse("qQueryGDBServer", response
) !=
2671 PacketResult::Success
)
2674 StructuredData::ObjectSP data
=
2675 StructuredData::ParseJSON(response
.GetStringRef());
2679 StructuredData::Array
*array
= data
->GetAsArray();
2683 for (size_t i
= 0, count
= array
->GetSize(); i
< count
; ++i
) {
2684 std::optional
<StructuredData::Dictionary
*> maybe_element
=
2685 array
->GetItemAtIndexAsDictionary(i
);
2689 StructuredData::Dictionary
*element
= *maybe_element
;
2691 if (StructuredData::ObjectSP port_osp
=
2692 element
->GetValueForKey(llvm::StringRef("port")))
2693 port
= port_osp
->GetUnsignedIntegerValue(0);
2695 std::string socket_name
;
2696 if (StructuredData::ObjectSP socket_name_osp
=
2697 element
->GetValueForKey(llvm::StringRef("socket_name")))
2698 socket_name
= std::string(socket_name_osp
->GetStringValue());
2700 if (port
!= 0 || !socket_name
.empty())
2701 connection_urls
.emplace_back(port
, socket_name
);
2703 return connection_urls
.size();
2706 bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid
) {
2707 StreamString stream
;
2708 stream
.Printf("qKillSpawnedProcess:%" PRId64
, pid
);
2710 StringExtractorGDBRemote response
;
2711 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
2712 PacketResult::Success
) {
2713 if (response
.IsOKResponse())
2719 std::optional
<PidTid
> GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(
2720 uint64_t tid
, uint64_t pid
, char op
) {
2721 lldb_private::StreamString packet
;
2722 packet
.PutChar('H');
2725 if (pid
!= LLDB_INVALID_PROCESS_ID
)
2726 packet
.Printf("p%" PRIx64
".", pid
);
2728 if (tid
== UINT64_MAX
)
2729 packet
.PutCString("-1");
2731 packet
.Printf("%" PRIx64
, tid
);
2733 StringExtractorGDBRemote response
;
2734 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
2735 PacketResult::Success
) {
2736 if (response
.IsOKResponse())
2737 return {{pid
, tid
}};
2740 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2742 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2744 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2746 if (response
.IsUnsupportedResponse() && IsConnected())
2749 return std::nullopt
;
2752 bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid
,
2754 if (m_curr_tid
== tid
&&
2755 (m_curr_pid
== pid
|| LLDB_INVALID_PROCESS_ID
== pid
))
2758 std::optional
<PidTid
> ret
= SendSetCurrentThreadPacket(tid
, pid
, 'g');
2760 if (ret
->pid
!= LLDB_INVALID_PROCESS_ID
)
2761 m_curr_pid
= ret
->pid
;
2762 m_curr_tid
= ret
->tid
;
2764 return ret
.has_value();
2767 bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid
,
2769 if (m_curr_tid_run
== tid
&&
2770 (m_curr_pid_run
== pid
|| LLDB_INVALID_PROCESS_ID
== pid
))
2773 std::optional
<PidTid
> ret
= SendSetCurrentThreadPacket(tid
, pid
, 'c');
2775 if (ret
->pid
!= LLDB_INVALID_PROCESS_ID
)
2776 m_curr_pid_run
= ret
->pid
;
2777 m_curr_tid_run
= ret
->tid
;
2779 return ret
.has_value();
2782 bool GDBRemoteCommunicationClient::GetStopReply(
2783 StringExtractorGDBRemote
&response
) {
2784 if (SendPacketAndWaitForResponse("?", response
) == PacketResult::Success
)
2785 return response
.IsNormalResponse();
2789 bool GDBRemoteCommunicationClient::GetThreadStopInfo(
2790 lldb::tid_t tid
, StringExtractorGDBRemote
&response
) {
2791 if (m_supports_qThreadStopInfo
) {
2794 ::snprintf(packet
, sizeof(packet
), "qThreadStopInfo%" PRIx64
, tid
);
2795 assert(packet_len
< (int)sizeof(packet
));
2796 UNUSED_IF_ASSERT_DISABLED(packet_len
);
2797 if (SendPacketAndWaitForResponse(packet
, response
) ==
2798 PacketResult::Success
) {
2799 if (response
.IsUnsupportedResponse())
2800 m_supports_qThreadStopInfo
= false;
2801 else if (response
.IsNormalResponse())
2806 m_supports_qThreadStopInfo
= false;
2812 uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
2813 GDBStoppointType type
, bool insert
, addr_t addr
, uint32_t length
,
2814 std::chrono::seconds timeout
) {
2815 Log
*log
= GetLog(LLDBLog::Breakpoints
);
2816 LLDB_LOGF(log
, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64
,
2817 __FUNCTION__
, insert
? "add" : "remove", addr
);
2819 // Check if the stub is known not to support this breakpoint type
2820 if (!SupportsGDBStoppointPacket(type
))
2822 // Construct the breakpoint packet
2824 const int packet_len
=
2825 ::snprintf(packet
, sizeof(packet
), "%c%i,%" PRIx64
",%x",
2826 insert
? 'Z' : 'z', type
, addr
, length
);
2827 // Check we haven't overwritten the end of the packet buffer
2828 assert(packet_len
+ 1 < (int)sizeof(packet
));
2829 UNUSED_IF_ASSERT_DISABLED(packet_len
);
2830 StringExtractorGDBRemote response
;
2831 // Make sure the response is either "OK", "EXX" where XX are two hex digits,
2832 // or "" (unsupported)
2833 response
.SetResponseValidatorToOKErrorNotSupported();
2834 // Try to send the breakpoint packet, and check that it was correctly sent
2835 if (SendPacketAndWaitForResponse(packet
, response
, timeout
) ==
2836 PacketResult::Success
) {
2837 // Receive and OK packet when the breakpoint successfully placed
2838 if (response
.IsOKResponse())
2841 // Status while setting breakpoint, send back specific error
2842 if (response
.IsErrorResponse())
2843 return response
.GetError();
2845 // Empty packet informs us that breakpoint is not supported
2846 if (response
.IsUnsupportedResponse()) {
2847 // Disable this breakpoint type since it is unsupported
2849 case eBreakpointSoftware
:
2850 m_supports_z0
= false;
2852 case eBreakpointHardware
:
2853 m_supports_z1
= false;
2855 case eWatchpointWrite
:
2856 m_supports_z2
= false;
2858 case eWatchpointRead
:
2859 m_supports_z3
= false;
2861 case eWatchpointReadWrite
:
2862 m_supports_z4
= false;
2864 case eStoppointInvalid
:
2869 // Signal generic failure
2873 std::vector
<std::pair
<lldb::pid_t
, lldb::tid_t
>>
2874 GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs(
2875 bool &sequence_mutex_unavailable
) {
2876 std::vector
<std::pair
<lldb::pid_t
, lldb::tid_t
>> ids
;
2880 sequence_mutex_unavailable
= false;
2881 StringExtractorGDBRemote response
;
2883 PacketResult packet_result
;
2884 for (packet_result
=
2885 SendPacketAndWaitForResponseNoLock("qfThreadInfo", response
);
2886 packet_result
== PacketResult::Success
&& response
.IsNormalResponse();
2888 SendPacketAndWaitForResponseNoLock("qsThreadInfo", response
)) {
2889 char ch
= response
.GetChar();
2894 auto pid_tid
= response
.GetPidTid(LLDB_INVALID_PROCESS_ID
);
2895 // If we get an invalid response, break out of the loop.
2896 // If there are valid tids, they have been added to ids.
2897 // If there are no valid tids, we'll fall through to the
2898 // bare-iron target handling below.
2902 ids
.push_back(*pid_tid
);
2903 ch
= response
.GetChar(); // Skip the command separator
2904 } while (ch
== ','); // Make sure we got a comma separator
2909 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2910 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
2912 * be as simple as 'S05'. There is no packet which can give us pid and/or
2914 * Assume pid=tid=1 in such cases.
2916 if ((response
.IsUnsupportedResponse() || response
.IsNormalResponse()) &&
2917 ids
.size() == 0 && IsConnected()) {
2918 ids
.emplace_back(1, 1);
2921 Log
*log(GetLog(GDBRLog::Process
| GDBRLog::Packets
));
2922 LLDB_LOG(log
, "error: failed to get packet sequence mutex, not sending "
2923 "packet 'qfThreadInfo'");
2924 sequence_mutex_unavailable
= true;
2930 size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2931 std::vector
<lldb::tid_t
> &thread_ids
, bool &sequence_mutex_unavailable
) {
2932 lldb::pid_t pid
= GetCurrentProcessID();
2935 auto ids
= GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable
);
2936 if (ids
.empty() || sequence_mutex_unavailable
)
2939 for (auto id
: ids
) {
2940 // skip threads that do not belong to the current process
2941 if (id
.first
!= LLDB_INVALID_PROCESS_ID
&& id
.first
!= pid
)
2943 if (id
.second
!= LLDB_INVALID_THREAD_ID
&&
2944 id
.second
!= StringExtractorGDBRemote::AllThreads
)
2945 thread_ids
.push_back(id
.second
);
2948 return thread_ids
.size();
2951 lldb::addr_t
GDBRemoteCommunicationClient::GetShlibInfoAddr() {
2952 StringExtractorGDBRemote response
;
2953 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response
) !=
2954 PacketResult::Success
||
2955 !response
.IsNormalResponse())
2956 return LLDB_INVALID_ADDRESS
;
2957 return response
.GetHexMaxU64(false, LLDB_INVALID_ADDRESS
);
2960 lldb_private::Status
GDBRemoteCommunicationClient::RunShellCommand(
2961 llvm::StringRef command
,
2963 working_dir
, // Pass empty FileSpec to use the current working directory
2964 int *status_ptr
, // Pass NULL if you don't want the process exit status
2965 int *signo_ptr
, // Pass NULL if you don't want the signal that caused the
2968 *command_output
, // Pass NULL if you don't want the command output
2969 const Timeout
<std::micro
> &timeout
) {
2970 lldb_private::StreamString stream
;
2971 stream
.PutCString("qPlatform_shell:");
2972 stream
.PutBytesAsRawHex8(command
.data(), command
.size());
2973 stream
.PutChar(',');
2974 uint32_t timeout_sec
= UINT32_MAX
;
2976 // TODO: Use chrono version of std::ceil once c++17 is available.
2977 timeout_sec
= std::ceil(std::chrono::duration
<double>(*timeout
).count());
2979 stream
.PutHex32(timeout_sec
);
2981 std::string path
{working_dir
.GetPath(false)};
2982 stream
.PutChar(',');
2983 stream
.PutStringAsRawHex8(path
);
2985 StringExtractorGDBRemote response
;
2986 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
2987 PacketResult::Success
) {
2988 if (response
.GetChar() != 'F')
2989 return Status::FromErrorString("malformed reply");
2990 if (response
.GetChar() != ',')
2991 return Status::FromErrorString("malformed reply");
2992 uint32_t exitcode
= response
.GetHexMaxU32(false, UINT32_MAX
);
2993 if (exitcode
== UINT32_MAX
)
2994 return Status::FromErrorString("unable to run remote process");
2995 else if (status_ptr
)
2996 *status_ptr
= exitcode
;
2997 if (response
.GetChar() != ',')
2998 return Status::FromErrorString("malformed reply");
2999 uint32_t signo
= response
.GetHexMaxU32(false, UINT32_MAX
);
3002 if (response
.GetChar() != ',')
3003 return Status::FromErrorString("malformed reply");
3005 response
.GetEscapedBinaryData(output
);
3007 command_output
->assign(output
);
3010 return Status::FromErrorString("unable to send packet");
3013 Status
GDBRemoteCommunicationClient::MakeDirectory(const FileSpec
&file_spec
,
3014 uint32_t file_permissions
) {
3015 std::string path
{file_spec
.GetPath(false)};
3016 lldb_private::StreamString stream
;
3017 stream
.PutCString("qPlatform_mkdir:");
3018 stream
.PutHex32(file_permissions
);
3019 stream
.PutChar(',');
3020 stream
.PutStringAsRawHex8(path
);
3021 llvm::StringRef packet
= stream
.GetString();
3022 StringExtractorGDBRemote response
;
3024 if (SendPacketAndWaitForResponse(packet
, response
) != PacketResult::Success
)
3025 return Status::FromErrorStringWithFormat("failed to send '%s' packet",
3026 packet
.str().c_str());
3028 if (response
.GetChar() != 'F')
3029 return Status::FromErrorStringWithFormat("invalid response to '%s' packet",
3030 packet
.str().c_str());
3032 return Status(response
.GetHexMaxU32(false, UINT32_MAX
), eErrorTypePOSIX
);
3036 GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec
&file_spec
,
3037 uint32_t file_permissions
) {
3038 std::string path
{file_spec
.GetPath(false)};
3039 lldb_private::StreamString stream
;
3040 stream
.PutCString("qPlatform_chmod:");
3041 stream
.PutHex32(file_permissions
);
3042 stream
.PutChar(',');
3043 stream
.PutStringAsRawHex8(path
);
3044 llvm::StringRef packet
= stream
.GetString();
3045 StringExtractorGDBRemote response
;
3047 if (SendPacketAndWaitForResponse(packet
, response
) != PacketResult::Success
)
3048 return Status::FromErrorStringWithFormat("failed to send '%s' packet",
3051 if (response
.GetChar() != 'F')
3052 return Status::FromErrorStringWithFormat("invalid response to '%s' packet",
3055 return Status(response
.GetHexMaxU32(false, UINT32_MAX
), eErrorTypePOSIX
);
3058 static int gdb_errno_to_system(int err
) {
3060 #define HANDLE_ERRNO(name, value) \
3063 #include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
3069 static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote
&response
,
3070 uint64_t fail_result
, Status
&error
) {
3071 response
.SetFilePos(0);
3072 if (response
.GetChar() != 'F')
3074 int32_t result
= response
.GetS32(-2, 16);
3077 if (response
.GetChar() == ',') {
3078 int result_errno
= gdb_errno_to_system(response
.GetS32(-1, 16));
3079 if (result_errno
!= -1)
3080 error
= Status(result_errno
, eErrorTypePOSIX
);
3082 error
= Status(-1, eErrorTypeGeneric
);
3088 GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec
&file_spec
,
3089 File::OpenOptions flags
, mode_t mode
,
3091 std::string
path(file_spec
.GetPath(false));
3092 lldb_private::StreamString stream
;
3093 stream
.PutCString("vFile:open:");
3096 stream
.PutStringAsRawHex8(path
);
3097 stream
.PutChar(',');
3098 stream
.PutHex32(flags
);
3099 stream
.PutChar(',');
3100 stream
.PutHex32(mode
);
3101 StringExtractorGDBRemote response
;
3102 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
3103 PacketResult::Success
) {
3104 return ParseHostIOPacketResponse(response
, UINT64_MAX
, error
);
3109 bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd
,
3111 lldb_private::StreamString stream
;
3112 stream
.Printf("vFile:close:%x", (int)fd
);
3113 StringExtractorGDBRemote response
;
3114 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
3115 PacketResult::Success
) {
3116 return ParseHostIOPacketResponse(response
, -1, error
) == 0;
3121 std::optional
<GDBRemoteFStatData
>
3122 GDBRemoteCommunicationClient::FStat(lldb::user_id_t fd
) {
3123 lldb_private::StreamString stream
;
3124 stream
.Printf("vFile:fstat:%" PRIx64
, fd
);
3125 StringExtractorGDBRemote response
;
3126 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
3127 PacketResult::Success
) {
3128 if (response
.GetChar() != 'F')
3129 return std::nullopt
;
3130 int64_t size
= response
.GetS64(-1, 16);
3131 if (size
> 0 && response
.GetChar() == ';') {
3133 if (response
.GetEscapedBinaryData(buffer
)) {
3134 GDBRemoteFStatData out
;
3135 if (buffer
.size() != sizeof(out
))
3136 return std::nullopt
;
3137 memcpy(&out
, buffer
.data(), sizeof(out
));
3142 return std::nullopt
;
3145 std::optional
<GDBRemoteFStatData
>
3146 GDBRemoteCommunicationClient::Stat(const lldb_private::FileSpec
&file_spec
) {
3148 lldb::user_id_t fd
= OpenFile(file_spec
, File::eOpenOptionReadOnly
, 0, error
);
3149 if (fd
== UINT64_MAX
)
3150 return std::nullopt
;
3151 std::optional
<GDBRemoteFStatData
> st
= FStat(fd
);
3152 CloseFile(fd
, error
);
3156 // Extension of host I/O packets to get the file size.
3157 lldb::user_id_t
GDBRemoteCommunicationClient::GetFileSize(
3158 const lldb_private::FileSpec
&file_spec
) {
3159 if (m_supports_vFileSize
) {
3160 std::string
path(file_spec
.GetPath(false));
3161 lldb_private::StreamString stream
;
3162 stream
.PutCString("vFile:size:");
3163 stream
.PutStringAsRawHex8(path
);
3164 StringExtractorGDBRemote response
;
3165 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) !=
3166 PacketResult::Success
)
3169 if (!response
.IsUnsupportedResponse()) {
3170 if (response
.GetChar() != 'F')
3172 uint32_t retcode
= response
.GetHexMaxU64(false, UINT64_MAX
);
3175 m_supports_vFileSize
= false;
3178 // Fallback to fstat.
3179 std::optional
<GDBRemoteFStatData
> st
= Stat(file_spec
);
3180 return st
? st
->gdb_st_size
: UINT64_MAX
;
3183 void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory(
3184 CompletionRequest
&request
, bool only_dir
) {
3185 lldb_private::StreamString stream
;
3186 stream
.PutCString("qPathComplete:");
3187 stream
.PutHex32(only_dir
? 1 : 0);
3188 stream
.PutChar(',');
3189 stream
.PutStringAsRawHex8(request
.GetCursorArgumentPrefix());
3190 StringExtractorGDBRemote response
;
3191 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
3192 PacketResult::Success
) {
3194 char ch
= response
.GetChar();
3197 while (response
.Peek()) {
3199 while ((ch
= response
.GetHexU8(0, false)) != '\0')
3201 request
.AddCompletion(strm
.GetString());
3202 if (response
.GetChar() != ',')
3209 GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec
&file_spec
,
3210 uint32_t &file_permissions
) {
3211 if (m_supports_vFileMode
) {
3212 std::string path
{file_spec
.GetPath(false)};
3214 lldb_private::StreamString stream
;
3215 stream
.PutCString("vFile:mode:");
3216 stream
.PutStringAsRawHex8(path
);
3217 StringExtractorGDBRemote response
;
3218 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) !=
3219 PacketResult::Success
) {
3220 error
= Status::FromErrorStringWithFormat("failed to send '%s' packet",
3224 if (!response
.IsUnsupportedResponse()) {
3225 if (response
.GetChar() != 'F') {
3226 error
= Status::FromErrorStringWithFormat(
3227 "invalid response to '%s' packet", stream
.GetData());
3229 const uint32_t mode
= response
.GetS32(-1, 16);
3230 if (static_cast<int32_t>(mode
) == -1) {
3231 if (response
.GetChar() == ',') {
3232 int response_errno
= gdb_errno_to_system(response
.GetS32(-1, 16));
3233 if (response_errno
> 0)
3234 error
= Status(response_errno
, lldb::eErrorTypePOSIX
);
3236 error
= Status::FromErrorString("unknown error");
3238 error
= Status::FromErrorString("unknown error");
3240 file_permissions
= mode
& (S_IRWXU
| S_IRWXG
| S_IRWXO
);
3244 } else { // response.IsUnsupportedResponse()
3245 m_supports_vFileMode
= false;
3249 // Fallback to fstat.
3250 if (std::optional
<GDBRemoteFStatData
> st
= Stat(file_spec
)) {
3251 file_permissions
= st
->gdb_st_mode
& (S_IRWXU
| S_IRWXG
| S_IRWXO
);
3254 return Status::FromErrorString("fstat failed");
3257 uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd
,
3258 uint64_t offset
, void *dst
,
3261 lldb_private::StreamString stream
;
3262 stream
.Printf("vFile:pread:%x,%" PRIx64
",%" PRIx64
, (int)fd
, dst_len
,
3264 StringExtractorGDBRemote response
;
3265 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
3266 PacketResult::Success
) {
3267 if (response
.GetChar() != 'F')
3269 int64_t retcode
= response
.GetS64(-1, 16);
3270 if (retcode
== -1) {
3271 error
= Status::FromErrorString("unknown error");
3272 if (response
.GetChar() == ',') {
3273 int response_errno
= gdb_errno_to_system(response
.GetS32(-1, 16));
3274 if (response_errno
> 0)
3275 error
= Status(response_errno
, lldb::eErrorTypePOSIX
);
3279 const char next
= (response
.Peek() ? *response
.Peek() : 0);
3283 response
.GetChar(); // skip the semicolon
3285 if (response
.GetEscapedBinaryData(buffer
)) {
3286 const uint64_t data_to_write
=
3287 std::min
<uint64_t>(dst_len
, buffer
.size());
3288 if (data_to_write
> 0)
3289 memcpy(dst
, &buffer
[0], data_to_write
);
3290 return data_to_write
;
3297 uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd
,
3302 lldb_private::StreamGDBRemote stream
;
3303 stream
.Printf("vFile:pwrite:%x,%" PRIx64
",", (int)fd
, offset
);
3304 stream
.PutEscapedBytes(src
, src_len
);
3305 StringExtractorGDBRemote response
;
3306 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
3307 PacketResult::Success
) {
3308 if (response
.GetChar() != 'F') {
3309 error
= Status::FromErrorStringWithFormat("write file failed");
3312 int64_t bytes_written
= response
.GetS64(-1, 16);
3313 if (bytes_written
== -1) {
3314 error
= Status::FromErrorString("unknown error");
3315 if (response
.GetChar() == ',') {
3316 int response_errno
= gdb_errno_to_system(response
.GetS32(-1, 16));
3317 if (response_errno
> 0)
3318 error
= Status(response_errno
, lldb::eErrorTypePOSIX
);
3322 return bytes_written
;
3324 error
= Status::FromErrorString("failed to send vFile:pwrite packet");
3329 Status
GDBRemoteCommunicationClient::CreateSymlink(const FileSpec
&src
,
3330 const FileSpec
&dst
) {
3331 std::string src_path
{src
.GetPath(false)}, dst_path
{dst
.GetPath(false)};
3333 lldb_private::StreamGDBRemote stream
;
3334 stream
.PutCString("vFile:symlink:");
3335 // the unix symlink() command reverses its parameters where the dst if first,
3336 // so we follow suit here
3337 stream
.PutStringAsRawHex8(dst_path
);
3338 stream
.PutChar(',');
3339 stream
.PutStringAsRawHex8(src_path
);
3340 StringExtractorGDBRemote response
;
3341 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
3342 PacketResult::Success
) {
3343 if (response
.GetChar() == 'F') {
3344 uint32_t result
= response
.GetHexMaxU32(false, UINT32_MAX
);
3346 error
= Status::FromErrorString("unknown error");
3347 if (response
.GetChar() == ',') {
3348 int response_errno
= gdb_errno_to_system(response
.GetS32(-1, 16));
3349 if (response_errno
> 0)
3350 error
= Status(response_errno
, lldb::eErrorTypePOSIX
);
3354 // Should have returned with 'F<result>[,<errno>]'
3355 error
= Status::FromErrorStringWithFormat("symlink failed");
3358 error
= Status::FromErrorString("failed to send vFile:symlink packet");
3363 Status
GDBRemoteCommunicationClient::Unlink(const FileSpec
&file_spec
) {
3364 std::string path
{file_spec
.GetPath(false)};
3366 lldb_private::StreamGDBRemote stream
;
3367 stream
.PutCString("vFile:unlink:");
3368 // the unix symlink() command reverses its parameters where the dst if first,
3369 // so we follow suit here
3370 stream
.PutStringAsRawHex8(path
);
3371 StringExtractorGDBRemote response
;
3372 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
3373 PacketResult::Success
) {
3374 if (response
.GetChar() == 'F') {
3375 uint32_t result
= response
.GetHexMaxU32(false, UINT32_MAX
);
3377 error
= Status::FromErrorString("unknown error");
3378 if (response
.GetChar() == ',') {
3379 int response_errno
= gdb_errno_to_system(response
.GetS32(-1, 16));
3380 if (response_errno
> 0)
3381 error
= Status(response_errno
, lldb::eErrorTypePOSIX
);
3385 // Should have returned with 'F<result>[,<errno>]'
3386 error
= Status::FromErrorStringWithFormat("unlink failed");
3389 error
= Status::FromErrorString("failed to send vFile:unlink packet");
3394 // Extension of host I/O packets to get whether a file exists.
3395 bool GDBRemoteCommunicationClient::GetFileExists(
3396 const lldb_private::FileSpec
&file_spec
) {
3397 if (m_supports_vFileExists
) {
3398 std::string
path(file_spec
.GetPath(false));
3399 lldb_private::StreamString stream
;
3400 stream
.PutCString("vFile:exists:");
3401 stream
.PutStringAsRawHex8(path
);
3402 StringExtractorGDBRemote response
;
3403 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) !=
3404 PacketResult::Success
)
3406 if (!response
.IsUnsupportedResponse()) {
3407 if (response
.GetChar() != 'F')
3409 if (response
.GetChar() != ',')
3411 bool retcode
= (response
.GetChar() != '0');
3414 m_supports_vFileExists
= false;
3417 // Fallback to open.
3419 lldb::user_id_t fd
= OpenFile(file_spec
, File::eOpenOptionReadOnly
, 0, error
);
3420 if (fd
== UINT64_MAX
)
3422 CloseFile(fd
, error
);
3426 llvm::ErrorOr
<llvm::MD5::MD5Result
> GDBRemoteCommunicationClient::CalculateMD5(
3427 const lldb_private::FileSpec
&file_spec
) {
3428 std::string
path(file_spec
.GetPath(false));
3429 lldb_private::StreamString stream
;
3430 stream
.PutCString("vFile:MD5:");
3431 stream
.PutStringAsRawHex8(path
);
3432 StringExtractorGDBRemote response
;
3433 if (SendPacketAndWaitForResponse(stream
.GetString(), response
) ==
3434 PacketResult::Success
) {
3435 if (response
.GetChar() != 'F')
3436 return std::make_error_code(std::errc::illegal_byte_sequence
);
3437 if (response
.GetChar() != ',')
3438 return std::make_error_code(std::errc::illegal_byte_sequence
);
3439 if (response
.Peek() && *response
.Peek() == 'x')
3440 return std::make_error_code(std::errc::no_such_file_or_directory
);
3442 // GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 concatenates low and
3443 // high hex strings. We can't use response.GetHexMaxU64 because that can't
3444 // handle the concatenated hex string. What would happen is parsing the low
3445 // would consume the whole response packet which would give incorrect
3446 // results. Instead, we get the byte string for each low and high hex
3447 // separately, and parse them.
3449 // An alternate way to handle this is to change the server to put a
3450 // delimiter between the low/high parts, and change the client to parse the
3451 // delimiter. However, we choose not to do this so existing lldb-servers
3452 // don't have to be patched
3454 // The checksum is 128 bits encoded as hex
3455 // This means low/high are halves of 64 bits each, in otherwords, 8 bytes.
3456 // Each byte takes 2 hex characters in the response.
3457 const size_t MD5_HALF_LENGTH
= sizeof(uint64_t) * 2;
3461 response
.GetStringRef().substr(response
.GetFilePos(), MD5_HALF_LENGTH
);
3462 if (part
.size() != MD5_HALF_LENGTH
)
3463 return std::make_error_code(std::errc::illegal_byte_sequence
);
3464 response
.SetFilePos(response
.GetFilePos() + part
.size());
3467 if (part
.getAsInteger(/*radix=*/16, low
))
3468 return std::make_error_code(std::errc::illegal_byte_sequence
);
3472 response
.GetStringRef().substr(response
.GetFilePos(), MD5_HALF_LENGTH
);
3473 if (part
.size() != MD5_HALF_LENGTH
)
3474 return std::make_error_code(std::errc::illegal_byte_sequence
);
3475 response
.SetFilePos(response
.GetFilePos() + part
.size());
3478 if (part
.getAsInteger(/*radix=*/16, high
))
3479 return std::make_error_code(std::errc::illegal_byte_sequence
);
3481 llvm::MD5::MD5Result result
;
3482 llvm::support::endian::write
<uint64_t, llvm::endianness::little
>(
3483 result
.data(), low
);
3484 llvm::support::endian::write
<uint64_t, llvm::endianness::little
>(
3485 result
.data() + 8, high
);
3489 return std::make_error_code(std::errc::operation_canceled
);
3492 bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote
*process
) {
3493 // Some targets have issues with g/G packets and we need to avoid using them
3494 if (m_avoid_g_packets
== eLazyBoolCalculate
) {
3496 m_avoid_g_packets
= eLazyBoolNo
;
3497 const ArchSpec
&arch
= process
->GetTarget().GetArchitecture();
3498 if (arch
.IsValid() &&
3499 arch
.GetTriple().getVendor() == llvm::Triple::Apple
&&
3500 arch
.GetTriple().getOS() == llvm::Triple::IOS
&&
3501 (arch
.GetTriple().getArch() == llvm::Triple::aarch64
||
3502 arch
.GetTriple().getArch() == llvm::Triple::aarch64_32
)) {
3503 m_avoid_g_packets
= eLazyBoolYes
;
3504 uint32_t gdb_server_version
= GetGDBServerProgramVersion();
3505 if (gdb_server_version
!= 0) {
3506 const char *gdb_server_name
= GetGDBServerProgramName();
3507 if (gdb_server_name
&& strcmp(gdb_server_name
, "debugserver") == 0) {
3508 if (gdb_server_version
>= 310)
3509 m_avoid_g_packets
= eLazyBoolNo
;
3515 return m_avoid_g_packets
== eLazyBoolYes
;
3518 DataBufferSP
GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid
,
3520 StreamString payload
;
3521 payload
.Printf("p%x", reg
);
3522 StringExtractorGDBRemote response
;
3523 if (SendThreadSpecificPacketAndWaitForResponse(
3524 tid
, std::move(payload
), response
) != PacketResult::Success
||
3525 !response
.IsNormalResponse())
3528 WritableDataBufferSP
buffer_sp(
3529 new DataBufferHeap(response
.GetStringRef().size() / 2, 0));
3530 response
.GetHexBytes(buffer_sp
->GetData(), '\xcc');
3534 DataBufferSP
GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid
) {
3535 StreamString payload
;
3536 payload
.PutChar('g');
3537 StringExtractorGDBRemote response
;
3538 if (SendThreadSpecificPacketAndWaitForResponse(
3539 tid
, std::move(payload
), response
) != PacketResult::Success
||
3540 !response
.IsNormalResponse())
3543 WritableDataBufferSP
buffer_sp(
3544 new DataBufferHeap(response
.GetStringRef().size() / 2, 0));
3545 response
.GetHexBytes(buffer_sp
->GetData(), '\xcc');
3549 bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid
,
3551 llvm::ArrayRef
<uint8_t> data
) {
3552 StreamString payload
;
3553 payload
.Printf("P%x=", reg_num
);
3554 payload
.PutBytesAsRawHex8(data
.data(), data
.size(),
3555 endian::InlHostByteOrder(),
3556 endian::InlHostByteOrder());
3557 StringExtractorGDBRemote response
;
3558 return SendThreadSpecificPacketAndWaitForResponse(
3559 tid
, std::move(payload
), response
) == PacketResult::Success
&&
3560 response
.IsOKResponse();
3563 bool GDBRemoteCommunicationClient::WriteAllRegisters(
3564 lldb::tid_t tid
, llvm::ArrayRef
<uint8_t> data
) {
3565 StreamString payload
;
3566 payload
.PutChar('G');
3567 payload
.PutBytesAsRawHex8(data
.data(), data
.size(),
3568 endian::InlHostByteOrder(),
3569 endian::InlHostByteOrder());
3570 StringExtractorGDBRemote response
;
3571 return SendThreadSpecificPacketAndWaitForResponse(
3572 tid
, std::move(payload
), response
) == PacketResult::Success
&&
3573 response
.IsOKResponse();
3576 bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid
,
3577 uint32_t &save_id
) {
3578 save_id
= 0; // Set to invalid save ID
3579 if (m_supports_QSaveRegisterState
== eLazyBoolNo
)
3582 m_supports_QSaveRegisterState
= eLazyBoolYes
;
3583 StreamString payload
;
3584 payload
.PutCString("QSaveRegisterState");
3585 StringExtractorGDBRemote response
;
3586 if (SendThreadSpecificPacketAndWaitForResponse(
3587 tid
, std::move(payload
), response
) != PacketResult::Success
)
3590 if (response
.IsUnsupportedResponse())
3591 m_supports_QSaveRegisterState
= eLazyBoolNo
;
3593 const uint32_t response_save_id
= response
.GetU32(0);
3594 if (response_save_id
== 0)
3597 save_id
= response_save_id
;
3601 bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid
,
3603 // We use the "m_supports_QSaveRegisterState" variable here because the
3604 // QSaveRegisterState and QRestoreRegisterState packets must both be
3605 // supported in order to be useful
3606 if (m_supports_QSaveRegisterState
== eLazyBoolNo
)
3609 StreamString payload
;
3610 payload
.Printf("QRestoreRegisterState:%u", save_id
);
3611 StringExtractorGDBRemote response
;
3612 if (SendThreadSpecificPacketAndWaitForResponse(
3613 tid
, std::move(payload
), response
) != PacketResult::Success
)
3616 if (response
.IsOKResponse())
3619 if (response
.IsUnsupportedResponse())
3620 m_supports_QSaveRegisterState
= eLazyBoolNo
;
3624 bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid
) {
3625 if (!GetSyncThreadStateSupported())
3628 StreamString packet
;
3629 StringExtractorGDBRemote response
;
3630 packet
.Printf("QSyncThreadState:%4.4" PRIx64
";", tid
);
3631 return SendPacketAndWaitForResponse(packet
.GetString(), response
) ==
3632 GDBRemoteCommunication::PacketResult::Success
&&
3633 response
.IsOKResponse();
3636 llvm::Expected
<TraceSupportedResponse
>
3637 GDBRemoteCommunicationClient::SendTraceSupported(std::chrono::seconds timeout
) {
3638 Log
*log
= GetLog(GDBRLog::Process
);
3640 StreamGDBRemote escaped_packet
;
3641 escaped_packet
.PutCString("jLLDBTraceSupported");
3643 StringExtractorGDBRemote response
;
3644 if (SendPacketAndWaitForResponse(escaped_packet
.GetString(), response
,
3646 GDBRemoteCommunication::PacketResult::Success
) {
3647 if (response
.IsErrorResponse())
3648 return response
.GetStatus().ToError();
3649 if (response
.IsUnsupportedResponse())
3650 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3651 "jLLDBTraceSupported is unsupported");
3653 return llvm::json::parse
<TraceSupportedResponse
>(response
.Peek(),
3654 "TraceSupportedResponse");
3656 LLDB_LOG(log
, "failed to send packet: jLLDBTraceSupported");
3657 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3658 "failed to send packet: jLLDBTraceSupported");
3662 GDBRemoteCommunicationClient::SendTraceStop(const TraceStopRequest
&request
,
3663 std::chrono::seconds timeout
) {
3664 Log
*log
= GetLog(GDBRLog::Process
);
3666 StreamGDBRemote escaped_packet
;
3667 escaped_packet
.PutCString("jLLDBTraceStop:");
3669 std::string json_string
;
3670 llvm::raw_string_ostream
os(json_string
);
3671 os
<< toJSON(request
);
3673 escaped_packet
.PutEscapedBytes(json_string
.c_str(), json_string
.size());
3675 StringExtractorGDBRemote response
;
3676 if (SendPacketAndWaitForResponse(escaped_packet
.GetString(), response
,
3678 GDBRemoteCommunication::PacketResult::Success
) {
3679 if (response
.IsErrorResponse())
3680 return response
.GetStatus().ToError();
3681 if (response
.IsUnsupportedResponse())
3682 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3683 "jLLDBTraceStop is unsupported");
3684 if (response
.IsOKResponse())
3685 return llvm::Error::success();
3686 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3687 "Invalid jLLDBTraceStart response");
3689 LLDB_LOG(log
, "failed to send packet: jLLDBTraceStop");
3690 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3691 "failed to send packet: jLLDBTraceStop '%s'",
3692 escaped_packet
.GetData());
3696 GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value
¶ms
,
3697 std::chrono::seconds timeout
) {
3698 Log
*log
= GetLog(GDBRLog::Process
);
3700 StreamGDBRemote escaped_packet
;
3701 escaped_packet
.PutCString("jLLDBTraceStart:");
3703 std::string json_string
;
3704 llvm::raw_string_ostream
os(json_string
);
3707 escaped_packet
.PutEscapedBytes(json_string
.c_str(), json_string
.size());
3709 StringExtractorGDBRemote response
;
3710 if (SendPacketAndWaitForResponse(escaped_packet
.GetString(), response
,
3712 GDBRemoteCommunication::PacketResult::Success
) {
3713 if (response
.IsErrorResponse())
3714 return response
.GetStatus().ToError();
3715 if (response
.IsUnsupportedResponse())
3716 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3717 "jLLDBTraceStart is unsupported");
3718 if (response
.IsOKResponse())
3719 return llvm::Error::success();
3720 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3721 "Invalid jLLDBTraceStart response");
3723 LLDB_LOG(log
, "failed to send packet: jLLDBTraceStart");
3724 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3725 "failed to send packet: jLLDBTraceStart '%s'",
3726 escaped_packet
.GetData());
3729 llvm::Expected
<std::string
>
3730 GDBRemoteCommunicationClient::SendTraceGetState(llvm::StringRef type
,
3731 std::chrono::seconds timeout
) {
3732 Log
*log
= GetLog(GDBRLog::Process
);
3734 StreamGDBRemote escaped_packet
;
3735 escaped_packet
.PutCString("jLLDBTraceGetState:");
3737 std::string json_string
;
3738 llvm::raw_string_ostream
os(json_string
);
3739 os
<< toJSON(TraceGetStateRequest
{type
.str()});
3741 escaped_packet
.PutEscapedBytes(json_string
.c_str(), json_string
.size());
3743 StringExtractorGDBRemote response
;
3744 if (SendPacketAndWaitForResponse(escaped_packet
.GetString(), response
,
3746 GDBRemoteCommunication::PacketResult::Success
) {
3747 if (response
.IsErrorResponse())
3748 return response
.GetStatus().ToError();
3749 if (response
.IsUnsupportedResponse())
3750 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3751 "jLLDBTraceGetState is unsupported");
3752 return std::string(response
.Peek());
3755 LLDB_LOG(log
, "failed to send packet: jLLDBTraceGetState");
3756 return llvm::createStringError(
3757 llvm::inconvertibleErrorCode(),
3758 "failed to send packet: jLLDBTraceGetState '%s'",
3759 escaped_packet
.GetData());
3762 llvm::Expected
<std::vector
<uint8_t>>
3763 GDBRemoteCommunicationClient::SendTraceGetBinaryData(
3764 const TraceGetBinaryDataRequest
&request
, std::chrono::seconds timeout
) {
3765 Log
*log
= GetLog(GDBRLog::Process
);
3767 StreamGDBRemote escaped_packet
;
3768 escaped_packet
.PutCString("jLLDBTraceGetBinaryData:");
3770 std::string json_string
;
3771 llvm::raw_string_ostream
os(json_string
);
3772 os
<< toJSON(request
);
3774 escaped_packet
.PutEscapedBytes(json_string
.c_str(), json_string
.size());
3776 StringExtractorGDBRemote response
;
3777 if (SendPacketAndWaitForResponse(escaped_packet
.GetString(), response
,
3779 GDBRemoteCommunication::PacketResult::Success
) {
3780 if (response
.IsErrorResponse())
3781 return response
.GetStatus().ToError();
3783 response
.GetEscapedBinaryData(data
);
3784 return std::vector
<uint8_t>(data
.begin(), data
.end());
3786 LLDB_LOG(log
, "failed to send packet: jLLDBTraceGetBinaryData");
3787 return llvm::createStringError(
3788 llvm::inconvertibleErrorCode(),
3789 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3790 escaped_packet
.GetData());
3793 std::optional
<QOffsets
> GDBRemoteCommunicationClient::GetQOffsets() {
3794 StringExtractorGDBRemote response
;
3795 if (SendPacketAndWaitForResponse("qOffsets", response
) !=
3796 PacketResult::Success
)
3797 return std::nullopt
;
3798 if (!response
.IsNormalResponse())
3799 return std::nullopt
;
3802 llvm::StringRef ref
= response
.GetStringRef();
3803 const auto &GetOffset
= [&] {
3805 if (ref
.consumeInteger(16, offset
))
3807 result
.offsets
.push_back(offset
);
3811 if (ref
.consume_front("Text=")) {
3812 result
.segments
= false;
3814 return std::nullopt
;
3815 if (!ref
.consume_front(";Data=") || !GetOffset())
3816 return std::nullopt
;
3819 if (ref
.consume_front(";Bss=") && GetOffset() && ref
.empty())
3821 } else if (ref
.consume_front("TextSeg=")) {
3822 result
.segments
= true;
3824 return std::nullopt
;
3827 if (ref
.consume_front(";DataSeg=") && GetOffset() && ref
.empty())
3830 return std::nullopt
;
3833 bool GDBRemoteCommunicationClient::GetModuleInfo(
3834 const FileSpec
&module_file_spec
, const lldb_private::ArchSpec
&arch_spec
,
3835 ModuleSpec
&module_spec
) {
3836 if (!m_supports_qModuleInfo
)
3839 std::string module_path
= module_file_spec
.GetPath(false);
3840 if (module_path
.empty())
3843 StreamString packet
;
3844 packet
.PutCString("qModuleInfo:");
3845 packet
.PutStringAsRawHex8(module_path
);
3846 packet
.PutCString(";");
3847 const auto &triple
= arch_spec
.GetTriple().getTriple();
3848 packet
.PutStringAsRawHex8(triple
);
3850 StringExtractorGDBRemote response
;
3851 if (SendPacketAndWaitForResponse(packet
.GetString(), response
) !=
3852 PacketResult::Success
)
3855 if (response
.IsErrorResponse())
3858 if (response
.IsUnsupportedResponse()) {
3859 m_supports_qModuleInfo
= false;
3863 llvm::StringRef name
;
3864 llvm::StringRef value
;
3866 module_spec
.Clear();
3867 module_spec
.GetFileSpec() = module_file_spec
;
3869 while (response
.GetNameColonValue(name
, value
)) {
3870 if (name
== "uuid" || name
== "md5") {
3871 StringExtractor
extractor(value
);
3873 extractor
.GetHexByteString(uuid
);
3874 module_spec
.GetUUID().SetFromStringRef(uuid
);
3875 } else if (name
== "triple") {
3876 StringExtractor
extractor(value
);
3878 extractor
.GetHexByteString(triple
);
3879 module_spec
.GetArchitecture().SetTriple(triple
.c_str());
3880 } else if (name
== "file_offset") {
3882 if (!value
.getAsInteger(16, ival
))
3883 module_spec
.SetObjectOffset(ival
);
3884 } else if (name
== "file_size") {
3886 if (!value
.getAsInteger(16, ival
))
3887 module_spec
.SetObjectSize(ival
);
3888 } else if (name
== "file_path") {
3889 StringExtractor
extractor(value
);
3891 extractor
.GetHexByteString(path
);
3892 module_spec
.GetFileSpec() = FileSpec(path
, arch_spec
.GetTriple());
3899 static std::optional
<ModuleSpec
>
3900 ParseModuleSpec(StructuredData::Dictionary
*dict
) {
3903 return std::nullopt
;
3905 llvm::StringRef string
;
3908 if (!dict
->GetValueForKeyAsString("uuid", string
))
3909 return std::nullopt
;
3910 if (!result
.GetUUID().SetFromStringRef(string
))
3911 return std::nullopt
;
3913 if (!dict
->GetValueForKeyAsInteger("file_offset", integer
))
3914 return std::nullopt
;
3915 result
.SetObjectOffset(integer
);
3917 if (!dict
->GetValueForKeyAsInteger("file_size", integer
))
3918 return std::nullopt
;
3919 result
.SetObjectSize(integer
);
3921 if (!dict
->GetValueForKeyAsString("triple", string
))
3922 return std::nullopt
;
3923 result
.GetArchitecture().SetTriple(string
);
3925 if (!dict
->GetValueForKeyAsString("file_path", string
))
3926 return std::nullopt
;
3927 result
.GetFileSpec() = FileSpec(string
, result
.GetArchitecture().GetTriple());
3932 std::optional
<std::vector
<ModuleSpec
>>
3933 GDBRemoteCommunicationClient::GetModulesInfo(
3934 llvm::ArrayRef
<FileSpec
> module_file_specs
, const llvm::Triple
&triple
) {
3935 namespace json
= llvm::json
;
3937 if (!m_supports_jModulesInfo
)
3938 return std::nullopt
;
3940 json::Array module_array
;
3941 for (const FileSpec
&module_file_spec
: module_file_specs
) {
3942 module_array
.push_back(
3943 json::Object
{{"file", module_file_spec
.GetPath(false)},
3944 {"triple", triple
.getTriple()}});
3946 StreamString unescaped_payload
;
3947 unescaped_payload
.PutCString("jModulesInfo:");
3948 unescaped_payload
.AsRawOstream() << std::move(module_array
);
3950 StreamGDBRemote payload
;
3951 payload
.PutEscapedBytes(unescaped_payload
.GetString().data(),
3952 unescaped_payload
.GetSize());
3954 // Increase the timeout for jModulesInfo since this packet can take longer.
3955 ScopedTimeout
timeout(*this, std::chrono::seconds(10));
3957 StringExtractorGDBRemote response
;
3958 if (SendPacketAndWaitForResponse(payload
.GetString(), response
) !=
3959 PacketResult::Success
||
3960 response
.IsErrorResponse())
3961 return std::nullopt
;
3963 if (response
.IsUnsupportedResponse()) {
3964 m_supports_jModulesInfo
= false;
3965 return std::nullopt
;
3968 StructuredData::ObjectSP response_object_sp
=
3969 StructuredData::ParseJSON(response
.GetStringRef());
3970 if (!response_object_sp
)
3971 return std::nullopt
;
3973 StructuredData::Array
*response_array
= response_object_sp
->GetAsArray();
3974 if (!response_array
)
3975 return std::nullopt
;
3977 std::vector
<ModuleSpec
> result
;
3978 for (size_t i
= 0; i
< response_array
->GetSize(); ++i
) {
3979 if (std::optional
<ModuleSpec
> module_spec
= ParseModuleSpec(
3980 response_array
->GetItemAtIndex(i
)->GetAsDictionary()))
3981 result
.push_back(*module_spec
);
3987 // query the target remote for extended information using the qXfer packet
3989 // example: object='features', annex='target.xml'
3990 // return: <xml output> or error
3991 llvm::Expected
<std::string
>
3992 GDBRemoteCommunicationClient::ReadExtFeature(llvm::StringRef object
,
3993 llvm::StringRef annex
) {
3996 llvm::raw_string_ostream
output_stream(output
);
3997 StringExtractorGDBRemote chunk
;
3999 uint64_t size
= GetRemoteMaxPacketSize();
4002 size
= size
- 1; // Leave space for the 'm' or 'l' character in the response
4006 // loop until all data has been read
4009 // send query extended feature packet
4010 std::string packet
=
4011 ("qXfer:" + object
+ ":read:" + annex
+ ":" +
4012 llvm::Twine::utohexstr(offset
) + "," + llvm::Twine::utohexstr(size
))
4015 GDBRemoteCommunication::PacketResult res
=
4016 SendPacketAndWaitForResponse(packet
, chunk
);
4018 if (res
!= GDBRemoteCommunication::PacketResult::Success
||
4019 chunk
.GetStringRef().empty()) {
4020 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4021 "Error sending $qXfer packet");
4024 // check packet code
4025 switch (chunk
.GetStringRef()[0]) {
4033 output_stream
<< chunk
.GetStringRef().drop_front();
4034 offset
+= chunk
.GetStringRef().size() - 1;
4039 return llvm::createStringError(
4040 llvm::inconvertibleErrorCode(),
4041 "Invalid continuation code from $qXfer packet");
4048 // Notify the target that gdb is prepared to serve symbol lookup requests.
4049 // packet: "qSymbol::"
4051 // OK The target does not need to look up any (more) symbols.
4052 // qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
4054 // LLDB may provide the value by sending another qSymbol
4056 // in the form of"qSymbol:<sym_value>:<sym_name>".
4060 // lldb sends: qSymbol::
4061 // lldb receives: OK
4062 // Remote gdb stub does not need to know the addresses of any symbols, lldb
4064 // need to ask again in this session.
4066 // lldb sends: qSymbol::
4067 // lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
4068 // lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
4069 // lldb receives: OK
4070 // Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
4072 // the address at this time. lldb needs to send qSymbol:: again when it has
4076 // lldb sends: qSymbol::
4077 // lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
4078 // lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
4079 // lldb receives: OK
4080 // Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
4082 // is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
4084 // need any more symbols. lldb does not need to ask again in this session.
4086 void GDBRemoteCommunicationClient::ServeSymbolLookups(
4087 lldb_private::Process
*process
) {
4088 // Set to true once we've resolved a symbol to an address for the remote
4089 // stub. If we get an 'OK' response after this, the remote stub doesn't need
4090 // any more symbols and we can stop asking.
4091 bool symbol_response_provided
= false;
4093 // Is this the initial qSymbol:: packet?
4094 bool first_qsymbol_query
= true;
4096 if (m_supports_qSymbol
&& !m_qSymbol_requests_done
) {
4099 StreamString packet
;
4100 packet
.PutCString("qSymbol::");
4101 StringExtractorGDBRemote response
;
4102 while (SendPacketAndWaitForResponseNoLock(packet
.GetString(), response
) ==
4103 PacketResult::Success
) {
4104 if (response
.IsOKResponse()) {
4105 if (symbol_response_provided
|| first_qsymbol_query
) {
4106 m_qSymbol_requests_done
= true;
4109 // We are done serving symbols requests
4112 first_qsymbol_query
= false;
4114 if (response
.IsUnsupportedResponse()) {
4115 // qSymbol is not supported by the current GDB server we are
4117 m_supports_qSymbol
= false;
4120 llvm::StringRef
response_str(response
.GetStringRef());
4121 if (response_str
.starts_with("qSymbol:")) {
4122 response
.SetFilePos(strlen("qSymbol:"));
4123 std::string symbol_name
;
4124 if (response
.GetHexByteString(symbol_name
)) {
4125 if (symbol_name
.empty())
4128 addr_t symbol_load_addr
= LLDB_INVALID_ADDRESS
;
4129 lldb_private::SymbolContextList sc_list
;
4130 process
->GetTarget().GetImages().FindSymbolsWithNameAndType(
4131 ConstString(symbol_name
), eSymbolTypeAny
, sc_list
);
4132 for (const SymbolContext
&sc
: sc_list
) {
4133 if (symbol_load_addr
!= LLDB_INVALID_ADDRESS
)
4136 switch (sc
.symbol
->GetType()) {
4137 case eSymbolTypeInvalid
:
4138 case eSymbolTypeAbsolute
:
4139 case eSymbolTypeUndefined
:
4140 case eSymbolTypeSourceFile
:
4141 case eSymbolTypeHeaderFile
:
4142 case eSymbolTypeObjectFile
:
4143 case eSymbolTypeCommonBlock
:
4144 case eSymbolTypeBlock
:
4145 case eSymbolTypeLocal
:
4146 case eSymbolTypeParam
:
4147 case eSymbolTypeVariable
:
4148 case eSymbolTypeVariableType
:
4149 case eSymbolTypeLineEntry
:
4150 case eSymbolTypeLineHeader
:
4151 case eSymbolTypeScopeBegin
:
4152 case eSymbolTypeScopeEnd
:
4153 case eSymbolTypeAdditional
:
4154 case eSymbolTypeCompiler
:
4155 case eSymbolTypeInstrumentation
:
4156 case eSymbolTypeTrampoline
:
4159 case eSymbolTypeCode
:
4160 case eSymbolTypeResolver
:
4161 case eSymbolTypeData
:
4162 case eSymbolTypeRuntime
:
4163 case eSymbolTypeException
:
4164 case eSymbolTypeObjCClass
:
4165 case eSymbolTypeObjCMetaClass
:
4166 case eSymbolTypeObjCIVar
:
4167 case eSymbolTypeReExported
:
4169 sc
.symbol
->GetLoadAddress(&process
->GetTarget());
4174 // This is the normal path where our symbol lookup was successful
4175 // and we want to send a packet with the new symbol value and see
4176 // if another lookup needs to be done.
4178 // Change "packet" to contain the requested symbol value and name
4180 packet
.PutCString("qSymbol:");
4181 if (symbol_load_addr
!= LLDB_INVALID_ADDRESS
) {
4182 packet
.Printf("%" PRIx64
, symbol_load_addr
);
4183 symbol_response_provided
= true;
4185 symbol_response_provided
= false;
4187 packet
.PutCString(":");
4188 packet
.PutBytesAsRawHex8(symbol_name
.data(), symbol_name
.size());
4189 continue; // go back to the while loop and send "packet" and wait
4190 // for another response
4195 // If we make it here, the symbol request packet response wasn't valid or
4196 // our symbol lookup failed so we must abort
4199 } else if (Log
*log
= GetLog(GDBRLog::Process
| GDBRLog::Packets
)) {
4201 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4207 StructuredData::Array
*
4208 GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
4209 if (!m_supported_async_json_packets_is_valid
) {
4210 // Query the server for the array of supported asynchronous JSON packets.
4211 m_supported_async_json_packets_is_valid
= true;
4213 Log
*log
= GetLog(GDBRLog::Process
);
4216 StringExtractorGDBRemote response
;
4217 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response
) ==
4218 PacketResult::Success
) {
4219 m_supported_async_json_packets_sp
=
4220 StructuredData::ParseJSON(response
.GetStringRef());
4221 if (m_supported_async_json_packets_sp
&&
4222 !m_supported_async_json_packets_sp
->GetAsArray()) {
4223 // We were returned something other than a JSON array. This is
4224 // invalid. Clear it out.
4226 "GDBRemoteCommunicationClient::%s(): "
4227 "QSupportedAsyncJSONPackets returned invalid "
4229 __FUNCTION__
, response
.GetStringRef().data());
4230 m_supported_async_json_packets_sp
.reset();
4234 "GDBRemoteCommunicationClient::%s(): "
4235 "QSupportedAsyncJSONPackets unsupported",
4239 if (log
&& m_supported_async_json_packets_sp
) {
4240 StreamString stream
;
4241 m_supported_async_json_packets_sp
->Dump(stream
);
4243 "GDBRemoteCommunicationClient::%s(): supported async "
4245 __FUNCTION__
, stream
.GetData());
4249 return m_supported_async_json_packets_sp
4250 ? m_supported_async_json_packets_sp
->GetAsArray()
4254 Status
GDBRemoteCommunicationClient::SendSignalsToIgnore(
4255 llvm::ArrayRef
<int32_t> signals
) {
4257 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
4258 auto range
= llvm::make_range(signals
.begin(), signals
.end());
4259 std::string packet
= formatv("QPassSignals:{0:$[;]@(x-2)}", range
).str();
4261 StringExtractorGDBRemote response
;
4262 auto send_status
= SendPacketAndWaitForResponse(packet
, response
);
4264 if (send_status
!= GDBRemoteCommunication::PacketResult::Success
)
4265 return Status::FromErrorString("Sending QPassSignals packet failed");
4267 if (response
.IsOKResponse()) {
4270 return Status::FromErrorString(
4271 "Unknown error happened during sending QPassSignals packet.");
4275 Status
GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
4276 llvm::StringRef type_name
, const StructuredData::ObjectSP
&config_sp
) {
4279 if (type_name
.empty()) {
4280 error
= Status::FromErrorString("invalid type_name argument");
4284 // Build command: Configure{type_name}: serialized config data.
4285 StreamGDBRemote stream
;
4286 stream
.PutCString("QConfigure");
4287 stream
.PutCString(type_name
);
4288 stream
.PutChar(':');
4290 // Gather the plain-text version of the configuration data.
4291 StreamString unescaped_stream
;
4292 config_sp
->Dump(unescaped_stream
);
4293 unescaped_stream
.Flush();
4295 // Add it to the stream in escaped fashion.
4296 stream
.PutEscapedBytes(unescaped_stream
.GetString().data(),
4297 unescaped_stream
.GetSize());
4302 StringExtractorGDBRemote response
;
4303 auto result
= SendPacketAndWaitForResponse(stream
.GetString(), response
);
4304 if (result
== PacketResult::Success
) {
4305 // We failed if the config result comes back other than OK.
4306 if (response
.GetStringRef() == "OK") {
4310 error
= Status::FromErrorStringWithFormatv(
4311 "configuring StructuredData feature {0} failed with error {1}",
4312 type_name
, response
.GetStringRef());
4315 // Can we get more data here on the failure?
4316 error
= Status::FromErrorStringWithFormatv(
4317 "configuring StructuredData feature {0} failed when sending packet: "
4319 type_name
, (int)result
);
4324 void GDBRemoteCommunicationClient::OnRunPacketSent(bool first
) {
4325 GDBRemoteClientBase::OnRunPacketSent(first
);
4326 m_curr_tid
= LLDB_INVALID_THREAD_ID
;
4329 bool GDBRemoteCommunicationClient::UsesNativeSignals() {
4330 if (m_uses_native_signals
== eLazyBoolCalculate
)
4331 GetRemoteQSupported();
4332 if (m_uses_native_signals
== eLazyBoolYes
)
4335 // If the remote didn't indicate native-signal support explicitly,
4336 // check whether it is an old version of lldb-server.
4337 return GetThreadSuffixSupported();
4340 llvm::Expected
<int> GDBRemoteCommunicationClient::KillProcess(lldb::pid_t pid
) {
4341 StringExtractorGDBRemote response
;
4342 GDBRemoteCommunication::ScopedTimeout(*this, seconds(3));
4344 if (SendPacketAndWaitForResponse("k", response
, GetPacketTimeout()) !=
4345 PacketResult::Success
)
4346 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4347 "failed to send k packet");
4349 char packet_cmd
= response
.GetChar(0);
4350 if (packet_cmd
== 'W' || packet_cmd
== 'X')
4351 return response
.GetHexU8();
4353 return llvm::createStringError(llvm::inconvertibleErrorCode(),
4354 "unexpected response to k packet: %s",
4355 response
.GetStringRef().str().c_str());