LLDB mainline
GDBRemoteCommunication.h
Go to the documentation of this file.
1//===-- GDBRemoteCommunication.h --------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H
10#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H
11
13
14#include <condition_variable>
15#include <future>
16#include <mutex>
17#include <queue>
18#include <string>
19#include <vector>
20
22#include "lldb/Host/Config.h"
24#include "lldb/Utility/Args.h"
28#include "lldb/lldb-public.h"
29
30namespace lldb_private {
31namespace repro {
32class PacketRecorder;
33}
34namespace process_gdb_remote {
35
43};
44
45enum class CompressionType {
46 None = 0, // no compression
47 ZlibDeflate, // zlib's deflate compression scheme, requires zlib or Apple's
48 // libcompression
49 LZFSE, // an Apple compression scheme, requires Apple's libcompression
50 LZ4, // lz compression - called "lz4 raw" in libcompression terms, compat with
51 // https://code.google.com/p/lz4/
52 LZMA, // Lempel–Ziv–Markov chain algorithm
53};
54
55// Data included in the vFile:fstat packet.
56// https://sourceware.org/gdb/onlinedocs/gdb/struct-stat.html#struct-stat
58 llvm::support::ubig32_t gdb_st_dev;
59 llvm::support::ubig32_t gdb_st_ino;
60 llvm::support::ubig32_t gdb_st_mode;
61 llvm::support::ubig32_t gdb_st_nlink;
62 llvm::support::ubig32_t gdb_st_uid;
63 llvm::support::ubig32_t gdb_st_gid;
64 llvm::support::ubig32_t gdb_st_rdev;
65 llvm::support::ubig64_t gdb_st_size;
66 llvm::support::ubig64_t gdb_st_blksize;
67 llvm::support::ubig64_t gdb_st_blocks;
68 llvm::support::ubig32_t gdb_st_atime;
69 llvm::support::ubig32_t gdb_st_mtime;
70 llvm::support::ubig32_t gdb_st_ctime;
71};
72static_assert(sizeof(GDBRemoteFStatData) == 64,
73 "size of GDBRemoteFStatData is not 64");
74
76#define HANDLE_ERRNO(name, value) GDB_##name = value,
77#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
78 GDB_EUNKNOWN = 9999
79};
80
81class ProcessGDBRemote;
82
84public:
85 enum class PacketType { Invalid = 0, Standard, Notify };
86
87 enum class PacketResult {
88 Success = 0, // Success
89 ErrorSendFailed, // Status sending the packet
90 ErrorSendAck, // Didn't get an ack back after sending a packet
91 ErrorReplyFailed, // Status getting the reply
92 ErrorReplyTimeout, // Timed out waiting for reply
93 ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that
94 // was sent
95 ErrorReplyAck, // Sending reply ack failed
96 ErrorDisconnected, // We were disconnected
97 ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet
98 // request
99 };
100
101 // Class to change the timeout for a given scope and restore it to the
102 // original value when the
103 // created ScopedTimeout object got out of scope
105 public:
107 std::chrono::seconds timeout);
109
110 private:
112 std::chrono::seconds m_saved_timeout;
113 // Don't ever reduce the timeout for a packet, only increase it. If the
114 // requested timeout if less than the current timeout, we don't set it
115 // and won't need to restore it.
117 };
118
120
121 ~GDBRemoteCommunication() override;
122
124
125 size_t SendAck();
126
127 size_t SendNack();
128
129 char CalculcateChecksum(llvm::StringRef payload);
130
131 PacketType CheckForPacket(const uint8_t *src, size_t src_len,
133
134 bool GetSendAcks() { return m_send_acks; }
135
136 // Set the global packet timeout.
137 //
138 // For clients, this is the timeout that gets used when sending
139 // packets and waiting for responses. For servers, this is used when waiting
140 // for ACKs.
141 std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
142 const auto old_packet_timeout = m_packet_timeout;
143 m_packet_timeout = packet_timeout;
144 return old_packet_timeout;
145 }
146
147 std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
148
149 // Start a debugserver instance on the current host using the
150 // supplied connection URL.
152 const char *url,
153 Platform *platform, // If non nullptr, then check with the platform for
154 // the GDB server binary if it can't be located
155 ProcessLaunchInfo &launch_info, uint16_t *port, const Args *inferior_args,
156 int pass_comm_fd); // Communication file descriptor to pass during
157 // fork/exec to avoid having to connect/accept
158
159 void DumpHistory(Stream &strm);
160
161 void SetPacketRecorder(repro::PacketRecorder *recorder);
162
163 static llvm::Error ConnectLocally(GDBRemoteCommunication &client,
164 GDBRemoteCommunication &server);
165
166 /// Expand GDB run-length encoding.
167 static std::string ExpandRLE(std::string);
168
169protected:
170 std::chrono::seconds m_packet_timeout;
175 bool m_is_platform; // Set to true if this class represents a platform,
176 // false if this class represents a debug session for
177 // a single process
178
179 std::string m_bytes;
180 std::recursive_mutex m_bytes_mutex;
182
183 PacketResult SendPacketNoLock(llvm::StringRef payload);
184 PacketResult SendNotificationPacketNoLock(llvm::StringRef notify_type,
185 std::deque<std::string>& queue,
186 llvm::StringRef payload);
187 PacketResult SendRawPacketNoLock(llvm::StringRef payload,
188 bool skip_ack = false);
189
191 Timeout<std::micro> timeout, bool sync_on_timeout);
192
194 Timeout<std::micro> timeout,
195 bool sync_on_timeout);
196
199 }
200
201 // If compression is enabled, decompress the packet in m_bytes and update
202 // m_bytes with the uncompressed version.
203 // Returns 'true' packet was decompressed and m_bytes is the now-decompressed
204 // text.
205 // Returns 'false' if unable to decompress or if the checksum was invalid.
206 //
207 // NB: Once the packet has been decompressed, checksum cannot be computed
208 // based
209 // on m_bytes. The checksum was for the compressed packet.
210 bool DecompressPacket();
211
212 Status StartListenThread(const char *hostname = "127.0.0.1",
213 uint16_t port = 0);
214
215 bool JoinListenThread();
216
218
219private:
220 // Promise used to grab the port number from listening thread
221 std::promise<uint16_t> m_port_promise;
222
224 std::string m_listen_url;
225
226#if defined(HAVE_LIBCOMPRESSION)
227 CompressionType m_decompression_scratch_type = CompressionType::None;
228 void *m_decompression_scratch = nullptr;
229#endif
230
234};
235
236} // namespace process_gdb_remote
237} // namespace lldb_private
238
239namespace llvm {
240template <>
241struct format_provider<
242 lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult> {
244 GDBRemoteCommunication::PacketResult &state,
245 raw_ostream &Stream, StringRef Style);
246};
247} // namespace llvm
248
249#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H
A command line argument class.
Definition: Args.h:33
An abstract communications class.
Definition: Communication.h:39
A plug-in interface definition class for debug platform that includes many platform abilities such as...
Definition: Platform.h:76
An error handling class.
Definition: Status.h:44
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
The history keeps a circular buffer of GDB remote packets.
std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout)
GDBRemoteCommunication(const GDBRemoteCommunication &)=delete
static llvm::Error ConnectLocally(GDBRemoteCommunication &client, GDBRemoteCommunication &server)
PacketResult ReadPacket(StringExtractorGDBRemote &response, Timeout< std::micro > timeout, bool sync_on_timeout)
Status StartDebugserverProcess(const char *url, Platform *platform, ProcessLaunchInfo &launch_info, uint16_t *port, const Args *inferior_args, int pass_comm_fd)
PacketResult SendNotificationPacketNoLock(llvm::StringRef notify_type, std::deque< std::string > &queue, llvm::StringRef payload)
PacketResult WaitForPacketNoLock(StringExtractorGDBRemote &response, Timeout< std::micro > timeout, bool sync_on_timeout)
PacketResult SendRawPacketNoLock(llvm::StringRef payload, bool skip_ack=false)
Status StartListenThread(const char *hostname="127.0.0.1", uint16_t port=0)
const GDBRemoteCommunication & operator=(const GDBRemoteCommunication &)=delete
void SetPacketRecorder(repro::PacketRecorder *recorder)
static std::string ExpandRLE(std::string)
Expand GDB run-length encoding.
PacketType CheckForPacket(const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
A class that represents a running process on the host machine.
void * thread_result_t
Definition: lldb-types.h:62
Definition: Debugger.h:54
static void format(const lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult &state, raw_ostream &Stream, StringRef Style)