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
14#include "lldb/Host/Config.h"
15#include "lldb/Host/Socket.h"
16#include "lldb/Utility/Args.h"
18#include <mutex>
19#include <string>
20
21namespace lldb_private {
22namespace process_gdb_remote {
23
32
33enum class CompressionType {
34 None = 0, // no compression
35 ZlibDeflate, // zlib's deflate compression scheme, requires zlib or Apple's
36 // libcompression
37 LZFSE, // an Apple compression scheme, requires Apple's libcompression
38 LZ4, // lz compression - called "lz4 raw" in libcompression terms, compat with
39 // https://code.google.com/p/lz4/
40 LZMA, // Lempel–Ziv–Markov chain algorithm
41};
42
43// Data included in the vFile:fstat packet.
44// https://sourceware.org/gdb/onlinedocs/gdb/struct-stat.html#struct-stat
46 llvm::support::ubig32_t gdb_st_dev;
47 llvm::support::ubig32_t gdb_st_ino;
48 llvm::support::ubig32_t gdb_st_mode;
49 llvm::support::ubig32_t gdb_st_nlink;
50 llvm::support::ubig32_t gdb_st_uid;
51 llvm::support::ubig32_t gdb_st_gid;
52 llvm::support::ubig32_t gdb_st_rdev;
53 llvm::support::ubig64_t gdb_st_size;
54 llvm::support::ubig64_t gdb_st_blksize;
55 llvm::support::ubig64_t gdb_st_blocks;
56 llvm::support::ubig32_t gdb_st_atime;
57 llvm::support::ubig32_t gdb_st_mtime;
58 llvm::support::ubig32_t gdb_st_ctime;
59};
60static_assert(sizeof(GDBRemoteFStatData) == 64,
61 "size of GDBRemoteFStatData is not 64");
62
64#define HANDLE_ERRNO(name, value) GDB_##name = value,
65#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
67};
68
69class ProcessGDBRemote;
70
72public:
73 enum class PacketType { Invalid = 0, Standard, Notify };
74
75 enum class PacketResult {
76 Success = 0, // Success
77 ErrorSendFailed, // Status sending the packet
78 ErrorSendAck, // Didn't get an ack back after sending a packet
79 ErrorReplyFailed, // Status getting the reply
80 ErrorReplyTimeout, // Timed out waiting for reply
81 ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that
82 // was sent
83 ErrorReplyAck, // Sending reply ack failed
84 ErrorDisconnected, // We were disconnected
85 ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet
86 // request
87 };
88
89 // Class to change the timeout for a given scope and restore it to the
90 // original value when the
91 // created ScopedTimeout object got out of scope
93 public:
95 std::chrono::seconds timeout);
97
98 private:
100 std::chrono::seconds m_saved_timeout;
101 // Don't ever reduce the timeout for a packet, only increase it. If the
102 // requested timeout if less than the current timeout, we don't set it
103 // and won't need to restore it.
105 };
106
108
109 ~GDBRemoteCommunication() override;
110
112
113 size_t SendAck();
114
115 size_t SendNack();
116
117 char CalculcateChecksum(llvm::StringRef payload);
118
119 PacketType CheckForPacket(const uint8_t *src, size_t src_len,
121
122 bool GetSendAcks() { return m_send_acks; }
123
124 // Set the global packet timeout.
125 //
126 // For clients, this is the timeout that gets used when sending
127 // packets and waiting for responses. For servers, this is used when waiting
128 // for ACKs.
129 std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
130 const auto old_packet_timeout = m_packet_timeout;
131 m_packet_timeout = packet_timeout;
132 return old_packet_timeout;
133 }
134
135 std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
136
137 // Start a debugserver instance on the current host using the
138 // supplied connection URL.
139 static Status
140 StartDebugserverProcess(std::variant<llvm::StringRef, shared_fd_t> comm,
141 ProcessLaunchInfo &launch_info,
142 const Args *inferior_args);
143
144 void DumpHistory(Stream &strm);
145
146 /// Expand GDB run-length encoding.
147 static std::optional<std::string> ExpandRLE(std::string);
148
149protected:
150 std::chrono::seconds m_packet_timeout;
155 bool m_is_platform; // Set to true if this class represents a platform,
156 // false if this class represents a debug session for
157 // a single process
158
159 std::string m_bytes;
160 std::recursive_mutex m_bytes_mutex;
162
163 PacketResult SendPacketNoLock(llvm::StringRef payload);
164 PacketResult SendNotificationPacketNoLock(llvm::StringRef notify_type,
165 std::deque<std::string>& queue,
166 llvm::StringRef payload);
167 PacketResult SendRawPacketNoLock(llvm::StringRef payload,
168 bool skip_ack = false);
169
171 Timeout<std::micro> timeout, bool sync_on_timeout);
172
174 Timeout<std::micro> timeout,
175 bool sync_on_timeout);
176
180
181 // If compression is enabled, decompress the packet in m_bytes and update
182 // m_bytes with the uncompressed version.
183 // Returns 'true' packet was decompressed and m_bytes is the now-decompressed
184 // text.
185 // Returns 'false' if unable to decompress or if the checksum was invalid.
186 //
187 // NB: Once the packet has been decompressed, checksum cannot be computed
188 // based
189 // on m_bytes. The checksum was for the compressed packet.
190 bool DecompressPacket();
191
192private:
193#if HAVE_LIBCOMPRESSION
194 CompressionType m_decompression_scratch_type = CompressionType::None;
195 void *m_decompression_scratch = nullptr;
196#endif
197
201};
202
203} // namespace process_gdb_remote
204} // namespace lldb_private
205
206namespace llvm {
207template <>
208struct format_provider<
209 lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult> {
211 GDBRemoteCommunication::PacketResult &state,
212 raw_ostream &Stream, StringRef Style);
213};
214} // namespace llvm
215
216#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H
A command line argument class.
Definition Args.h:33
Communication()
Construct the Communication object.
An error handling class.
Definition Status.h:118
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.
ScopedTimeout(GDBRemoteCommunication &gdb_comm, std::chrono::seconds timeout)
std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout)
GDBRemoteCommunication(const GDBRemoteCommunication &)=delete
PacketResult ReadPacket(StringExtractorGDBRemote &response, Timeout< std::micro > timeout, bool sync_on_timeout)
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)
static Status StartDebugserverProcess(std::variant< llvm::StringRef, shared_fd_t > comm, ProcessLaunchInfo &launch_info, const Args *inferior_args)
const GDBRemoteCommunication & operator=(const GDBRemoteCommunication &)=delete
static std::optional< 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.
static void format(const lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult &state, raw_ostream &Stream, StringRef Style)