blob: d7986d5b278c005526d556bc2bd462f78566ac17 [file] [log] [blame]
Chris Lattner24943d22010-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>
17
18// Other libraries and framework includes
19// Project includes
Greg Clayton451fa822012-04-09 22:46:21 +000020#include "lldb/lldb-public.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/Communication.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Core/Listener.h"
23#include "lldb/Host/Mutex.h"
24#include "lldb/Host/Predicate.h"
Peter Collingbourne20fe30c2011-06-18 23:52:14 +000025#include "lldb/Host/TimeValue.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026
Greg Clayton54e7afa2010-07-09 20:39:50 +000027#include "Utility/StringExtractorGDBRemote.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028
29class ProcessGDBRemote;
30
Greg Clayton61d043b2011-03-22 04:00:09 +000031class GDBRemoteCommunication : public lldb_private::Communication
Chris Lattner24943d22010-06-08 16:52:24 +000032{
33public:
Greg Claytonb749a262010-12-03 06:02:24 +000034 enum
35 {
36 eBroadcastBitRunPacketSent = kLoUserBroadcastBit
37 };
Chris Lattner24943d22010-06-08 16:52:24 +000038 //------------------------------------------------------------------
39 // Constructors and Destructors
40 //------------------------------------------------------------------
Greg Claytonb72d0f02011-04-12 05:54:46 +000041 GDBRemoteCommunication(const char *comm_name,
42 const char *listener_name,
43 bool is_platform);
Chris Lattner24943d22010-06-08 16:52:24 +000044
45 virtual
46 ~GDBRemoteCommunication();
47
48 size_t
49 SendPacket (const char *payload);
50
51 size_t
52 SendPacket (const char *payload,
53 size_t payload_length);
54
Greg Clayton24bc5d92011-03-30 18:16:51 +000055 size_t
56 SendPacket (lldb_private::StreamString &response);
57
Chris Lattner24943d22010-06-08 16:52:24 +000058 // Wait for a packet within 'nsec' seconds
59 size_t
Greg Clayton63afdb02011-06-17 01:22:15 +000060 WaitForPacketWithTimeoutMicroSeconds (StringExtractorGDBRemote &response,
61 uint32_t usec);
Chris Lattner24943d22010-06-08 16:52:24 +000062
63 char
Greg Claytonc97bfdb2011-03-10 02:26:48 +000064 GetAck ();
Chris Lattner24943d22010-06-08 16:52:24 +000065
66 size_t
Greg Claytona4881d02011-01-22 07:12:45 +000067 SendAck ();
68
69 size_t
70 SendNack ();
71
Chris Lattner24943d22010-06-08 16:52:24 +000072 char
73 CalculcateChecksum (const char *payload,
74 size_t payload_length);
75
Chris Lattner24943d22010-06-08 16:52:24 +000076 bool
Greg Claytonae932352012-04-10 00:18:59 +000077 TryLockSequenceMutex(lldb_private::Mutex::Locker& locker);
Chris Lattner24943d22010-06-08 16:52:24 +000078
Greg Clayton63afdb02011-06-17 01:22:15 +000079 bool
80 CheckForPacket (const uint8_t *src,
81 size_t src_len,
82 StringExtractorGDBRemote &packet);
Chris Lattner24943d22010-06-08 16:52:24 +000083 bool
84 IsRunning() const
85 {
Greg Claytoncecf3482011-01-20 07:53:45 +000086 return m_public_is_running.GetValue();
Chris Lattner24943d22010-06-08 16:52:24 +000087 }
Greg Clayton72e1c782011-01-22 23:43:18 +000088
Greg Clayton58e26e02011-03-24 04:28:38 +000089 bool
90 GetSendAcks ()
91 {
92 return m_send_acks;
93 }
94
Greg Clayton61d043b2011-03-22 04:00:09 +000095 //------------------------------------------------------------------
96 // Client and server must implement these pure virtual functions
97 //------------------------------------------------------------------
98 virtual bool
99 GetThreadSuffixSupported () = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000100
Greg Clayton61d043b2011-03-22 04:00:09 +0000101 //------------------------------------------------------------------
102 // Set the global packet timeout.
103 //
104 // For clients, this is the timeout that gets used when sending
105 // packets and waiting for responses. For servers, this might not
106 // get used, and if it doesn't this should be moved to the
107 // GDBRemoteCommunicationClient.
108 //------------------------------------------------------------------
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000109 uint32_t
110 SetPacketTimeout (uint32_t packet_timeout)
111 {
112 const uint32_t old_packet_timeout = m_packet_timeout;
113 m_packet_timeout = packet_timeout;
114 return old_packet_timeout;
115 }
Greg Claytonc1f45872011-02-12 06:28:37 +0000116
Greg Clayton63afdb02011-06-17 01:22:15 +0000117 uint32_t
118 GetPacketTimeoutInMicroSeconds () const
119 {
Peter Collingbourne20fe30c2011-06-18 23:52:14 +0000120 return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
Greg Clayton63afdb02011-06-17 01:22:15 +0000121 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000122 //------------------------------------------------------------------
123 // Start a debugserver instance on the current host using the
124 // supplied connection URL.
125 //------------------------------------------------------------------
126 lldb_private::Error
127 StartDebugserverProcess (const char *connect_url,
128 const char *unix_socket_name,
129 lldb_private::ProcessLaunchInfo &launch_info);
130
Greg Clayton451fa822012-04-09 22:46:21 +0000131 void
132 DumpHistory(const char *path);
Greg Clayton63afdb02011-06-17 01:22:15 +0000133
Chris Lattner24943d22010-06-08 16:52:24 +0000134protected:
Greg Clayton451fa822012-04-09 22:46:21 +0000135
136 class History
137 {
138 public:
139 enum PacketType
140 {
141 ePacketTypeInvalid = 0,
142 ePacketTypeSend,
143 ePacketTypeRecv
144 };
145
146 struct Entry
147 {
148 Entry() :
149 packet(),
150 type (ePacketTypeInvalid),
151 bytes_transmitted (0),
152 packet_idx (0)
153 {
154 }
155
156 void
157 Clear ()
158 {
159 packet.clear();
160 type = ePacketTypeInvalid;
161 bytes_transmitted = 0;
162 packet_idx = 0;
163
164 }
165 std::string packet;
166 PacketType type;
167 uint32_t bytes_transmitted;
168 uint32_t packet_idx;
169 };
170
171 History (uint32_t size);
172
173 ~History ();
174
175 // For single char packets for ack, nack and /x03
176 void
177 AddPacket (char packet_char,
178 PacketType type,
179 uint32_t bytes_transmitted)
180 {
181 const size_t size = m_packets.size();
182 if (size > 0)
183 {
184 const uint32_t idx = GetNextIndex();
185 m_packets[idx].packet.assign (1, packet_char);
186 m_packets[idx].type = type;
187 m_packets[idx].bytes_transmitted = bytes_transmitted;
188 m_packets[idx].packet_idx = m_total_packet_count;
189 }
190 }
191
192 void
193 AddPacket (const std::string &src,
194 uint32_t src_len,
195 PacketType type,
196 uint32_t bytes_transmitted)
197 {
198 const size_t size = m_packets.size();
199 if (size > 0)
200 {
201 const uint32_t idx = GetNextIndex();
202 m_packets[idx].packet.assign (src, 0, src_len);
203 m_packets[idx].type = type;
204 m_packets[idx].bytes_transmitted = bytes_transmitted;
205 m_packets[idx].packet_idx = m_total_packet_count;
206 }
207 }
208
209 void
210 Dump (lldb_private::Stream &strm) const;
211
212 void
213 Dump (lldb_private::Log *log) const;
214
215 bool
216 DidDumpToLog () const
217 {
218 return m_dumped_to_log;
219 }
220
221protected:
222 uint32_t
223 GetFirstSavedPacketIndex () const
224 {
225 if (m_total_packet_count < m_packets.size())
226 return 0;
227 else
228 return m_curr_idx + 1;
229 }
230
231 uint32_t
232 GetNumPacketsInHistory () const
233 {
234 if (m_total_packet_count < m_packets.size())
235 return m_total_packet_count;
236 else
237 return (uint32_t)m_packets.size();
238 }
239
240 uint32_t
241 GetNextIndex()
242 {
243 ++m_total_packet_count;
244 const uint32_t idx = m_curr_idx;
245 m_curr_idx = NormalizeIndex(idx + 1);
246 return idx;
247 }
248
249 uint32_t
250 NormalizeIndex (uint32_t i) const
251 {
252 return i % m_packets.size();
253 }
254
255
256 std::vector<Entry> m_packets;
257 uint32_t m_curr_idx;
258 uint32_t m_total_packet_count;
259 mutable bool m_dumped_to_log;
260 };
Chris Lattner24943d22010-06-08 16:52:24 +0000261
262 size_t
263 SendPacketNoLock (const char *payload,
264 size_t payload_length);
265
266 size_t
Greg Clayton63afdb02011-06-17 01:22:15 +0000267 WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response,
268 uint32_t timeout_usec);
Greg Clayton72e1c782011-01-22 23:43:18 +0000269
270 bool
271 WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
Chris Lattner24943d22010-06-08 16:52:24 +0000272
273 //------------------------------------------------------------------
274 // Classes that inherit from GDBRemoteCommunication can see and modify these
275 //------------------------------------------------------------------
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000276 uint32_t m_packet_timeout;
Chris Lattner24943d22010-06-08 16:52:24 +0000277 lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
Greg Claytoncecf3482011-01-20 07:53:45 +0000278 lldb_private::Predicate<bool> m_public_is_running;
279 lldb_private::Predicate<bool> m_private_is_running;
Greg Clayton451fa822012-04-09 22:46:21 +0000280 History m_history;
Greg Clayton58e26e02011-03-24 04:28:38 +0000281 bool m_send_acks;
Greg Claytonb72d0f02011-04-12 05:54:46 +0000282 bool m_is_platform; // Set to true if this class represents a platform,
283 // false if this class represents a debug session for
284 // a single process
Greg Clayton58e26e02011-03-24 04:28:38 +0000285
286
Chris Lattner24943d22010-06-08 16:52:24 +0000287
Greg Claytonb72d0f02011-04-12 05:54:46 +0000288
Chris Lattner24943d22010-06-08 16:52:24 +0000289private:
290 //------------------------------------------------------------------
291 // For GDBRemoteCommunication only
292 //------------------------------------------------------------------
293 DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
294};
295
296#endif // liblldb_GDBRemoteCommunication_h_