blob: f742bfce34b82f9ec6de1869b4d9a32e2e311575 [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>
16
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017// C++ Includes
18// Other libraries and framework includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/Log.h"
Greg Claytonc1422c12012-04-09 22:46:21 +000020#include "lldb/Core/StreamFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/StreamString.h"
Greg Clayton8b82f082011-04-12 05:54:46 +000022#include "lldb/Host/FileSpec.h"
23#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Host/TimeValue.h"
Greg Clayton8b82f082011-04-12 05:54:46 +000025#include "lldb/Target/Process.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
27// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "ProcessGDBRemoteLog.h"
29
Greg Clayton8b82f082011-04-12 05:54:46 +000030#define DEBUGSERVER_BASENAME "debugserver"
31
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032using namespace lldb;
33using namespace lldb_private;
34
Greg Claytonc1422c12012-04-09 22:46:21 +000035GDBRemoteCommunication::History::History (uint32_t size) :
36 m_packets(),
37 m_curr_idx (0),
38 m_total_packet_count (0),
39 m_dumped_to_log (false)
40{
41 m_packets.resize(size);
42}
43
44GDBRemoteCommunication::History::~History ()
45{
46}
47
48void
Greg Claytond451c1a2012-04-13 21:24:18 +000049GDBRemoteCommunication::History::AddPacket (char packet_char,
50 PacketType type,
51 uint32_t bytes_transmitted)
52{
53 const size_t size = m_packets.size();
54 if (size > 0)
55 {
56 const uint32_t idx = GetNextIndex();
57 m_packets[idx].packet.assign (1, packet_char);
58 m_packets[idx].type = type;
59 m_packets[idx].bytes_transmitted = bytes_transmitted;
60 m_packets[idx].packet_idx = m_total_packet_count;
61 m_packets[idx].tid = Host::GetCurrentThreadID();
62 }
63}
64
65void
66GDBRemoteCommunication::History::AddPacket (const std::string &src,
67 uint32_t src_len,
68 PacketType type,
69 uint32_t bytes_transmitted)
70{
71 const size_t size = m_packets.size();
72 if (size > 0)
73 {
74 const uint32_t idx = GetNextIndex();
75 m_packets[idx].packet.assign (src, 0, src_len);
76 m_packets[idx].type = type;
77 m_packets[idx].bytes_transmitted = bytes_transmitted;
78 m_packets[idx].packet_idx = m_total_packet_count;
79 m_packets[idx].tid = Host::GetCurrentThreadID();
80 }
81}
82
83void
Greg Claytonc1422c12012-04-09 22:46:21 +000084GDBRemoteCommunication::History::Dump (lldb_private::Stream &strm) const
85{
86 const uint32_t size = GetNumPacketsInHistory ();
87 const uint32_t first_idx = GetFirstSavedPacketIndex ();
88 const uint32_t stop_idx = m_curr_idx + size;
89 for (uint32_t i = first_idx; i < stop_idx; ++i)
90 {
91 const uint32_t idx = NormalizeIndex (i);
92 const Entry &entry = m_packets[idx];
93 if (entry.type == ePacketTypeInvalid || entry.packet.empty())
94 break;
Daniel Malead01b2952012-11-29 21:49:15 +000095 strm.Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
Greg Claytonc1422c12012-04-09 22:46:21 +000096 entry.packet_idx,
Greg Claytond451c1a2012-04-13 21:24:18 +000097 entry.tid,
Greg Claytonc1422c12012-04-09 22:46:21 +000098 entry.bytes_transmitted,
99 (entry.type == ePacketTypeSend) ? "send" : "read",
100 entry.packet.c_str());
101 }
102}
103
104void
105GDBRemoteCommunication::History::Dump (lldb_private::Log *log) const
106{
107 if (log && !m_dumped_to_log)
108 {
109 m_dumped_to_log = true;
110 const uint32_t size = GetNumPacketsInHistory ();
111 const uint32_t first_idx = GetFirstSavedPacketIndex ();
112 const uint32_t stop_idx = m_curr_idx + size;
113 for (uint32_t i = first_idx; i < stop_idx; ++i)
114 {
115 const uint32_t idx = NormalizeIndex (i);
116 const Entry &entry = m_packets[idx];
117 if (entry.type == ePacketTypeInvalid || entry.packet.empty())
118 break;
Daniel Malead01b2952012-11-29 21:49:15 +0000119 log->Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
Greg Claytonc1422c12012-04-09 22:46:21 +0000120 entry.packet_idx,
Greg Claytond451c1a2012-04-13 21:24:18 +0000121 entry.tid,
Greg Claytonc1422c12012-04-09 22:46:21 +0000122 entry.bytes_transmitted,
123 (entry.type == ePacketTypeSend) ? "send" : "read",
124 entry.packet.c_str());
125 }
126 }
127}
128
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129//----------------------------------------------------------------------
130// GDBRemoteCommunication constructor
131//----------------------------------------------------------------------
Greg Clayton8b82f082011-04-12 05:54:46 +0000132GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
133 const char *listener_name,
134 bool is_platform) :
Greg Clayton576d8832011-03-22 04:00:09 +0000135 Communication(comm_name),
Daniel Maleae0f8f572013-08-26 23:57:52 +0000136#ifdef LLDB_CONFIGURATION_DEBUG
137 m_packet_timeout (1000),
138#else
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000139 m_packet_timeout (1),
Daniel Maleae0f8f572013-08-26 23:57:52 +0000140#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141 m_sequence_mutex (Mutex::eMutexTypeRecursive),
Greg Clayton4dc72282011-01-20 07:53:45 +0000142 m_public_is_running (false),
Greg Clayton1cb64962011-03-24 04:28:38 +0000143 m_private_is_running (false),
Greg Claytonc1422c12012-04-09 22:46:21 +0000144 m_history (512),
Greg Clayton8b82f082011-04-12 05:54:46 +0000145 m_send_acks (true),
146 m_is_platform (is_platform)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148}
149
150//----------------------------------------------------------------------
151// Destructor
152//----------------------------------------------------------------------
153GDBRemoteCommunication::~GDBRemoteCommunication()
154{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155 if (IsConnected())
156 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157 Disconnect();
158 }
159}
160
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161char
162GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
163{
164 int checksum = 0;
165
Ed Mastea6b4c772013-08-20 14:12:58 +0000166 for (size_t i = 0; i < payload_length; ++i)
167 checksum += payload[i];
168
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169 return checksum & 255;
170}
171
172size_t
Greg Clayton6ed95942011-01-22 07:12:45 +0000173GDBRemoteCommunication::SendAck ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174{
Greg Clayton5160ce52013-03-27 23:08:40 +0000175 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176 ConnectionStatus status = eConnectionStatusSuccess;
Greg Claytonc1422c12012-04-09 22:46:21 +0000177 char ch = '+';
178 const size_t bytes_written = Write (&ch, 1, status, NULL);
179 if (log)
Deepak Panickald66b50c2013-10-22 12:27:43 +0000180 log->Printf ("<" PRIx64 "> send packet: %c", (uint64_t)bytes_written, ch);
Greg Claytonc1422c12012-04-09 22:46:21 +0000181 m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
182 return bytes_written;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183}
184
185size_t
Greg Clayton6ed95942011-01-22 07:12:45 +0000186GDBRemoteCommunication::SendNack ()
187{
Greg Clayton5160ce52013-03-27 23:08:40 +0000188 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Greg Clayton6ed95942011-01-22 07:12:45 +0000189 ConnectionStatus status = eConnectionStatusSuccess;
Greg Claytonc1422c12012-04-09 22:46:21 +0000190 char ch = '-';
191 const size_t bytes_written = Write (&ch, 1, status, NULL);
192 if (log)
Deepak Panickald66b50c2013-10-22 12:27:43 +0000193 log->Printf("<" PRIx64 "> send packet: %c", (uint64_t)bytes_written, ch);
Greg Claytonc1422c12012-04-09 22:46:21 +0000194 m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
195 return bytes_written;
Greg Clayton32e0a752011-03-30 18:16:51 +0000196}
197
198size_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
200{
201 Mutex::Locker locker(m_sequence_mutex);
202 return SendPacketNoLock (payload, payload_length);
203}
204
205size_t
206GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
207{
208 if (IsConnected())
209 {
210 StreamString packet(0, 4, eByteOrderBig);
211
212 packet.PutChar('$');
213 packet.Write (payload, payload_length);
214 packet.PutChar('#');
215 packet.PutHex8(CalculcateChecksum (payload, payload_length));
216
Greg Clayton5160ce52013-03-27 23:08:40 +0000217 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218 ConnectionStatus status = eConnectionStatusSuccess;
219 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
Greg Claytonc1422c12012-04-09 22:46:21 +0000220 if (log)
221 {
222 // If logging was just enabled and we have history, then dump out what
223 // we have to the log so we get the historical context. The Dump() call that
224 // logs all of the packet will set a boolean so that we don't dump this more
225 // than once
226 if (!m_history.DidDumpToLog ())
Greg Clayton5160ce52013-03-27 23:08:40 +0000227 m_history.Dump (log);
Greg Claytonc1422c12012-04-09 22:46:21 +0000228
Deepak Panickald66b50c2013-10-22 12:27:43 +0000229 log->Printf("<" PRIx64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet.GetSize(), packet.GetData());
Greg Claytonc1422c12012-04-09 22:46:21 +0000230 }
231
232 m_history.AddPacket (packet.GetString(), packet.GetSize(), History::ePacketTypeSend, bytes_written);
233
234
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235 if (bytes_written == packet.GetSize())
236 {
Greg Clayton71fc2a32011-02-12 06:28:37 +0000237 if (GetSendAcks ())
Greg Claytonc982c762010-07-09 20:39:50 +0000238 {
Greg Claytonc574ede2011-03-10 02:26:48 +0000239 if (GetAck () != '+')
Greg Clayton1cb64962011-03-24 04:28:38 +0000240 {
Johnny Chen561e1902012-06-02 00:22:07 +0000241 if (log)
242 log->Printf("get ack failed...");
Greg Claytonc982c762010-07-09 20:39:50 +0000243 return 0;
Greg Clayton1cb64962011-03-24 04:28:38 +0000244 }
Greg Claytonc982c762010-07-09 20:39:50 +0000245 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246 }
Johnny Chend0c40dd2010-09-14 22:10:43 +0000247 else
248 {
Greg Clayton6d093452011-02-05 02:25:06 +0000249 if (log)
Greg Clayton5fe15d22011-05-20 03:15:54 +0000250 log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData());
Johnny Chend0c40dd2010-09-14 22:10:43 +0000251 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252 return bytes_written;
Greg Claytonf5e56de2010-09-14 23:36:40 +0000253 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000254 return 0;
255}
256
257char
Greg Claytonc574ede2011-03-10 02:26:48 +0000258GDBRemoteCommunication::GetAck ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259{
Greg Clayton576d8832011-03-22 04:00:09 +0000260 StringExtractorGDBRemote packet;
Greg Clayton37a0a242012-04-11 00:24:49 +0000261 if (WaitForPacketWithTimeoutMicroSecondsNoLock (packet, GetPacketTimeoutInMicroSeconds ()) == 1)
Greg Clayton576d8832011-03-22 04:00:09 +0000262 return packet.GetChar();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263 return 0;
264}
265
266bool
Jim Ingham4ceb9282012-06-08 22:50:40 +0000267GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268{
Greg Claytond9896732012-05-31 16:54:51 +0000269 if (IsRunning())
Jim Ingham4ceb9282012-06-08 22:50:40 +0000270 return locker.TryLock (m_sequence_mutex, failure_message);
Greg Claytond9896732012-05-31 16:54:51 +0000271
272 locker.Lock (m_sequence_mutex);
273 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274}
275
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276
Greg Clayton6779606a2011-01-22 23:43:18 +0000277bool
Greg Clayton6779606a2011-01-22 23:43:18 +0000278GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
279{
280 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
281}
282
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283size_t
Greg Clayton73bf5db2011-06-17 01:22:15 +0000284GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000285{
Greg Clayton73bf5db2011-06-17 01:22:15 +0000286 uint8_t buffer[8192];
287 Error error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288
Greg Clayton5160ce52013-03-27 23:08:40 +0000289 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));
Greg Clayton644247c2011-07-07 01:59:51 +0000290
Greg Clayton73bf5db2011-06-17 01:22:15 +0000291 // Check for a packet from our cache first without trying any reading...
292 if (CheckForPacket (NULL, 0, packet))
293 return packet.GetStringRef().size();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294
Greg Clayton0c51ac32011-07-02 23:21:06 +0000295 bool timed_out = false;
296 while (IsConnected() && !timed_out)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297 {
Johnny Chen74549c82011-07-19 01:13:00 +0000298 lldb::ConnectionStatus status = eConnectionStatusNoConnection;
Greg Clayton73bf5db2011-06-17 01:22:15 +0000299 size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
Greg Clayton644247c2011-07-07 01:59:51 +0000300
301 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000302 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 +0000303 __PRETTY_FUNCTION__,
304 timeout_usec,
305 Communication::ConnectionStatusAsCString (status),
306 error.AsCString(),
Greg Clayton43e0af02012-09-18 18:04:04 +0000307 (uint64_t)bytes_read);
Greg Clayton644247c2011-07-07 01:59:51 +0000308
Greg Clayton73bf5db2011-06-17 01:22:15 +0000309 if (bytes_read > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000311 if (CheckForPacket (buffer, bytes_read, packet))
312 return packet.GetStringRef().size();
313 }
314 else
315 {
316 switch (status)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 {
Greg Clayton197bacf2011-07-02 21:07:54 +0000318 case eConnectionStatusTimedOut:
Greg Clayton0c51ac32011-07-02 23:21:06 +0000319 timed_out = true;
320 break;
321 case eConnectionStatusSuccess:
322 //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
Greg Clayton73bf5db2011-06-17 01:22:15 +0000323 break;
324
325 case eConnectionStatusEndOfFile:
326 case eConnectionStatusNoConnection:
327 case eConnectionStatusLostConnection:
328 case eConnectionStatusError:
329 Disconnect();
330 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 }
332 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 }
Greg Clayton73bf5db2011-06-17 01:22:15 +0000334 packet.Clear ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335 return 0;
336}
337
Greg Clayton73bf5db2011-06-17 01:22:15 +0000338bool
339GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340{
341 // Put the packet data into the buffer in a thread safe fashion
342 Mutex::Locker locker(m_bytes_mutex);
Greg Clayton197bacf2011-07-02 21:07:54 +0000343
Greg Clayton5160ce52013-03-27 23:08:40 +0000344 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
Greg Clayton197bacf2011-07-02 21:07:54 +0000345
Greg Clayton73bf5db2011-06-17 01:22:15 +0000346 if (src && src_len > 0)
Greg Clayton197bacf2011-07-02 21:07:54 +0000347 {
Greg Clayton0c51ac32011-07-02 23:21:06 +0000348 if (log && log->GetVerbose())
Greg Clayton197bacf2011-07-02 21:07:54 +0000349 {
350 StreamString s;
Greg Clayton0c51ac32011-07-02 23:21:06 +0000351 log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s",
352 __FUNCTION__,
353 (uint32_t)src_len,
354 (uint32_t)src_len,
355 src);
Greg Clayton197bacf2011-07-02 21:07:54 +0000356 }
Greg Clayton73bf5db2011-06-17 01:22:15 +0000357 m_bytes.append ((const char *)src, src_len);
Greg Clayton197bacf2011-07-02 21:07:54 +0000358 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359
360 // Parse up the packets into gdb remote packets
Greg Clayton197bacf2011-07-02 21:07:54 +0000361 if (!m_bytes.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362 {
363 // end_idx must be one past the last valid packet byte. Start
364 // it off with an invalid value that is the same as the current
365 // index.
Greg Clayton73bf5db2011-06-17 01:22:15 +0000366 size_t content_start = 0;
367 size_t content_length = 0;
368 size_t total_length = 0;
369 size_t checksum_idx = std::string::npos;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370
371 switch (m_bytes[0])
372 {
373 case '+': // Look for ack
374 case '-': // Look for cancel
375 case '\x03': // ^C to halt target
Greg Clayton73bf5db2011-06-17 01:22:15 +0000376 content_length = total_length = 1; // The command is one byte long...
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377 break;
378
379 case '$':
380 // Look for a standard gdb packet?
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000382 size_t hash_pos = m_bytes.find('#');
383 if (hash_pos != std::string::npos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000385 if (hash_pos + 2 < m_bytes.size())
386 {
387 checksum_idx = hash_pos + 1;
388 // Skip the dollar sign
389 content_start = 1;
390 // Don't include the # in the content or the $ in the content length
391 content_length = hash_pos - 1;
392
393 total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
394 }
395 else
396 {
397 // Checksum bytes aren't all here yet
398 content_length = std::string::npos;
399 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400 }
401 }
402 break;
403
404 default:
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000405 {
Greg Clayton197bacf2011-07-02 21:07:54 +0000406 // We have an unexpected byte and we need to flush all bad
407 // data that is in m_bytes, so we need to find the first
408 // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
409 // or '$' character (start of packet header) or of course,
410 // the end of the data in m_bytes...
411 const size_t bytes_len = m_bytes.size();
412 bool done = false;
413 uint32_t idx;
414 for (idx = 1; !done && idx < bytes_len; ++idx)
415 {
416 switch (m_bytes[idx])
417 {
418 case '+':
419 case '-':
420 case '\x03':
421 case '$':
422 done = true;
423 break;
424
425 default:
426 break;
427 }
428 }
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000429 if (log)
Greg Clayton197bacf2011-07-02 21:07:54 +0000430 log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
431 __FUNCTION__, idx, idx, m_bytes.c_str());
432 m_bytes.erase(0, idx);
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000433 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000434 break;
435 }
436
Greg Clayton73bf5db2011-06-17 01:22:15 +0000437 if (content_length == std::string::npos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000439 packet.Clear();
440 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441 }
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000442 else if (total_length > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000444
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445 // We have a valid packet...
Greg Clayton73bf5db2011-06-17 01:22:15 +0000446 assert (content_length <= m_bytes.size());
447 assert (total_length <= m_bytes.size());
448 assert (content_length <= total_length);
449
450 bool success = true;
451 std::string &packet_str = packet.GetStringRef();
Greg Claytonc1422c12012-04-09 22:46:21 +0000452
453
454 if (log)
455 {
456 // If logging was just enabled and we have history, then dump out what
457 // we have to the log so we get the historical context. The Dump() call that
458 // logs all of the packet will set a boolean so that we don't dump this more
459 // than once
460 if (!m_history.DidDumpToLog ())
Greg Clayton5160ce52013-03-27 23:08:40 +0000461 m_history.Dump (log);
Greg Claytonc1422c12012-04-09 22:46:21 +0000462
Deepak Panickald66b50c2013-10-22 12:27:43 +0000463 log->Printf("<" PRIx64 "> read packet: %.*s", (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
Greg Claytonc1422c12012-04-09 22:46:21 +0000464 }
465
466 m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length);
467
Hafiz Abid Qadeere5fd5e12013-08-28 15:10:37 +0000468 // Clear packet_str in case there is some existing data in it.
469 packet_str.clear();
Hafiz Abid Qadeerda96ef22013-08-28 10:31:52 +0000470 // Copy the packet from m_bytes to packet_str expanding the
471 // run-length encoding in the process.
472 // Reserve enough byte for the most common case (no RLE used)
473 packet_str.reserve(m_bytes.length());
474 for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_start + content_length; ++c)
475 {
476 if (*c == '*')
477 {
478 // '*' indicates RLE. Next character will give us the
479 // repeat count and previous character is what is to be
480 // repeated.
481 char char_to_repeat = packet_str.back();
482 // Number of time the previous character is repeated
483 int repeat_count = *++c + 3 - ' ';
484 // We have the char_to_repeat and repeat_count. Now push
485 // it in the packet.
486 for (int i = 0; i < repeat_count; ++i)
487 packet_str.push_back(char_to_repeat);
488 }
489 else
490 {
491 packet_str.push_back(*c);
492 }
493 }
494
Greg Clayton73bf5db2011-06-17 01:22:15 +0000495 if (m_bytes[0] == '$')
496 {
497 assert (checksum_idx < m_bytes.size());
498 if (::isxdigit (m_bytes[checksum_idx+0]) ||
499 ::isxdigit (m_bytes[checksum_idx+1]))
500 {
501 if (GetSendAcks ())
502 {
503 const char *packet_checksum_cstr = &m_bytes[checksum_idx];
504 char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
505 char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
506 success = packet_checksum == actual_checksum;
507 if (!success)
508 {
509 if (log)
510 log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
511 (int)(total_length),
512 m_bytes.c_str(),
513 (uint8_t)packet_checksum,
514 (uint8_t)actual_checksum);
515 }
516 // Send the ack or nack if needed
517 if (!success)
518 SendNack();
519 else
520 SendAck();
521 }
Greg Clayton73bf5db2011-06-17 01:22:15 +0000522 }
523 else
524 {
525 success = false;
526 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000527 log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str());
Greg Clayton73bf5db2011-06-17 01:22:15 +0000528 }
529 }
Greg Claytonc1422c12012-04-09 22:46:21 +0000530
Greg Clayton73bf5db2011-06-17 01:22:15 +0000531 m_bytes.erase(0, total_length);
532 packet.SetFilePos(0);
533 return success;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000535 }
Greg Clayton73bf5db2011-06-17 01:22:15 +0000536 packet.Clear();
537 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538}
539
Greg Clayton8b82f082011-04-12 05:54:46 +0000540Error
541GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
542 const char *unix_socket_name, // For handshaking
543 lldb_private::ProcessLaunchInfo &launch_info)
544{
545 Error error;
546 // If we locate debugserver, keep that located version around
547 static FileSpec g_debugserver_file_spec;
548
549 // This function will fill in the launch information for the debugserver
550 // instance that gets launched.
551 launch_info.Clear();
552
553 char debugserver_path[PATH_MAX];
554 FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
555
556 // Always check to see if we have an environment override for the path
557 // to the debugserver to use and use it if we do.
558 const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
559 if (env_debugserver_path)
560 debugserver_file_spec.SetFile (env_debugserver_path, false);
561 else
562 debugserver_file_spec = g_debugserver_file_spec;
563 bool debugserver_exists = debugserver_file_spec.Exists();
564 if (!debugserver_exists)
565 {
566 // The debugserver binary is in the LLDB.framework/Resources
567 // directory.
568 if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
569 {
570 debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
571 debugserver_exists = debugserver_file_spec.Exists();
572 if (debugserver_exists)
573 {
574 g_debugserver_file_spec = debugserver_file_spec;
575 }
576 else
577 {
578 g_debugserver_file_spec.Clear();
579 debugserver_file_spec.Clear();
580 }
581 }
582 }
583
584 if (debugserver_exists)
585 {
586 debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
587
588 Args &debugserver_args = launch_info.GetArguments();
589 debugserver_args.Clear();
590 char arg_cstr[PATH_MAX];
591
592 // Start args with "debugserver /file/path -r --"
593 debugserver_args.AppendArgument(debugserver_path);
594 debugserver_args.AppendArgument(debugserver_url);
595 // use native registers, not the GDB registers
596 debugserver_args.AppendArgument("--native-regs");
597 // make debugserver run in its own session so signals generated by
598 // special terminal key sequences (^C) don't affect debugserver
599 debugserver_args.AppendArgument("--setsid");
600
601 if (unix_socket_name && unix_socket_name[0])
602 {
603 debugserver_args.AppendArgument("--unix-socket");
604 debugserver_args.AppendArgument(unix_socket_name);
605 }
606
607 const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
608 if (env_debugserver_log_file)
609 {
610 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
611 debugserver_args.AppendArgument(arg_cstr);
612 }
613
614 const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
615 if (env_debugserver_log_flags)
616 {
617 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
618 debugserver_args.AppendArgument(arg_cstr);
619 }
620 // debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
621 // debugserver_args.AppendArgument("--log-flags=0x802e0e");
622
623 // We currently send down all arguments, attach pids, or attach
624 // process names in dedicated GDB server packets, so we don't need
625 // to pass them as arguments. This is currently because of all the
626 // things we need to setup prior to launching: the environment,
627 // current working dir, file actions, etc.
628#if 0
629 // Now append the program arguments
630 if (inferior_argv)
631 {
632 // Terminate the debugserver args so we can now append the inferior args
633 debugserver_args.AppendArgument("--");
634
635 for (int i = 0; inferior_argv[i] != NULL; ++i)
636 debugserver_args.AppendArgument (inferior_argv[i]);
637 }
638 else if (attach_pid != LLDB_INVALID_PROCESS_ID)
639 {
640 ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
641 debugserver_args.AppendArgument (arg_cstr);
642 }
643 else if (attach_name && attach_name[0])
644 {
645 if (wait_for_launch)
646 debugserver_args.AppendArgument ("--waitfor");
647 else
648 debugserver_args.AppendArgument ("--attach");
649 debugserver_args.AppendArgument (attach_name);
650 }
651#endif
652
653 // Close STDIN, STDOUT and STDERR. We might need to redirect them
654 // to "/dev/null" if we run into any problems.
655// launch_info.AppendCloseFileAction (STDIN_FILENO);
656// launch_info.AppendCloseFileAction (STDOUT_FILENO);
657// launch_info.AppendCloseFileAction (STDERR_FILENO);
658
659 error = Host::LaunchProcess(launch_info);
660 }
661 else
662 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000663 error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME );
Greg Clayton8b82f082011-04-12 05:54:46 +0000664 }
665 return error;
666}
667
Greg Claytonc1422c12012-04-09 22:46:21 +0000668void
Greg Claytond451c1a2012-04-13 21:24:18 +0000669GDBRemoteCommunication::DumpHistory(Stream &strm)
Greg Claytonc1422c12012-04-09 22:46:21 +0000670{
Greg Claytond451c1a2012-04-13 21:24:18 +0000671 m_history.Dump (strm);
Greg Claytonc1422c12012-04-09 22:46:21 +0000672}