1 //===-- 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 <string>
16 #include <queue>
17 #include <vector>
18 
19 // Other libraries and framework includes
20 // Project includes
21 #include "lldb/lldb-public.h"
22 #include "lldb/Core/Communication.h"
23 #include "lldb/Core/Listener.h"
24 #include "lldb/Host/HostThread.h"
25 #include "lldb/Host/Mutex.h"
26 #include "lldb/Host/Predicate.h"
27 #include "lldb/Host/TimeValue.h"
28 
29 #include "Utility/StringExtractorGDBRemote.h"
30 
31 namespace lldb_private {
32 namespace process_gdb_remote {
33 
34 typedef enum
35 {
36     eStoppointInvalid = -1,
37     eBreakpointSoftware = 0,
38     eBreakpointHardware,
39     eWatchpointWrite,
40     eWatchpointRead,
41     eWatchpointReadWrite
42 } GDBStoppointType;
43 
44 enum class CompressionType
45 {
46     None = 0,       // no compression
47     ZlibDeflate,    // zlib's deflate compression scheme, requires zlib or Apple's libcompression
48     LZFSE,          // an Apple compression scheme, requires Apple's libcompression
49     LZ4,            // lz compression - called "lz4 raw" in libcompression terms, compat with https://code.google.com/p/lz4/
50     LZMA,           // Lempel–Ziv–Markov chain algorithm
51 };
52 
53 class ProcessGDBRemote;
54 
55 class GDBRemoteCommunication : public Communication
56 {
57 public:
58     enum
59     {
60         eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
61         eBroadcastBitGdbReadThreadGotNotify = kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
62     };
63 
64     enum class PacketType
65     {
66         Invalid = 0,
67         Standard,
68         Notify
69     };
70 
71     enum class PacketResult
72     {
73         Success = 0,        // Success
74         ErrorSendFailed,    // Error sending the packet
75         ErrorSendAck,       // Didn't get an ack back after sending a packet
76         ErrorReplyFailed,   // Error getting the reply
77         ErrorReplyTimeout,  // Timed out waiting for reply
78         ErrorReplyInvalid,  // Got a reply but it wasn't valid for the packet that was sent
79         ErrorReplyAck,      // Sending reply ack failed
80         ErrorDisconnected,  // We were disconnected
81         ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request
82     };
83 
84     // Class to change the timeout for a given scope and restore it to the original value when the
85     // created ScopedTimeout object got out of scope
86     class ScopedTimeout
87     {
88     public:
89         ScopedTimeout (GDBRemoteCommunication& gdb_comm, uint32_t timeout);
90         ~ScopedTimeout ();
91 
92     private:
93         GDBRemoteCommunication& m_gdb_comm;
94         uint32_t m_saved_timeout;
95     };
96 
97     GDBRemoteCommunication(const char *comm_name,
98                            const char *listener_name);
99 
100     ~GDBRemoteCommunication() override;
101 
102     PacketResult
103     GetAck ();
104 
105     size_t
106     SendAck ();
107 
108     size_t
109     SendNack ();
110 
111     char
112     CalculcateChecksum (const char *payload,
113                         size_t payload_length);
114 
115     bool
116     GetSequenceMutex(Mutex::Locker& locker, const char *failure_message = nullptr);
117 
118     PacketType
119     CheckForPacket (const uint8_t *src,
120                     size_t src_len,
121                     StringExtractorGDBRemote &packet);
122 
123     bool
124     IsRunning() const
125     {
126         return m_public_is_running.GetValue();
127     }
128 
129     bool
130     GetSendAcks ()
131     {
132         return m_send_acks;
133     }
134 
135     //------------------------------------------------------------------
136     // Client and server must implement these pure virtual functions
137     //------------------------------------------------------------------
138     virtual bool
139     GetThreadSuffixSupported () = 0;
140 
141     //------------------------------------------------------------------
142     // Set the global packet timeout.
143     //
144     // For clients, this is the timeout that gets used when sending
145     // packets and waiting for responses. For servers, this might not
146     // get used, and if it doesn't this should be moved to the
147     // GDBRemoteCommunicationClient.
148     //------------------------------------------------------------------
149     uint32_t
150     SetPacketTimeout (uint32_t packet_timeout)
151     {
152         const uint32_t old_packet_timeout = m_packet_timeout;
153         m_packet_timeout = packet_timeout;
154         return old_packet_timeout;
155     }
156 
157     uint32_t
158     GetPacketTimeoutInMicroSeconds () const
159     {
160         return m_packet_timeout * TimeValue::MicroSecPerSec;
161     }
162 
163     //------------------------------------------------------------------
164     // Start a debugserver instance on the current host using the
165     // supplied connection URL.
166     //------------------------------------------------------------------
167     Error
168     StartDebugserverProcess(const char *url,
169                             Platform *platform, // If non nullptr, then check with the platform for the GDB server binary if it can't be located
170                             ProcessLaunchInfo &launch_info,
171                             uint16_t *port);
172 
173     void
174     DumpHistory(Stream &strm);
175 
176 protected:
177     class History
178     {
179     public:
180         enum PacketType
181         {
182             ePacketTypeInvalid = 0,
183             ePacketTypeSend,
184             ePacketTypeRecv
185         };
186 
187         struct Entry
188         {
189             Entry() :
190                 packet(),
191                 type (ePacketTypeInvalid),
192                 bytes_transmitted (0),
193                 packet_idx (0),
194                 tid (LLDB_INVALID_THREAD_ID)
195             {
196             }
197 
198             void
199             Clear ()
200             {
201                 packet.clear();
202                 type = ePacketTypeInvalid;
203                 bytes_transmitted = 0;
204                 packet_idx = 0;
205                 tid = LLDB_INVALID_THREAD_ID;
206             }
207             std::string packet;
208             PacketType type;
209             uint32_t bytes_transmitted;
210             uint32_t packet_idx;
211             lldb::tid_t tid;
212         };
213 
214         History (uint32_t size);
215 
216         ~History ();
217 
218         // For single char packets for ack, nack and /x03
219         void
220         AddPacket (char packet_char,
221                    PacketType type,
222                    uint32_t bytes_transmitted);
223 
224         void
225         AddPacket (const std::string &src,
226                    uint32_t src_len,
227                    PacketType type,
228                    uint32_t bytes_transmitted);
229 
230         void
231         Dump (Stream &strm) const;
232 
233         void
234         Dump (Log *log) const;
235 
236         bool
237         DidDumpToLog () const
238         {
239             return m_dumped_to_log;
240         }
241 
242     protected:
243         uint32_t
244         GetFirstSavedPacketIndex () const
245         {
246             if (m_total_packet_count < m_packets.size())
247                 return 0;
248             else
249                 return m_curr_idx + 1;
250         }
251 
252         uint32_t
253         GetNumPacketsInHistory () const
254         {
255             if (m_total_packet_count < m_packets.size())
256                 return m_total_packet_count;
257             else
258                 return (uint32_t)m_packets.size();
259         }
260 
261         uint32_t
262         GetNextIndex()
263         {
264             ++m_total_packet_count;
265             const uint32_t idx = m_curr_idx;
266             m_curr_idx = NormalizeIndex(idx + 1);
267             return idx;
268         }
269 
270         uint32_t
271         NormalizeIndex (uint32_t i) const
272         {
273             return i % m_packets.size();
274         }
275 
276         std::vector<Entry> m_packets;
277         uint32_t m_curr_idx;
278         uint32_t m_total_packet_count;
279         mutable bool m_dumped_to_log;
280     };
281 
282     uint32_t m_packet_timeout;
283     uint32_t m_echo_number;
284     LazyBool m_supports_qEcho;
285 #ifdef ENABLE_MUTEX_ERROR_CHECKING
286     TrackingMutex m_sequence_mutex;
287 #else
288     Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
289 #endif
290     Predicate<bool> m_public_is_running;
291     Predicate<bool> m_private_is_running;
292     History m_history;
293     bool m_send_acks;
294     bool m_is_platform; // Set to true if this class represents a platform,
295                         // false if this class represents a debug session for
296                         // a single process
297 
298     CompressionType m_compression_type;
299 
300     PacketResult
301     SendPacket (const char *payload,
302                 size_t payload_length);
303 
304     PacketResult
305     SendPacketNoLock (const char *payload,
306                       size_t payload_length);
307 
308     PacketResult
309     ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout);
310 
311     // Pop a packet from the queue in a thread safe manner
312     PacketResult
313     PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec);
314 
315     PacketResult
316     WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response,
317                                                 uint32_t timeout_usec,
318                                                 bool sync_on_timeout);
319 
320     bool
321     WaitForNotRunningPrivate (const TimeValue *timeout_ptr);
322 
323     bool
324     CompressionIsEnabled ()
325     {
326         return m_compression_type != CompressionType::None;
327     }
328 
329     // If compression is enabled, decompress the packet in m_bytes and update
330     // m_bytes with the uncompressed version.
331     // Returns 'true' packet was decompressed and m_bytes is the now-decompressed text.
332     // Returns 'false' if unable to decompress or if the checksum was invalid.
333     //
334     // NB: Once the packet has been decompressed, checksum cannot be computed based
335     // on m_bytes.  The checksum was for the compressed packet.
336     bool
337     DecompressPacket ();
338 
339     Error
340     StartListenThread (const char *hostname = "127.0.0.1", uint16_t port = 0);
341 
342     bool
343     JoinListenThread ();
344 
345     static lldb::thread_result_t
346     ListenThread (lldb::thread_arg_t arg);
347 
348     // GDB-Remote read thread
349     //  . this thread constantly tries to read from the communication
350     //    class and stores all packets received in a queue.  The usual
351     //    threads read requests simply pop packets off the queue in the
352     //    usual order.
353     //    This setup allows us to intercept and handle async packets, such
354     //    as the notify packet.
355 
356     // This method is defined as part of communication.h
357     // when the read thread gets any bytes it will pass them on to this function
358     void AppendBytesToCache(const uint8_t * bytes,
359                             size_t len,
360                             bool broadcast,
361                             lldb::ConnectionStatus status) override;
362 
363 private:
364     std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
365     lldb_private::Mutex m_packet_queue_mutex;            // Mutex for accessing queue
366     Condition m_condition_queue_not_empty;               // Condition variable to wait for packets
367 
368     HostThread m_listen_thread;
369     std::string m_listen_url;
370 
371     DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
372 };
373 
374 } // namespace process_gdb_remote
375 } // namespace lldb_private
376 
377 #endif // liblldb_GDBRemoteCommunication_h_
378