blob: ef0c1983898b8ccfd879657ad99f095d98883cac [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
Chris Lattner24943d22010-06-08 16:52:24 +000048 char
Greg Claytonc97bfdb2011-03-10 02:26:48 +000049 GetAck ();
Chris Lattner24943d22010-06-08 16:52:24 +000050
51 size_t
Greg Claytona4881d02011-01-22 07:12:45 +000052 SendAck ();
53
54 size_t
55 SendNack ();
56
Chris Lattner24943d22010-06-08 16:52:24 +000057 char
58 CalculcateChecksum (const char *payload,
59 size_t payload_length);
60
Chris Lattner24943d22010-06-08 16:52:24 +000061 bool
Greg Clayton516f0842012-04-11 00:24:49 +000062 GetSequenceMutex (lldb_private::Mutex::Locker& locker, uint32_t usec_timeout);
Chris Lattner24943d22010-06-08 16:52:24 +000063
Greg Clayton63afdb02011-06-17 01:22:15 +000064 bool
65 CheckForPacket (const uint8_t *src,
66 size_t src_len,
67 StringExtractorGDBRemote &packet);
Chris Lattner24943d22010-06-08 16:52:24 +000068 bool
69 IsRunning() const
70 {
Greg Claytoncecf3482011-01-20 07:53:45 +000071 return m_public_is_running.GetValue();
Chris Lattner24943d22010-06-08 16:52:24 +000072 }
Greg Clayton72e1c782011-01-22 23:43:18 +000073
Greg Clayton58e26e02011-03-24 04:28:38 +000074 bool
75 GetSendAcks ()
76 {
77 return m_send_acks;
78 }
79
Greg Clayton61d043b2011-03-22 04:00:09 +000080 //------------------------------------------------------------------
81 // Client and server must implement these pure virtual functions
82 //------------------------------------------------------------------
83 virtual bool
84 GetThreadSuffixSupported () = 0;
Chris Lattner24943d22010-06-08 16:52:24 +000085
Greg Clayton61d043b2011-03-22 04:00:09 +000086 //------------------------------------------------------------------
87 // Set the global packet timeout.
88 //
89 // For clients, this is the timeout that gets used when sending
90 // packets and waiting for responses. For servers, this might not
91 // get used, and if it doesn't this should be moved to the
92 // GDBRemoteCommunicationClient.
93 //------------------------------------------------------------------
Greg Claytonc97bfdb2011-03-10 02:26:48 +000094 uint32_t
95 SetPacketTimeout (uint32_t packet_timeout)
96 {
97 const uint32_t old_packet_timeout = m_packet_timeout;
98 m_packet_timeout = packet_timeout;
99 return old_packet_timeout;
100 }
Greg Claytonc1f45872011-02-12 06:28:37 +0000101
Greg Clayton63afdb02011-06-17 01:22:15 +0000102 uint32_t
103 GetPacketTimeoutInMicroSeconds () const
104 {
Peter Collingbourne20fe30c2011-06-18 23:52:14 +0000105 return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
Greg Clayton63afdb02011-06-17 01:22:15 +0000106 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000107 //------------------------------------------------------------------
108 // Start a debugserver instance on the current host using the
109 // supplied connection URL.
110 //------------------------------------------------------------------
111 lldb_private::Error
112 StartDebugserverProcess (const char *connect_url,
113 const char *unix_socket_name,
114 lldb_private::ProcessLaunchInfo &launch_info);
115
Greg Clayton451fa822012-04-09 22:46:21 +0000116 void
117 DumpHistory(const char *path);
Greg Clayton63afdb02011-06-17 01:22:15 +0000118
Chris Lattner24943d22010-06-08 16:52:24 +0000119protected:
Greg Clayton451fa822012-04-09 22:46:21 +0000120
121 class History
122 {
123 public:
124 enum PacketType
125 {
126 ePacketTypeInvalid = 0,
127 ePacketTypeSend,
128 ePacketTypeRecv
129 };
130
131 struct Entry
132 {
133 Entry() :
134 packet(),
135 type (ePacketTypeInvalid),
136 bytes_transmitted (0),
137 packet_idx (0)
138 {
139 }
140
141 void
142 Clear ()
143 {
144 packet.clear();
145 type = ePacketTypeInvalid;
146 bytes_transmitted = 0;
147 packet_idx = 0;
148
149 }
150 std::string packet;
151 PacketType type;
152 uint32_t bytes_transmitted;
153 uint32_t packet_idx;
154 };
155
156 History (uint32_t size);
157
158 ~History ();
159
160 // For single char packets for ack, nack and /x03
161 void
162 AddPacket (char packet_char,
163 PacketType type,
164 uint32_t bytes_transmitted)
165 {
166 const size_t size = m_packets.size();
167 if (size > 0)
168 {
169 const uint32_t idx = GetNextIndex();
170 m_packets[idx].packet.assign (1, packet_char);
171 m_packets[idx].type = type;
172 m_packets[idx].bytes_transmitted = bytes_transmitted;
173 m_packets[idx].packet_idx = m_total_packet_count;
174 }
175 }
176
177 void
178 AddPacket (const std::string &src,
179 uint32_t src_len,
180 PacketType type,
181 uint32_t bytes_transmitted)
182 {
183 const size_t size = m_packets.size();
184 if (size > 0)
185 {
186 const uint32_t idx = GetNextIndex();
187 m_packets[idx].packet.assign (src, 0, src_len);
188 m_packets[idx].type = type;
189 m_packets[idx].bytes_transmitted = bytes_transmitted;
190 m_packets[idx].packet_idx = m_total_packet_count;
191 }
192 }
193
194 void
195 Dump (lldb_private::Stream &strm) const;
196
197 void
198 Dump (lldb_private::Log *log) const;
199
200 bool
201 DidDumpToLog () const
202 {
203 return m_dumped_to_log;
204 }
205
206protected:
207 uint32_t
208 GetFirstSavedPacketIndex () const
209 {
210 if (m_total_packet_count < m_packets.size())
211 return 0;
212 else
213 return m_curr_idx + 1;
214 }
215
216 uint32_t
217 GetNumPacketsInHistory () const
218 {
219 if (m_total_packet_count < m_packets.size())
220 return m_total_packet_count;
221 else
222 return (uint32_t)m_packets.size();
223 }
224
225 uint32_t
226 GetNextIndex()
227 {
228 ++m_total_packet_count;
229 const uint32_t idx = m_curr_idx;
230 m_curr_idx = NormalizeIndex(idx + 1);
231 return idx;
232 }
233
234 uint32_t
235 NormalizeIndex (uint32_t i) const
236 {
237 return i % m_packets.size();
238 }
239
240
241 std::vector<Entry> m_packets;
242 uint32_t m_curr_idx;
243 uint32_t m_total_packet_count;
244 mutable bool m_dumped_to_log;
245 };
Chris Lattner24943d22010-06-08 16:52:24 +0000246
247 size_t
Greg Clayton516f0842012-04-11 00:24:49 +0000248 SendPacket (const char *payload,
249 size_t payload_length);
250
251 size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000252 SendPacketNoLock (const char *payload,
253 size_t payload_length);
254
255 size_t
Greg Clayton63afdb02011-06-17 01:22:15 +0000256 WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response,
257 uint32_t timeout_usec);
Greg Clayton72e1c782011-01-22 23:43:18 +0000258
259 bool
260 WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
Chris Lattner24943d22010-06-08 16:52:24 +0000261
262 //------------------------------------------------------------------
263 // Classes that inherit from GDBRemoteCommunication can see and modify these
264 //------------------------------------------------------------------
Greg Claytonc97bfdb2011-03-10 02:26:48 +0000265 uint32_t m_packet_timeout;
Chris Lattner24943d22010-06-08 16:52:24 +0000266 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 +0000267 lldb_private::Predicate<bool> m_public_is_running;
268 lldb_private::Predicate<bool> m_private_is_running;
Greg Clayton451fa822012-04-09 22:46:21 +0000269 History m_history;
Greg Clayton58e26e02011-03-24 04:28:38 +0000270 bool m_send_acks;
Greg Claytonb72d0f02011-04-12 05:54:46 +0000271 bool m_is_platform; // Set to true if this class represents a platform,
272 // false if this class represents a debug session for
273 // a single process
Greg Clayton58e26e02011-03-24 04:28:38 +0000274
275
Chris Lattner24943d22010-06-08 16:52:24 +0000276
Greg Claytonb72d0f02011-04-12 05:54:46 +0000277
Chris Lattner24943d22010-06-08 16:52:24 +0000278private:
279 //------------------------------------------------------------------
280 // For GDBRemoteCommunication only
281 //------------------------------------------------------------------
282 DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
283};
284
285#endif // liblldb_GDBRemoteCommunication_h_