blob: ecc9386e49c7d551147c4835e60032ae75d7d4fa [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- GDBRemoteCommunication.h --------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_GDBRemoteCommunication_h_
11#define liblldb_GDBRemoteCommunication_h_
12
13// C Includes
14// C++ Includes
Saleem Abdulrasool2d6a9ec2016-07-28 17:32:20 +000015#include <condition_variable>
16#include <mutex>
Ewan Crawfordfab40d32015-06-16 15:50:18 +000017#include <queue>
Kate Stoneb9c1b512016-09-06 20:57:50 +000018#include <string>
Eugene Zelenkoedb35d92015-10-24 01:08:35 +000019#include <vector>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020
21// Other libraries and framework includes
22// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/Communication.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Core/Listener.h"
Zachary Turner39de3112014-09-09 20:54:56 +000025#include "lldb/Host/HostThread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Host/Predicate.h"
Tamas Berghammerccd6cff2015-12-08 14:08:19 +000027#include "lldb/Interpreter/Args.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000028#include "lldb/lldb-public.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029
Greg Claytonc982c762010-07-09 20:39:50 +000030#include "Utility/StringExtractorGDBRemote.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
Tamas Berghammerdb264a62015-03-31 09:52:22 +000032namespace lldb_private {
33namespace process_gdb_remote {
34
Kate Stoneb9c1b512016-09-06 20:57:50 +000035typedef enum {
36 eStoppointInvalid = -1,
37 eBreakpointSoftware = 0,
38 eBreakpointHardware,
39 eWatchpointWrite,
40 eWatchpointRead,
41 eWatchpointReadWrite
Chaoren Lin18fe6402015-02-03 01:51:47 +000042} GDBStoppointType;
43
Kate Stoneb9c1b512016-09-06 20:57:50 +000044enum class CompressionType {
45 None = 0, // no compression
46 ZlibDeflate, // zlib's deflate compression scheme, requires zlib or Apple's
47 // libcompression
48 LZFSE, // an Apple compression scheme, requires Apple's libcompression
49 LZ4, // lz compression - called "lz4 raw" in libcompression terms, compat with
50 // https://code.google.com/p/lz4/
51 LZMA, // Lempel–Ziv–Markov chain algorithm
Jason Molenda91ffe0a2015-06-18 21:46:06 +000052};
53
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054class ProcessGDBRemote;
55
Kate Stoneb9c1b512016-09-06 20:57:50 +000056class GDBRemoteCommunication : public Communication {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000058 enum {
59 eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
60 eBroadcastBitGdbReadThreadGotNotify =
61 kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
62 };
Ewan Crawford9aa2da002015-05-27 14:12:34 +000063
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 enum class PacketType { Invalid = 0, Standard, Notify };
Ewan Crawford9aa2da002015-05-27 14:12:34 +000065
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 enum class PacketResult {
67 Success = 0, // Success
Zachary Turner97206d52017-05-12 04:51:55 +000068 ErrorSendFailed, // Status sending the packet
Kate Stoneb9c1b512016-09-06 20:57:50 +000069 ErrorSendAck, // Didn't get an ack back after sending a packet
Zachary Turner97206d52017-05-12 04:51:55 +000070 ErrorReplyFailed, // Status getting the reply
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 ErrorReplyTimeout, // Timed out waiting for reply
72 ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that
73 // was sent
74 ErrorReplyAck, // Sending reply ack failed
75 ErrorDisconnected, // We were disconnected
76 ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet
77 // request
78 };
Tamas Berghammer912800c2015-02-24 10:23:39 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 // Class to change the timeout for a given scope and restore it to the
81 // original value when the
82 // created ScopedTimeout object got out of scope
83 class ScopedTimeout {
84 public:
Pavel Labath3aa04912016-10-31 17:19:42 +000085 ScopedTimeout(GDBRemoteCommunication &gdb_comm,
86 std::chrono::seconds timeout);
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 ~ScopedTimeout();
Tamas Berghammer912800c2015-02-24 10:23:39 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 private:
90 GDBRemoteCommunication &m_gdb_comm;
Pavel Labath3aa04912016-10-31 17:19:42 +000091 std::chrono::seconds m_saved_timeout;
Greg Clayton84577092017-04-17 16:20:22 +000092 // Don't ever reduce the timeout for a packet, only increase it. If the
93 // requested timeout if less than the current timeout, we don't set it
94 // and won't need to restore it.
95 bool m_timeout_modified;
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 };
Tamas Berghammer912800c2015-02-24 10:23:39 +000097
Kate Stoneb9c1b512016-09-06 20:57:50 +000098 GDBRemoteCommunication(const char *comm_name, const char *listener_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100 ~GDBRemoteCommunication() override;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102 PacketResult GetAck();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104 size_t SendAck();
Greg Clayton6ed95942011-01-22 07:12:45 +0000105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106 size_t SendNack();
Greg Clayton6ed95942011-01-22 07:12:45 +0000107
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108 char CalculcateChecksum(llvm::StringRef payload);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 PacketType CheckForPacket(const uint8_t *src, size_t src_len,
111 StringExtractorGDBRemote &packet);
Eugene Zelenkoedb35d92015-10-24 01:08:35 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 bool GetSendAcks() { return m_send_acks; }
Greg Clayton1cb64962011-03-24 04:28:38 +0000114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 //------------------------------------------------------------------
116 // Set the global packet timeout.
117 //
118 // For clients, this is the timeout that gets used when sending
Pavel Labath3aa04912016-10-31 17:19:42 +0000119 // packets and waiting for responses. For servers, this is used when waiting
120 // for ACKs.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121 //------------------------------------------------------------------
Pavel Labath3aa04912016-10-31 17:19:42 +0000122 std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
123 const auto old_packet_timeout = m_packet_timeout;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 m_packet_timeout = packet_timeout;
125 return old_packet_timeout;
126 }
Greg Clayton71fc2a32011-02-12 06:28:37 +0000127
Pavel Labath3aa04912016-10-31 17:19:42 +0000128 std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
Eugene Zelenkoedb35d92015-10-24 01:08:35 +0000129
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 //------------------------------------------------------------------
131 // Start a debugserver instance on the current host using the
132 // supplied connection URL.
133 //------------------------------------------------------------------
Zachary Turner97206d52017-05-12 04:51:55 +0000134 Status StartDebugserverProcess(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135 const char *url,
136 Platform *platform, // If non nullptr, then check with the platform for
137 // the GDB server binary if it can't be located
138 ProcessLaunchInfo &launch_info, uint16_t *port, const Args *inferior_args,
139 int pass_comm_fd); // Communication file descriptor to pass during
140 // fork/exec to avoid having to connect/accept
Greg Clayton8b82f082011-04-12 05:54:46 +0000141
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142 void DumpHistory(Stream &strm);
143
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000145 class History {
146 public:
147 enum PacketType {
148 ePacketTypeInvalid = 0,
149 ePacketTypeSend,
150 ePacketTypeRecv
Greg Claytonc1422c12012-04-09 22:46:21 +0000151 };
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152
Kate Stoneb9c1b512016-09-06 20:57:50 +0000153 struct Entry {
154 Entry()
155 : packet(), type(ePacketTypeInvalid), bytes_transmitted(0),
156 packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {}
Eugene Zelenkoedb35d92015-10-24 01:08:35 +0000157
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158 void Clear() {
159 packet.clear();
160 type = ePacketTypeInvalid;
161 bytes_transmitted = 0;
162 packet_idx = 0;
163 tid = LLDB_INVALID_THREAD_ID;
164 }
165 std::string packet;
166 PacketType type;
167 uint32_t bytes_transmitted;
168 uint32_t packet_idx;
169 lldb::tid_t tid;
170 };
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 History(uint32_t size);
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000173
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174 ~History();
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 // For single char packets for ack, nack and /x03
177 void AddPacket(char packet_char, PacketType type,
178 uint32_t bytes_transmitted);
Greg Clayton6779606a2011-01-22 23:43:18 +0000179
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
181 uint32_t bytes_transmitted);
182
183 void Dump(Stream &strm) const;
184
185 void Dump(Log *log) const;
186
187 bool DidDumpToLog() const { return m_dumped_to_log; }
188
189 protected:
190 uint32_t GetFirstSavedPacketIndex() const {
191 if (m_total_packet_count < m_packets.size())
192 return 0;
193 else
194 return m_curr_idx + 1;
Jason Molenda91ffe0a2015-06-18 21:46:06 +0000195 }
196
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 uint32_t GetNumPacketsInHistory() const {
198 if (m_total_packet_count < m_packets.size())
199 return m_total_packet_count;
200 else
201 return (uint32_t)m_packets.size();
202 }
Jason Molenda91ffe0a2015-06-18 21:46:06 +0000203
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204 uint32_t GetNextIndex() {
205 ++m_total_packet_count;
206 const uint32_t idx = m_curr_idx;
207 m_curr_idx = NormalizeIndex(idx + 1);
208 return idx;
209 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 uint32_t NormalizeIndex(uint32_t i) const { return i % m_packets.size(); }
Greg Clayton00fe87b2013-12-05 22:58:22 +0000212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213 std::vector<Entry> m_packets;
214 uint32_t m_curr_idx;
215 uint32_t m_total_packet_count;
216 mutable bool m_dumped_to_log;
217 };
Greg Clayton8b82f082011-04-12 05:54:46 +0000218
Pavel Labath3aa04912016-10-31 17:19:42 +0000219 std::chrono::seconds m_packet_timeout;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220 uint32_t m_echo_number;
221 LazyBool m_supports_qEcho;
222 History m_history;
223 bool m_send_acks;
224 bool m_is_platform; // Set to true if this class represents a platform,
225 // false if this class represents a debug session for
226 // a single process
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000227
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228 CompressionType m_compression_type;
229
230 PacketResult SendPacketNoLock(llvm::StringRef payload);
231
232 PacketResult ReadPacket(StringExtractorGDBRemote &response,
Pavel Labath1eff73c2016-11-24 10:54:49 +0000233 Timeout<std::micro> timeout, bool sync_on_timeout);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234
235 // Pop a packet from the queue in a thread safe manner
236 PacketResult PopPacketFromQueue(StringExtractorGDBRemote &response,
Pavel Labath1eff73c2016-11-24 10:54:49 +0000237 Timeout<std::micro> timeout);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000238
Pavel Labath1eff73c2016-11-24 10:54:49 +0000239 PacketResult WaitForPacketNoLock(StringExtractorGDBRemote &response,
240 Timeout<std::micro> timeout,
241 bool sync_on_timeout);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242
243 bool CompressionIsEnabled() {
244 return m_compression_type != CompressionType::None;
245 }
246
247 // If compression is enabled, decompress the packet in m_bytes and update
248 // m_bytes with the uncompressed version.
249 // Returns 'true' packet was decompressed and m_bytes is the now-decompressed
250 // text.
251 // Returns 'false' if unable to decompress or if the checksum was invalid.
252 //
253 // NB: Once the packet has been decompressed, checksum cannot be computed
254 // based
255 // on m_bytes. The checksum was for the compressed packet.
256 bool DecompressPacket();
257
Zachary Turner97206d52017-05-12 04:51:55 +0000258 Status StartListenThread(const char *hostname = "127.0.0.1",
259 uint16_t port = 0);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260
261 bool JoinListenThread();
262
263 static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg);
264
265 // GDB-Remote read thread
266 // . this thread constantly tries to read from the communication
267 // class and stores all packets received in a queue. The usual
268 // threads read requests simply pop packets off the queue in the
269 // usual order.
270 // This setup allows us to intercept and handle async packets, such
271 // as the notify packet.
272
273 // This method is defined as part of communication.h
274 // when the read thread gets any bytes it will pass them on to this function
275 void AppendBytesToCache(const uint8_t *bytes, size_t len, bool broadcast,
276 lldb::ConnectionStatus status) override;
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000277
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000278private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279 std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
280 std::mutex m_packet_queue_mutex; // Mutex for accessing queue
281 std::condition_variable
282 m_condition_queue_not_empty; // Condition variable to wait for packets
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000283
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 HostThread m_listen_thread;
285 std::string m_listen_url;
Greg Clayton00fe87b2013-12-05 22:58:22 +0000286
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287 DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288};
289
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000290} // namespace process_gdb_remote
291} // namespace lldb_private
292
Pavel Labath1ebc85f2017-11-09 15:45:09 +0000293namespace llvm {
294template <>
295struct format_provider<
296 lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult> {
297 static void format(const lldb_private::process_gdb_remote::
298 GDBRemoteCommunication::PacketResult &state,
299 raw_ostream &Stream, StringRef Style);
300};
301} // namespace llvm
302
Eugene Zelenkoedb35d92015-10-24 01:08:35 +0000303#endif // liblldb_GDBRemoteCommunication_h_