blob: be90eb2b2c92ba000fc408d1c8072efa4b3d7651 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- GDBRemoteCommunication.cpp ------------------------------*- 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
11#include "GDBRemoteCommunication.h"
12
13// C Includes
Johnny Chena5663552011-05-13 20:07:25 +000014#include <limits.h>
Stephen Wilsona78867b2011-03-25 18:16:28 +000015#include <string.h>
Greg Clayton91a9b2472013-12-04 19:19:12 +000016#include <sys/stat.h>
Stephen Wilsona78867b2011-03-25 18:16:28 +000017
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018// C++ Includes
19// Other libraries and framework includes
Greg Clayton00fe87b2013-12-05 22:58:22 +000020#include "lldb/Core/ConnectionFileDescriptor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/Log.h"
Greg Claytonc1422c12012-04-09 22:46:21 +000022#include "lldb/Core/StreamFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/StreamString.h"
Greg Clayton8b82f082011-04-12 05:54:46 +000024#include "lldb/Host/FileSpec.h"
25#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Host/TimeValue.h"
Greg Clayton8b82f082011-04-12 05:54:46 +000027#include "lldb/Target/Process.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028
29// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "ProcessGDBRemoteLog.h"
31
Todd Fiala015d8182014-07-22 23:41:36 +000032#if defined(__APPLE__)
33# define DEBUGSERVER_BASENAME "debugserver"
34#else
35# define DEBUGSERVER_BASENAME "lldb-gdbserver"
36#endif
Greg Clayton8b82f082011-04-12 05:54:46 +000037
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038using namespace lldb;
39using namespace lldb_private;
40
Greg Claytonc1422c12012-04-09 22:46:21 +000041GDBRemoteCommunication::History::History (uint32_t size) :
42 m_packets(),
43 m_curr_idx (0),
44 m_total_packet_count (0),
45 m_dumped_to_log (false)
46{
47 m_packets.resize(size);
48}
49
50GDBRemoteCommunication::History::~History ()
51{
52}
53
54void
Greg Claytond451c1a2012-04-13 21:24:18 +000055GDBRemoteCommunication::History::AddPacket (char packet_char,
56 PacketType type,
57 uint32_t bytes_transmitted)
58{
59 const size_t size = m_packets.size();
60 if (size > 0)
61 {
62 const uint32_t idx = GetNextIndex();
63 m_packets[idx].packet.assign (1, packet_char);
64 m_packets[idx].type = type;
65 m_packets[idx].bytes_transmitted = bytes_transmitted;
66 m_packets[idx].packet_idx = m_total_packet_count;
67 m_packets[idx].tid = Host::GetCurrentThreadID();
68 }
69}
70
71void
72GDBRemoteCommunication::History::AddPacket (const std::string &src,
73 uint32_t src_len,
74 PacketType type,
75 uint32_t bytes_transmitted)
76{
77 const size_t size = m_packets.size();
78 if (size > 0)
79 {
80 const uint32_t idx = GetNextIndex();
81 m_packets[idx].packet.assign (src, 0, src_len);
82 m_packets[idx].type = type;
83 m_packets[idx].bytes_transmitted = bytes_transmitted;
84 m_packets[idx].packet_idx = m_total_packet_count;
85 m_packets[idx].tid = Host::GetCurrentThreadID();
86 }
87}
88
89void
Greg Claytonc1422c12012-04-09 22:46:21 +000090GDBRemoteCommunication::History::Dump (lldb_private::Stream &strm) const
91{
92 const uint32_t size = GetNumPacketsInHistory ();
93 const uint32_t first_idx = GetFirstSavedPacketIndex ();
94 const uint32_t stop_idx = m_curr_idx + size;
95 for (uint32_t i = first_idx; i < stop_idx; ++i)
96 {
97 const uint32_t idx = NormalizeIndex (i);
98 const Entry &entry = m_packets[idx];
99 if (entry.type == ePacketTypeInvalid || entry.packet.empty())
100 break;
Daniel Malead01b2952012-11-29 21:49:15 +0000101 strm.Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
Greg Claytonc1422c12012-04-09 22:46:21 +0000102 entry.packet_idx,
Greg Claytond451c1a2012-04-13 21:24:18 +0000103 entry.tid,
Greg Claytonc1422c12012-04-09 22:46:21 +0000104 entry.bytes_transmitted,
105 (entry.type == ePacketTypeSend) ? "send" : "read",
106 entry.packet.c_str());
107 }
108}
109
110void
111GDBRemoteCommunication::History::Dump (lldb_private::Log *log) const
112{
113 if (log && !m_dumped_to_log)
114 {
115 m_dumped_to_log = true;
116 const uint32_t size = GetNumPacketsInHistory ();
117 const uint32_t first_idx = GetFirstSavedPacketIndex ();
118 const uint32_t stop_idx = m_curr_idx + size;
119 for (uint32_t i = first_idx; i < stop_idx; ++i)
120 {
121 const uint32_t idx = NormalizeIndex (i);
122 const Entry &entry = m_packets[idx];
123 if (entry.type == ePacketTypeInvalid || entry.packet.empty())
124 break;
Daniel Malead01b2952012-11-29 21:49:15 +0000125 log->Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
Greg Claytonc1422c12012-04-09 22:46:21 +0000126 entry.packet_idx,
Greg Claytond451c1a2012-04-13 21:24:18 +0000127 entry.tid,
Greg Claytonc1422c12012-04-09 22:46:21 +0000128 entry.bytes_transmitted,
129 (entry.type == ePacketTypeSend) ? "send" : "read",
130 entry.packet.c_str());
131 }
132 }
133}
134
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135//----------------------------------------------------------------------
136// GDBRemoteCommunication constructor
137//----------------------------------------------------------------------
Greg Clayton8b82f082011-04-12 05:54:46 +0000138GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
139 const char *listener_name,
140 bool is_platform) :
Greg Clayton576d8832011-03-22 04:00:09 +0000141 Communication(comm_name),
Daniel Maleae0f8f572013-08-26 23:57:52 +0000142#ifdef LLDB_CONFIGURATION_DEBUG
143 m_packet_timeout (1000),
144#else
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000145 m_packet_timeout (1),
Daniel Maleae0f8f572013-08-26 23:57:52 +0000146#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 m_sequence_mutex (Mutex::eMutexTypeRecursive),
Greg Clayton4dc72282011-01-20 07:53:45 +0000148 m_public_is_running (false),
Greg Clayton1cb64962011-03-24 04:28:38 +0000149 m_private_is_running (false),
Greg Claytonc1422c12012-04-09 22:46:21 +0000150 m_history (512),
Greg Clayton8b82f082011-04-12 05:54:46 +0000151 m_send_acks (true),
Greg Clayton00fe87b2013-12-05 22:58:22 +0000152 m_is_platform (is_platform),
153 m_listen_thread (LLDB_INVALID_HOST_THREAD),
154 m_listen_url ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156}
157
158//----------------------------------------------------------------------
159// Destructor
160//----------------------------------------------------------------------
161GDBRemoteCommunication::~GDBRemoteCommunication()
162{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163 if (IsConnected())
164 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165 Disconnect();
166 }
167}
168
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169char
170GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
171{
172 int checksum = 0;
173
Ed Mastea6b4c772013-08-20 14:12:58 +0000174 for (size_t i = 0; i < payload_length; ++i)
175 checksum += payload[i];
176
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000177 return checksum & 255;
178}
179
180size_t
Greg Clayton6ed95942011-01-22 07:12:45 +0000181GDBRemoteCommunication::SendAck ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182{
Greg Clayton5160ce52013-03-27 23:08:40 +0000183 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184 ConnectionStatus status = eConnectionStatusSuccess;
Greg Claytonc1422c12012-04-09 22:46:21 +0000185 char ch = '+';
186 const size_t bytes_written = Write (&ch, 1, status, NULL);
187 if (log)
Greg Clayton45989072013-10-23 18:24:30 +0000188 log->Printf ("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
Greg Claytonc1422c12012-04-09 22:46:21 +0000189 m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
190 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191}
192
193size_t
Greg Clayton6ed95942011-01-22 07:12:45 +0000194GDBRemoteCommunication::SendNack ()
195{
Greg Clayton5160ce52013-03-27 23:08:40 +0000196 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Greg Clayton6ed95942011-01-22 07:12:45 +0000197 ConnectionStatus status = eConnectionStatusSuccess;
Greg Claytonc1422c12012-04-09 22:46:21 +0000198 char ch = '-';
199 const size_t bytes_written = Write (&ch, 1, status, NULL);
200 if (log)
Greg Clayton45989072013-10-23 18:24:30 +0000201 log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
Greg Claytonc1422c12012-04-09 22:46:21 +0000202 m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
203 return bytes_written;
Greg Clayton32e0a752011-03-30 18:16:51 +0000204}
205
Greg Clayton3dedae12013-12-06 21:45:27 +0000206GDBRemoteCommunication::PacketResult
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
208{
209 Mutex::Locker locker(m_sequence_mutex);
210 return SendPacketNoLock (payload, payload_length);
211}
212
Greg Clayton3dedae12013-12-06 21:45:27 +0000213GDBRemoteCommunication::PacketResult
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
215{
216 if (IsConnected())
217 {
218 StreamString packet(0, 4, eByteOrderBig);
219
220 packet.PutChar('$');
221 packet.Write (payload, payload_length);
222 packet.PutChar('#');
223 packet.PutHex8(CalculcateChecksum (payload, payload_length));
224
Greg Clayton5160ce52013-03-27 23:08:40 +0000225 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 ConnectionStatus status = eConnectionStatusSuccess;
227 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
Greg Claytonc1422c12012-04-09 22:46:21 +0000228 if (log)
229 {
230 // If logging was just enabled and we have history, then dump out what
231 // we have to the log so we get the historical context. The Dump() call that
232 // logs all of the packet will set a boolean so that we don't dump this more
233 // than once
234 if (!m_history.DidDumpToLog ())
Greg Clayton5160ce52013-03-27 23:08:40 +0000235 m_history.Dump (log);
Greg Claytonc1422c12012-04-09 22:46:21 +0000236
Greg Clayton45989072013-10-23 18:24:30 +0000237 log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet.GetSize(), packet.GetData());
Greg Claytonc1422c12012-04-09 22:46:21 +0000238 }
239
240 m_history.AddPacket (packet.GetString(), packet.GetSize(), History::ePacketTypeSend, bytes_written);
241
242
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243 if (bytes_written == packet.GetSize())
244 {
Greg Clayton71fc2a32011-02-12 06:28:37 +0000245 if (GetSendAcks ())
Greg Clayton3dedae12013-12-06 21:45:27 +0000246 return GetAck ();
247 else
248 return PacketResult::Success;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 }
Johnny Chend0c40dd2010-09-14 22:10:43 +0000250 else
251 {
Greg Clayton6d093452011-02-05 02:25:06 +0000252 if (log)
Greg Clayton5fe15d22011-05-20 03:15:54 +0000253 log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData());
Johnny Chend0c40dd2010-09-14 22:10:43 +0000254 }
Greg Claytonf5e56de2010-09-14 23:36:40 +0000255 }
Greg Clayton3dedae12013-12-06 21:45:27 +0000256 return PacketResult::ErrorSendFailed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257}
258
Greg Clayton3dedae12013-12-06 21:45:27 +0000259GDBRemoteCommunication::PacketResult
Greg Claytonc574ede2011-03-10 02:26:48 +0000260GDBRemoteCommunication::GetAck ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261{
Greg Clayton576d8832011-03-22 04:00:09 +0000262 StringExtractorGDBRemote packet;
Greg Clayton3dedae12013-12-06 21:45:27 +0000263 PacketResult result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, GetPacketTimeoutInMicroSeconds ());
264 if (result == PacketResult::Success)
265 {
266 if (packet.GetResponseType() == StringExtractorGDBRemote::ResponseType::eAck)
267 return PacketResult::Success;
268 else
269 return PacketResult::ErrorSendAck;
270 }
271 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272}
273
274bool
Jim Ingham4ceb9282012-06-08 22:50:40 +0000275GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276{
Greg Claytond9896732012-05-31 16:54:51 +0000277 if (IsRunning())
Jim Ingham4ceb9282012-06-08 22:50:40 +0000278 return locker.TryLock (m_sequence_mutex, failure_message);
Greg Claytond9896732012-05-31 16:54:51 +0000279
280 locker.Lock (m_sequence_mutex);
281 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282}
283
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284
Greg Clayton6779606a2011-01-22 23:43:18 +0000285bool
Greg Clayton6779606a2011-01-22 23:43:18 +0000286GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
287{
288 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
289}
290
Greg Clayton3dedae12013-12-06 21:45:27 +0000291GDBRemoteCommunication::PacketResult
Greg Clayton73bf5db2011-06-17 01:22:15 +0000292GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293{
Greg Clayton73bf5db2011-06-17 01:22:15 +0000294 uint8_t buffer[8192];
295 Error error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296
Greg Clayton5160ce52013-03-27 23:08:40 +0000297 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));
Greg Clayton644247c2011-07-07 01:59:51 +0000298
Greg Clayton73bf5db2011-06-17 01:22:15 +0000299 // Check for a packet from our cache first without trying any reading...
300 if (CheckForPacket (NULL, 0, packet))
Greg Clayton3dedae12013-12-06 21:45:27 +0000301 return PacketResult::Success;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000302
Greg Clayton0c51ac32011-07-02 23:21:06 +0000303 bool timed_out = false;
Greg Clayton3dedae12013-12-06 21:45:27 +0000304 bool disconnected = false;
Greg Clayton0c51ac32011-07-02 23:21:06 +0000305 while (IsConnected() && !timed_out)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306 {
Johnny Chen74549c82011-07-19 01:13:00 +0000307 lldb::ConnectionStatus status = eConnectionStatusNoConnection;
Greg Clayton73bf5db2011-06-17 01:22:15 +0000308 size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
Greg Clayton644247c2011-07-07 01:59:51 +0000309
310 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000311 log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
Greg Clayton644247c2011-07-07 01:59:51 +0000312 __PRETTY_FUNCTION__,
313 timeout_usec,
314 Communication::ConnectionStatusAsCString (status),
315 error.AsCString(),
Greg Clayton43e0af02012-09-18 18:04:04 +0000316 (uint64_t)bytes_read);
Greg Clayton644247c2011-07-07 01:59:51 +0000317
Greg Clayton73bf5db2011-06-17 01:22:15 +0000318 if (bytes_read > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000320 if (CheckForPacket (buffer, bytes_read, packet))
Greg Clayton3dedae12013-12-06 21:45:27 +0000321 return PacketResult::Success;
Greg Clayton73bf5db2011-06-17 01:22:15 +0000322 }
323 else
324 {
325 switch (status)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326 {
Greg Clayton197bacf2011-07-02 21:07:54 +0000327 case eConnectionStatusTimedOut:
Greg Claytonf0066ad2014-05-02 00:45:31 +0000328 case eConnectionStatusInterrupted:
Greg Clayton0c51ac32011-07-02 23:21:06 +0000329 timed_out = true;
330 break;
331 case eConnectionStatusSuccess:
332 //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
Greg Clayton73bf5db2011-06-17 01:22:15 +0000333 break;
334
335 case eConnectionStatusEndOfFile:
336 case eConnectionStatusNoConnection:
337 case eConnectionStatusLostConnection:
338 case eConnectionStatusError:
Greg Clayton3dedae12013-12-06 21:45:27 +0000339 disconnected = true;
Greg Clayton73bf5db2011-06-17 01:22:15 +0000340 Disconnect();
341 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 }
343 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 }
Greg Clayton3dedae12013-12-06 21:45:27 +0000345 packet.Clear ();
346 if (disconnected)
347 return PacketResult::ErrorDisconnected;
348 if (timed_out)
349 return PacketResult::ErrorReplyTimeout;
350 else
351 return PacketResult::ErrorReplyFailed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352}
353
Greg Clayton73bf5db2011-06-17 01:22:15 +0000354bool
355GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356{
357 // Put the packet data into the buffer in a thread safe fashion
358 Mutex::Locker locker(m_bytes_mutex);
Greg Clayton197bacf2011-07-02 21:07:54 +0000359
Greg Clayton5160ce52013-03-27 23:08:40 +0000360 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Greg Clayton197bacf2011-07-02 21:07:54 +0000361
Greg Clayton73bf5db2011-06-17 01:22:15 +0000362 if (src && src_len > 0)
Greg Clayton197bacf2011-07-02 21:07:54 +0000363 {
Greg Clayton0c51ac32011-07-02 23:21:06 +0000364 if (log && log->GetVerbose())
Greg Clayton197bacf2011-07-02 21:07:54 +0000365 {
366 StreamString s;
Greg Clayton0c51ac32011-07-02 23:21:06 +0000367 log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s",
368 __FUNCTION__,
369 (uint32_t)src_len,
370 (uint32_t)src_len,
371 src);
Greg Clayton197bacf2011-07-02 21:07:54 +0000372 }
Greg Clayton73bf5db2011-06-17 01:22:15 +0000373 m_bytes.append ((const char *)src, src_len);
Greg Clayton197bacf2011-07-02 21:07:54 +0000374 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375
376 // Parse up the packets into gdb remote packets
Greg Clayton197bacf2011-07-02 21:07:54 +0000377 if (!m_bytes.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378 {
379 // end_idx must be one past the last valid packet byte. Start
380 // it off with an invalid value that is the same as the current
381 // index.
Greg Clayton73bf5db2011-06-17 01:22:15 +0000382 size_t content_start = 0;
383 size_t content_length = 0;
384 size_t total_length = 0;
385 size_t checksum_idx = std::string::npos;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386
387 switch (m_bytes[0])
388 {
389 case '+': // Look for ack
390 case '-': // Look for cancel
391 case '\x03': // ^C to halt target
Greg Clayton73bf5db2011-06-17 01:22:15 +0000392 content_length = total_length = 1; // The command is one byte long...
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000393 break;
394
395 case '$':
396 // Look for a standard gdb packet?
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000398 size_t hash_pos = m_bytes.find('#');
399 if (hash_pos != std::string::npos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000401 if (hash_pos + 2 < m_bytes.size())
402 {
403 checksum_idx = hash_pos + 1;
404 // Skip the dollar sign
405 content_start = 1;
406 // Don't include the # in the content or the $ in the content length
407 content_length = hash_pos - 1;
408
409 total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
410 }
411 else
412 {
413 // Checksum bytes aren't all here yet
414 content_length = std::string::npos;
415 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 }
417 }
418 break;
419
420 default:
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000421 {
Greg Clayton197bacf2011-07-02 21:07:54 +0000422 // We have an unexpected byte and we need to flush all bad
423 // data that is in m_bytes, so we need to find the first
424 // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
425 // or '$' character (start of packet header) or of course,
426 // the end of the data in m_bytes...
427 const size_t bytes_len = m_bytes.size();
428 bool done = false;
429 uint32_t idx;
430 for (idx = 1; !done && idx < bytes_len; ++idx)
431 {
432 switch (m_bytes[idx])
433 {
434 case '+':
435 case '-':
436 case '\x03':
437 case '$':
438 done = true;
439 break;
440
441 default:
442 break;
443 }
444 }
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000445 if (log)
Greg Clayton197bacf2011-07-02 21:07:54 +0000446 log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
447 __FUNCTION__, idx, idx, m_bytes.c_str());
448 m_bytes.erase(0, idx);
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000449 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450 break;
451 }
452
Greg Clayton73bf5db2011-06-17 01:22:15 +0000453 if (content_length == std::string::npos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000455 packet.Clear();
456 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457 }
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000458 else if (total_length > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000460
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461 // We have a valid packet...
Greg Clayton73bf5db2011-06-17 01:22:15 +0000462 assert (content_length <= m_bytes.size());
463 assert (total_length <= m_bytes.size());
464 assert (content_length <= total_length);
Greg Clayton06f09b52014-06-20 20:41:07 +0000465 const size_t content_end = content_start + content_length;
466
Greg Clayton73bf5db2011-06-17 01:22:15 +0000467 bool success = true;
468 std::string &packet_str = packet.GetStringRef();
Greg Claytonc1422c12012-04-09 22:46:21 +0000469
470
471 if (log)
472 {
473 // If logging was just enabled and we have history, then dump out what
474 // we have to the log so we get the historical context. The Dump() call that
475 // logs all of the packet will set a boolean so that we don't dump this more
476 // than once
477 if (!m_history.DidDumpToLog ())
Greg Clayton5160ce52013-03-27 23:08:40 +0000478 m_history.Dump (log);
Greg Claytonc1422c12012-04-09 22:46:21 +0000479
Greg Clayton06f09b52014-06-20 20:41:07 +0000480 bool binary = false;
481 // Only detect binary for packets that start with a '$' and have a '#CC' checksum
482 if (m_bytes[0] == '$' && total_length > 4)
483 {
484 for (size_t i=0; !binary && i<total_length; ++i)
485 {
486 if (isprint(m_bytes[i]) == 0)
487 binary = true;
488 }
489 }
490 if (binary)
491 {
492 StreamString strm;
493 // Packet header...
494 strm.Printf("<%4" PRIu64 "> read packet: %c", (uint64_t)total_length, m_bytes[0]);
495 for (size_t i=content_start; i<content_end; ++i)
496 {
497 // Remove binary escaped bytes when displaying the packet...
498 const char ch = m_bytes[i];
499 if (ch == 0x7d)
500 {
501 // 0x7d is the escape character. The next character is to
502 // be XOR'd with 0x20.
503 const char escapee = m_bytes[++i] ^ 0x20;
504 strm.Printf("%2.2x", escapee);
505 }
506 else
507 {
508 strm.Printf("%2.2x", (uint8_t)ch);
509 }
510 }
511 // Packet footer...
512 strm.Printf("%c%c%c", m_bytes[total_length-3], m_bytes[total_length-2], m_bytes[total_length-1]);
513 log->PutCString(strm.GetString().c_str());
514 }
515 else
516 {
517 log->Printf("<%4" PRIu64 "> read packet: %.*s", (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
518 }
Greg Claytonc1422c12012-04-09 22:46:21 +0000519 }
520
521 m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length);
522
Hafiz Abid Qadeere5fd5e12013-08-28 15:10:37 +0000523 // Clear packet_str in case there is some existing data in it.
524 packet_str.clear();
Hafiz Abid Qadeerda96ef22013-08-28 10:31:52 +0000525 // Copy the packet from m_bytes to packet_str expanding the
526 // run-length encoding in the process.
527 // Reserve enough byte for the most common case (no RLE used)
528 packet_str.reserve(m_bytes.length());
Greg Clayton06f09b52014-06-20 20:41:07 +0000529 for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_end; ++c)
Hafiz Abid Qadeerda96ef22013-08-28 10:31:52 +0000530 {
531 if (*c == '*')
532 {
533 // '*' indicates RLE. Next character will give us the
534 // repeat count and previous character is what is to be
535 // repeated.
536 char char_to_repeat = packet_str.back();
537 // Number of time the previous character is repeated
538 int repeat_count = *++c + 3 - ' ';
539 // We have the char_to_repeat and repeat_count. Now push
540 // it in the packet.
541 for (int i = 0; i < repeat_count; ++i)
542 packet_str.push_back(char_to_repeat);
543 }
Steve Pucci3c5d3332014-02-24 19:07:29 +0000544 else if (*c == 0x7d)
545 {
546 // 0x7d is the escape character. The next character is to
547 // be XOR'd with 0x20.
548 char escapee = *++c ^ 0x20;
549 packet_str.push_back(escapee);
550 }
Hafiz Abid Qadeerda96ef22013-08-28 10:31:52 +0000551 else
552 {
553 packet_str.push_back(*c);
554 }
555 }
556
Greg Clayton73bf5db2011-06-17 01:22:15 +0000557 if (m_bytes[0] == '$')
558 {
559 assert (checksum_idx < m_bytes.size());
560 if (::isxdigit (m_bytes[checksum_idx+0]) ||
561 ::isxdigit (m_bytes[checksum_idx+1]))
562 {
563 if (GetSendAcks ())
564 {
565 const char *packet_checksum_cstr = &m_bytes[checksum_idx];
566 char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
567 char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
568 success = packet_checksum == actual_checksum;
569 if (!success)
570 {
571 if (log)
572 log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
573 (int)(total_length),
574 m_bytes.c_str(),
575 (uint8_t)packet_checksum,
576 (uint8_t)actual_checksum);
577 }
578 // Send the ack or nack if needed
579 if (!success)
580 SendNack();
581 else
582 SendAck();
583 }
Greg Clayton73bf5db2011-06-17 01:22:15 +0000584 }
585 else
586 {
587 success = false;
588 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000589 log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str());
Greg Clayton73bf5db2011-06-17 01:22:15 +0000590 }
591 }
Greg Claytonc1422c12012-04-09 22:46:21 +0000592
Greg Clayton73bf5db2011-06-17 01:22:15 +0000593 m_bytes.erase(0, total_length);
594 packet.SetFilePos(0);
595 return success;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597 }
Greg Clayton73bf5db2011-06-17 01:22:15 +0000598 packet.Clear();
599 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600}
601
Greg Clayton8b82f082011-04-12 05:54:46 +0000602Error
Greg Claytond6299802013-12-06 17:46:35 +0000603GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port)
Greg Clayton00fe87b2013-12-05 22:58:22 +0000604{
605 Error error;
606 if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
607 {
608 error.SetErrorString("listen thread already running");
609 }
610 else
611 {
612 char listen_url[512];
613 if (hostname && hostname[0])
Jean-Daniel Dupas3c6774a2014-02-08 20:29:40 +0000614 snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
Greg Clayton00fe87b2013-12-05 22:58:22 +0000615 else
616 snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
617 m_listen_url = listen_url;
618 SetConnection(new ConnectionFileDescriptor());
619 m_listen_thread = Host::ThreadCreate (listen_url, GDBRemoteCommunication::ListenThread, this, &error);
620 }
621 return error;
622}
623
624bool
625GDBRemoteCommunication::JoinListenThread ()
626{
627 if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
628 {
629 Host::ThreadJoin(m_listen_thread, NULL, NULL);
630 m_listen_thread = LLDB_INVALID_HOST_THREAD;
631 }
632 return true;
633}
634
635lldb::thread_result_t
636GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
637{
638 GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
639 Error error;
640 ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)comm->GetConnection ();
641
642 if (connection)
643 {
644 // Do the listen on another thread so we can continue on...
645 if (connection->Connect(comm->m_listen_url.c_str(), &error) != eConnectionStatusSuccess)
646 comm->SetConnection(NULL);
647 }
648 return NULL;
649}
650
651Error
Greg Claytonfda4fab2014-01-10 22:24:11 +0000652GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
653 uint16_t in_port,
Greg Clayton91a9b2472013-12-04 19:19:12 +0000654 lldb_private::ProcessLaunchInfo &launch_info,
Greg Claytonfda4fab2014-01-10 22:24:11 +0000655 uint16_t &out_port)
Greg Clayton8b82f082011-04-12 05:54:46 +0000656{
Todd Fiala015d8182014-07-22 23:41:36 +0000657 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
658 if (log)
659 log->Printf ("GDBRemoteCommunication::%s(hostname=%s, in_port=%" PRIu16 ", out_port=%" PRIu16, __FUNCTION__, hostname ? hostname : "<empty>", in_port, out_port);
660
Greg Claytonfda4fab2014-01-10 22:24:11 +0000661 out_port = in_port;
Greg Clayton8b82f082011-04-12 05:54:46 +0000662 Error error;
663 // If we locate debugserver, keep that located version around
664 static FileSpec g_debugserver_file_spec;
665
Greg Clayton8b82f082011-04-12 05:54:46 +0000666 char debugserver_path[PATH_MAX];
667 FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
668
669 // Always check to see if we have an environment override for the path
670 // to the debugserver to use and use it if we do.
671 const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
672 if (env_debugserver_path)
Todd Fiala015d8182014-07-22 23:41:36 +0000673 {
Greg Clayton8b82f082011-04-12 05:54:46 +0000674 debugserver_file_spec.SetFile (env_debugserver_path, false);
Todd Fiala015d8182014-07-22 23:41:36 +0000675 if (log)
676 log->Printf ("GDBRemoteCommunication::%s() gdb-remote stub exe path set from environment variable: %s", __FUNCTION__, env_debugserver_path);
677 }
Greg Clayton8b82f082011-04-12 05:54:46 +0000678 else
679 debugserver_file_spec = g_debugserver_file_spec;
680 bool debugserver_exists = debugserver_file_spec.Exists();
681 if (!debugserver_exists)
682 {
683 // The debugserver binary is in the LLDB.framework/Resources
684 // directory.
685 if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
686 {
687 debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
688 debugserver_exists = debugserver_file_spec.Exists();
689 if (debugserver_exists)
690 {
Todd Fiala015d8182014-07-22 23:41:36 +0000691 if (log)
692 log->Printf ("GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
693
Greg Clayton8b82f082011-04-12 05:54:46 +0000694 g_debugserver_file_spec = debugserver_file_spec;
695 }
696 else
697 {
Todd Fiala015d8182014-07-22 23:41:36 +0000698 if (log)
699 log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
700
Greg Clayton8b82f082011-04-12 05:54:46 +0000701 g_debugserver_file_spec.Clear();
702 debugserver_file_spec.Clear();
703 }
704 }
705 }
706
707 if (debugserver_exists)
708 {
709 debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
710
711 Args &debugserver_args = launch_info.GetArguments();
712 debugserver_args.Clear();
713 char arg_cstr[PATH_MAX];
714
715 // Start args with "debugserver /file/path -r --"
716 debugserver_args.AppendArgument(debugserver_path);
Greg Clayton00fe87b2013-12-05 22:58:22 +0000717
718 // If a host and port is supplied then use it
Greg Claytonfda4fab2014-01-10 22:24:11 +0000719 char host_and_port[128];
720 if (hostname)
721 {
722 snprintf (host_and_port, sizeof(host_and_port), "%s:%u", hostname, in_port);
Greg Clayton00fe87b2013-12-05 22:58:22 +0000723 debugserver_args.AppendArgument(host_and_port);
Greg Claytonfda4fab2014-01-10 22:24:11 +0000724 }
725 else
726 {
727 host_and_port[0] = '\0';
728 }
729
Greg Clayton8b82f082011-04-12 05:54:46 +0000730 // use native registers, not the GDB registers
731 debugserver_args.AppendArgument("--native-regs");
732 // make debugserver run in its own session so signals generated by
733 // special terminal key sequences (^C) don't affect debugserver
734 debugserver_args.AppendArgument("--setsid");
Greg Clayton91a9b2472013-12-04 19:19:12 +0000735
Greg Clayton00fe87b2013-12-05 22:58:22 +0000736 char named_pipe_path[PATH_MAX];
Jason Molenda6e205542014-01-25 03:57:13 +0000737 named_pipe_path[0] = '\0';
Greg Clayton00fe87b2013-12-05 22:58:22 +0000738
Greg Claytonfda4fab2014-01-10 22:24:11 +0000739 bool listen = false;
740 if (host_and_port[0])
Greg Clayton91a9b2472013-12-04 19:19:12 +0000741 {
Greg Clayton00fe87b2013-12-05 22:58:22 +0000742 // Create a temporary file to get the stdout/stderr and redirect the
743 // output of the command into this file. We will later read this file
744 // if all goes well and fill the data into "command_output_ptr"
Greg Clayton00fe87b2013-12-05 22:58:22 +0000745
Greg Claytonfda4fab2014-01-10 22:24:11 +0000746 if (in_port == 0)
Greg Clayton00fe87b2013-12-05 22:58:22 +0000747 {
Greg Claytonfda4fab2014-01-10 22:24:11 +0000748 // Binding to port zero, we need to figure out what port it ends up
749 // using using a named pipe...
750 FileSpec tmpdir_file_spec;
751 if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
Greg Clayton00fe87b2013-12-05 22:58:22 +0000752 {
Greg Claytonfda4fab2014-01-10 22:24:11 +0000753 tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX");
754 strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));
755 }
756 else
757 {
758 strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path));
759 }
760
761 if (::mktemp (named_pipe_path))
762 {
Hafiz Abid Qadeer6eff1012014-03-12 10:45:23 +0000763#if defined(_WIN32)
Deepak Panickalb36da432014-01-13 14:55:15 +0000764 if ( false )
765#else
Greg Claytonfda4fab2014-01-10 22:24:11 +0000766 if (::mkfifo(named_pipe_path, 0600) == 0)
Deepak Panickalb36da432014-01-13 14:55:15 +0000767#endif
Greg Claytonfda4fab2014-01-10 22:24:11 +0000768 {
769 debugserver_args.AppendArgument("--named-pipe");
770 debugserver_args.AppendArgument(named_pipe_path);
771 }
Greg Clayton00fe87b2013-12-05 22:58:22 +0000772 }
Greg Clayton91a9b2472013-12-04 19:19:12 +0000773 }
774 else
Greg Claytonfda4fab2014-01-10 22:24:11 +0000775 {
776 listen = true;
777 }
Greg Clayton91a9b2472013-12-04 19:19:12 +0000778 }
779 else
Greg Clayton00fe87b2013-12-05 22:58:22 +0000780 {
Greg Clayton00fe87b2013-12-05 22:58:22 +0000781 // No host and port given, so lets listen on our end and make the debugserver
782 // connect to us..
Greg Clayton16810922014-02-27 19:38:18 +0000783 error = StartListenThread ("127.0.0.1", 0);
Greg Clayton00fe87b2013-12-05 22:58:22 +0000784 if (error.Fail())
785 return error;
Greg Clayton8b82f082011-04-12 05:54:46 +0000786
Greg Clayton00fe87b2013-12-05 22:58:22 +0000787 ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
Greg Clayton16810922014-02-27 19:38:18 +0000788 // Wait for 10 seconds to resolve the bound port
789 out_port = connection->GetBoundPort(10);
790 if (out_port > 0)
791 {
792 char port_cstr[32];
793 snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", out_port);
794 // Send the host and port down that debugserver and specify an option
795 // so that it connects back to the port we are listening to in this process
796 debugserver_args.AppendArgument("--reverse-connect");
797 debugserver_args.AppendArgument(port_cstr);
798 }
799 else
800 {
801 error.SetErrorString ("failed to bind to port 0 on 127.0.0.1");
802 return error;
803 }
Greg Clayton00fe87b2013-12-05 22:58:22 +0000804 }
805
806
Greg Clayton8b82f082011-04-12 05:54:46 +0000807 const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
808 if (env_debugserver_log_file)
809 {
810 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
811 debugserver_args.AppendArgument(arg_cstr);
812 }
813
814 const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
815 if (env_debugserver_log_flags)
816 {
817 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
818 debugserver_args.AppendArgument(arg_cstr);
819 }
Greg Clayton8b82f082011-04-12 05:54:46 +0000820
821 // Close STDIN, STDOUT and STDERR. We might need to redirect them
822 // to "/dev/null" if we run into any problems.
Greg Clayton91a9b2472013-12-04 19:19:12 +0000823 launch_info.AppendCloseFileAction (STDIN_FILENO);
824 launch_info.AppendCloseFileAction (STDOUT_FILENO);
825 launch_info.AppendCloseFileAction (STDERR_FILENO);
Greg Clayton8b82f082011-04-12 05:54:46 +0000826
827 error = Host::LaunchProcess(launch_info);
Greg Clayton91a9b2472013-12-04 19:19:12 +0000828
Greg Clayton3121fde2014-02-28 20:47:08 +0000829 if (error.Success() && launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
Greg Clayton91a9b2472013-12-04 19:19:12 +0000830 {
Greg Clayton3121fde2014-02-28 20:47:08 +0000831 if (named_pipe_path[0])
Greg Clayton91a9b2472013-12-04 19:19:12 +0000832 {
Greg Clayton3121fde2014-02-28 20:47:08 +0000833 File name_pipe_file;
834 error = name_pipe_file.Open(named_pipe_path, File::eOpenOptionRead);
835 if (error.Success())
836 {
837 char port_cstr[256];
838 port_cstr[0] = '\0';
839 size_t num_bytes = sizeof(port_cstr);
840 error = name_pipe_file.Read(port_cstr, num_bytes);
841 assert (error.Success());
842 assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
843 out_port = Args::StringToUInt32(port_cstr, 0);
844 name_pipe_file.Close();
845 }
846 Host::Unlink(named_pipe_path);
Greg Clayton91a9b2472013-12-04 19:19:12 +0000847 }
Greg Clayton3121fde2014-02-28 20:47:08 +0000848 else if (listen)
849 {
850
851 }
852 else
853 {
854 // Make sure we actually connect with the debugserver...
855 JoinListenThread();
856 }
Greg Clayton00fe87b2013-12-05 22:58:22 +0000857 }
Greg Clayton8b82f082011-04-12 05:54:46 +0000858 }
859 else
860 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000861 error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME );
Greg Clayton8b82f082011-04-12 05:54:46 +0000862 }
863 return error;
864}
865
Greg Claytonc1422c12012-04-09 22:46:21 +0000866void
Greg Claytond451c1a2012-04-13 21:24:18 +0000867GDBRemoteCommunication::DumpHistory(Stream &strm)
Greg Claytonc1422c12012-04-09 22:46:21 +0000868{
Greg Claytond451c1a2012-04-13 21:24:18 +0000869 m_history.Dump (strm);
Greg Claytonc1422c12012-04-09 22:46:21 +0000870}