blob: c13352781b36d529426779b69a49fa495e6a8268 [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
15#include <list>
16#include <string>
Ewan Crawfordfab40d32015-06-16 15:50:18 +000017#include <queue>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018
19// Other libraries and framework includes
20// Project includes
Greg Claytonc1422c12012-04-09 22:46:21 +000021#include "lldb/lldb-public.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/Communication.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/Listener.h"
Zachary Turner39de3112014-09-09 20:54:56 +000024#include "lldb/Host/HostThread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Host/Mutex.h"
26#include "lldb/Host/Predicate.h"
Peter Collingbourneba23ca02011-06-18 23:52:14 +000027#include "lldb/Host/TimeValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028
Greg Claytonc982c762010-07-09 20:39:50 +000029#include "Utility/StringExtractorGDBRemote.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030
Tamas Berghammerdb264a62015-03-31 09:52:22 +000031namespace lldb_private {
32namespace process_gdb_remote {
33
Chaoren Lin18fe6402015-02-03 01:51:47 +000034typedef enum
35{
36 eStoppointInvalid = -1,
37 eBreakpointSoftware = 0,
38 eBreakpointHardware,
39 eWatchpointWrite,
40 eWatchpointRead,
41 eWatchpointReadWrite
42} GDBStoppointType;
43
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044class ProcessGDBRemote;
45
Tamas Berghammerdb264a62015-03-31 09:52:22 +000046class GDBRemoteCommunication : public Communication
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047{
48public:
Greg Claytone5219662010-12-03 06:02:24 +000049 enum
50 {
Ewan Crawfordfab40d32015-06-16 15:50:18 +000051 eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
52 eBroadcastBitGdbReadThreadGotNotify = kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
Greg Claytone5219662010-12-03 06:02:24 +000053 };
Ewan Crawford9aa2da002015-05-27 14:12:34 +000054
55 enum class PacketType
56 {
57 Invalid = 0,
58 Standard,
59 Notify
60 };
61
Greg Clayton3dedae12013-12-06 21:45:27 +000062 enum class PacketResult
63 {
64 Success = 0, // Success
65 ErrorSendFailed, // Error sending the packet
66 ErrorSendAck, // Didn't get an ack back after sending a packet
67 ErrorReplyFailed, // Error getting the reply
68 ErrorReplyTimeout, // Timed out waiting for reply
69 ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that was sent
70 ErrorReplyAck, // Sending reply ack failed
Steve Pucci5ae54ae2014-01-25 05:46:51 +000071 ErrorDisconnected, // We were disconnected
72 ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request
Greg Clayton3dedae12013-12-06 21:45:27 +000073 };
Tamas Berghammer912800c2015-02-24 10:23:39 +000074
75 // Class to change the timeout for a given scope and restore it to the original value when the
76 // created ScopedTimeout object got out of scope
77 class ScopedTimeout
78 {
79 public:
80 ScopedTimeout (GDBRemoteCommunication& gdb_comm, uint32_t timeout);
81 ~ScopedTimeout ();
82
83 private:
84 GDBRemoteCommunication& m_gdb_comm;
85 uint32_t m_saved_timeout;
86 };
87
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088 //------------------------------------------------------------------
89 // Constructors and Destructors
90 //------------------------------------------------------------------
Greg Clayton8b82f082011-04-12 05:54:46 +000091 GDBRemoteCommunication(const char *comm_name,
Tamas Berghammere13c2732015-02-11 10:29:30 +000092 const char *listener_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093
94 virtual
95 ~GDBRemoteCommunication();
96
Greg Clayton3dedae12013-12-06 21:45:27 +000097 PacketResult
Greg Claytonc574ede2011-03-10 02:26:48 +000098 GetAck ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099
100 size_t
Greg Clayton6ed95942011-01-22 07:12:45 +0000101 SendAck ();
102
103 size_t
104 SendNack ();
105
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106 char
107 CalculcateChecksum (const char *payload,
108 size_t payload_length);
109
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 bool
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000111 GetSequenceMutex (Mutex::Locker& locker, const char *failure_message = NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112
Ewan Crawford9aa2da002015-05-27 14:12:34 +0000113 PacketType
Greg Clayton73bf5db2011-06-17 01:22:15 +0000114 CheckForPacket (const uint8_t *src,
115 size_t src_len,
116 StringExtractorGDBRemote &packet);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117 bool
118 IsRunning() const
119 {
Greg Clayton4dc72282011-01-20 07:53:45 +0000120 return m_public_is_running.GetValue();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121 }
Greg Clayton6779606a2011-01-22 23:43:18 +0000122
Greg Clayton1cb64962011-03-24 04:28:38 +0000123 bool
124 GetSendAcks ()
125 {
126 return m_send_acks;
127 }
128
Greg Clayton576d8832011-03-22 04:00:09 +0000129 //------------------------------------------------------------------
130 // Client and server must implement these pure virtual functions
131 //------------------------------------------------------------------
132 virtual bool
133 GetThreadSuffixSupported () = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000134
Greg Clayton576d8832011-03-22 04:00:09 +0000135 //------------------------------------------------------------------
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 might not
140 // get used, and if it doesn't this should be moved to the
141 // GDBRemoteCommunicationClient.
142 //------------------------------------------------------------------
Greg Claytonc574ede2011-03-10 02:26:48 +0000143 uint32_t
144 SetPacketTimeout (uint32_t packet_timeout)
145 {
146 const uint32_t old_packet_timeout = m_packet_timeout;
147 m_packet_timeout = packet_timeout;
148 return old_packet_timeout;
149 }
Greg Clayton71fc2a32011-02-12 06:28:37 +0000150
Greg Clayton73bf5db2011-06-17 01:22:15 +0000151 uint32_t
152 GetPacketTimeoutInMicroSeconds () const
153 {
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000154 return m_packet_timeout * TimeValue::MicroSecPerSec;
Greg Clayton73bf5db2011-06-17 01:22:15 +0000155 }
Greg Clayton8b82f082011-04-12 05:54:46 +0000156 //------------------------------------------------------------------
157 // Start a debugserver instance on the current host using the
158 // supplied connection URL.
159 //------------------------------------------------------------------
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000160 Error
Greg Claytonfda4fab2014-01-10 22:24:11 +0000161 StartDebugserverProcess (const char *hostname,
162 uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000163 ProcessLaunchInfo &launch_info,
Greg Claytonfda4fab2014-01-10 22:24:11 +0000164 uint16_t &out_port);
Greg Clayton8b82f082011-04-12 05:54:46 +0000165
Greg Claytonc1422c12012-04-09 22:46:21 +0000166 void
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000167 DumpHistory(Stream &strm);
Greg Clayton73bf5db2011-06-17 01:22:15 +0000168
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169protected:
Greg Claytonc1422c12012-04-09 22:46:21 +0000170
171 class History
172 {
173 public:
174 enum PacketType
175 {
176 ePacketTypeInvalid = 0,
177 ePacketTypeSend,
178 ePacketTypeRecv
179 };
180
181 struct Entry
182 {
183 Entry() :
184 packet(),
185 type (ePacketTypeInvalid),
186 bytes_transmitted (0),
Greg Claytond451c1a2012-04-13 21:24:18 +0000187 packet_idx (0),
188 tid (LLDB_INVALID_THREAD_ID)
Greg Claytonc1422c12012-04-09 22:46:21 +0000189 {
190 }
191
192 void
193 Clear ()
194 {
195 packet.clear();
196 type = ePacketTypeInvalid;
197 bytes_transmitted = 0;
198 packet_idx = 0;
Greg Claytond451c1a2012-04-13 21:24:18 +0000199 tid = LLDB_INVALID_THREAD_ID;
Greg Claytonc1422c12012-04-09 22:46:21 +0000200 }
201 std::string packet;
202 PacketType type;
203 uint32_t bytes_transmitted;
204 uint32_t packet_idx;
Greg Claytond451c1a2012-04-13 21:24:18 +0000205 lldb::tid_t tid;
Greg Claytonc1422c12012-04-09 22:46:21 +0000206 };
207
208 History (uint32_t size);
209
210 ~History ();
211
212 // For single char packets for ack, nack and /x03
213 void
214 AddPacket (char packet_char,
215 PacketType type,
Greg Claytond451c1a2012-04-13 21:24:18 +0000216 uint32_t bytes_transmitted);
Greg Claytonc1422c12012-04-09 22:46:21 +0000217 void
218 AddPacket (const std::string &src,
219 uint32_t src_len,
220 PacketType type,
Greg Claytond451c1a2012-04-13 21:24:18 +0000221 uint32_t bytes_transmitted);
Greg Claytonc1422c12012-04-09 22:46:21 +0000222
223 void
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000224 Dump (Stream &strm) const;
Greg Claytonc1422c12012-04-09 22:46:21 +0000225
226 void
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000227 Dump (Log *log) const;
Greg Claytonc1422c12012-04-09 22:46:21 +0000228
229 bool
230 DidDumpToLog () const
231 {
232 return m_dumped_to_log;
233 }
234
235protected:
236 uint32_t
237 GetFirstSavedPacketIndex () const
238 {
239 if (m_total_packet_count < m_packets.size())
240 return 0;
241 else
242 return m_curr_idx + 1;
243 }
244
245 uint32_t
246 GetNumPacketsInHistory () const
247 {
248 if (m_total_packet_count < m_packets.size())
249 return m_total_packet_count;
250 else
251 return (uint32_t)m_packets.size();
252 }
253
254 uint32_t
255 GetNextIndex()
256 {
257 ++m_total_packet_count;
258 const uint32_t idx = m_curr_idx;
259 m_curr_idx = NormalizeIndex(idx + 1);
260 return idx;
261 }
262
263 uint32_t
264 NormalizeIndex (uint32_t i) const
265 {
266 return i % m_packets.size();
267 }
268
269
270 std::vector<Entry> m_packets;
271 uint32_t m_curr_idx;
272 uint32_t m_total_packet_count;
273 mutable bool m_dumped_to_log;
274 };
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275
Greg Clayton3dedae12013-12-06 21:45:27 +0000276 PacketResult
Greg Clayton37a0a242012-04-11 00:24:49 +0000277 SendPacket (const char *payload,
278 size_t payload_length);
279
Greg Clayton3dedae12013-12-06 21:45:27 +0000280 PacketResult
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281 SendPacketNoLock (const char *payload,
282 size_t payload_length);
283
Greg Clayton3dedae12013-12-06 21:45:27 +0000284 PacketResult
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000285 ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout);
286
287 // Pop a packet from the queue in a thread safe manner
288 PacketResult
289 PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec);
290
291 PacketResult
Greg Clayton73bf5db2011-06-17 01:22:15 +0000292 WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response,
Greg Claytonb30c50c2015-05-29 00:01:55 +0000293 uint32_t timeout_usec,
294 bool sync_on_timeout);
Greg Clayton6779606a2011-01-22 23:43:18 +0000295
296 bool
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000297 WaitForNotRunningPrivate (const TimeValue *timeout_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298
299 //------------------------------------------------------------------
300 // Classes that inherit from GDBRemoteCommunication can see and modify these
301 //------------------------------------------------------------------
Greg Claytonc574ede2011-03-10 02:26:48 +0000302 uint32_t m_packet_timeout;
Greg Claytonb30c50c2015-05-29 00:01:55 +0000303 uint32_t m_echo_number;
304 LazyBool m_supports_qEcho;
Greg Claytonb09c5382013-12-13 17:20:18 +0000305#ifdef ENABLE_MUTEX_ERROR_CHECKING
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000306 TrackingMutex m_sequence_mutex;
Jim Ingham4ceb9282012-06-08 22:50:40 +0000307#else
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000308 Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
Jim Ingham4ceb9282012-06-08 22:50:40 +0000309#endif
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000310 Predicate<bool> m_public_is_running;
311 Predicate<bool> m_private_is_running;
Greg Claytonc1422c12012-04-09 22:46:21 +0000312 History m_history;
Greg Clayton1cb64962011-03-24 04:28:38 +0000313 bool m_send_acks;
Greg Clayton8b82f082011-04-12 05:54:46 +0000314 bool m_is_platform; // Set to true if this class represents a platform,
315 // false if this class represents a debug session for
316 // a single process
Greg Clayton1cb64962011-03-24 04:28:38 +0000317
318
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000319 Error
320 StartListenThread (const char *hostname = "127.0.0.1", uint16_t port = 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321
Greg Clayton00fe87b2013-12-05 22:58:22 +0000322 bool
323 JoinListenThread ();
324
325 static lldb::thread_result_t
326 ListenThread (lldb::thread_arg_t arg);
Greg Clayton8b82f082011-04-12 05:54:46 +0000327
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000328 // GDB-Remote read thread
329 // . this thread constantly tries to read from the communication
330 // class and stores all packets received in a queue. The usual
331 // threads read requests simply pop packets off the queue in the
332 // usual order.
333 // This setup allows us to intercept and handle async packets, such
334 // as the notify packet.
335
336 // This method is defined as part of communication.h
337 // when the read thread gets any bytes it will pass them on to this function
338 virtual void AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, lldb::ConnectionStatus status);
339
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340private:
Ewan Crawfordfab40d32015-06-16 15:50:18 +0000341
342 std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
343 lldb_private::Mutex m_packet_queue_mutex; // Mutex for accessing queue
344 Condition m_condition_queue_not_empty; // Condition variable to wait for packets
345
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000346 HostThread m_listen_thread;
Greg Clayton00fe87b2013-12-05 22:58:22 +0000347 std::string m_listen_url;
Greg Clayton00fe87b2013-12-05 22:58:22 +0000348
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349 //------------------------------------------------------------------
350 // For GDBRemoteCommunication only
351 //------------------------------------------------------------------
352 DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
353};
354
Tamas Berghammerdb264a62015-03-31 09:52:22 +0000355} // namespace process_gdb_remote
356} // namespace lldb_private
357
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358#endif // liblldb_GDBRemoteCommunication_h_