blob: 46bd9ca806919f0fa292bcf4c4a7125fa042838b [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)
180 log->Printf ("<%4zu> send packet: %c", bytes_written, ch);
181 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)
193 log->Printf ("<%4zu> send packet: %c", bytes_written, ch);
194 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
229 log->Printf ("<%4zu> send packet: %.*s", bytes_written, (int)packet.GetSize(), packet.GetData());
230 }
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
463 log->Printf ("<%4zu> read packet: %.*s", total_length, (int)(total_length), m_bytes.c_str());
464 }
465
466 m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length);
467
Greg Clayton73bf5db2011-06-17 01:22:15 +0000468 packet_str.assign (m_bytes, content_start, content_length);
Greg Claytonc1422c12012-04-09 22:46:21 +0000469
Greg Clayton73bf5db2011-06-17 01:22:15 +0000470 if (m_bytes[0] == '$')
471 {
472 assert (checksum_idx < m_bytes.size());
473 if (::isxdigit (m_bytes[checksum_idx+0]) ||
474 ::isxdigit (m_bytes[checksum_idx+1]))
475 {
476 if (GetSendAcks ())
477 {
478 const char *packet_checksum_cstr = &m_bytes[checksum_idx];
479 char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
480 char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
481 success = packet_checksum == actual_checksum;
482 if (!success)
483 {
484 if (log)
485 log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
486 (int)(total_length),
487 m_bytes.c_str(),
488 (uint8_t)packet_checksum,
489 (uint8_t)actual_checksum);
490 }
491 // Send the ack or nack if needed
492 if (!success)
493 SendNack();
494 else
495 SendAck();
496 }
Greg Clayton73bf5db2011-06-17 01:22:15 +0000497 }
498 else
499 {
500 success = false;
501 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000502 log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str());
Greg Clayton73bf5db2011-06-17 01:22:15 +0000503 }
504 }
Greg Claytonc1422c12012-04-09 22:46:21 +0000505
Greg Clayton73bf5db2011-06-17 01:22:15 +0000506 m_bytes.erase(0, total_length);
507 packet.SetFilePos(0);
508 return success;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000509 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510 }
Greg Clayton73bf5db2011-06-17 01:22:15 +0000511 packet.Clear();
512 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000513}
514
Greg Clayton8b82f082011-04-12 05:54:46 +0000515Error
516GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
517 const char *unix_socket_name, // For handshaking
518 lldb_private::ProcessLaunchInfo &launch_info)
519{
520 Error error;
521 // If we locate debugserver, keep that located version around
522 static FileSpec g_debugserver_file_spec;
523
524 // This function will fill in the launch information for the debugserver
525 // instance that gets launched.
526 launch_info.Clear();
527
528 char debugserver_path[PATH_MAX];
529 FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
530
531 // Always check to see if we have an environment override for the path
532 // to the debugserver to use and use it if we do.
533 const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
534 if (env_debugserver_path)
535 debugserver_file_spec.SetFile (env_debugserver_path, false);
536 else
537 debugserver_file_spec = g_debugserver_file_spec;
538 bool debugserver_exists = debugserver_file_spec.Exists();
539 if (!debugserver_exists)
540 {
541 // The debugserver binary is in the LLDB.framework/Resources
542 // directory.
543 if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
544 {
545 debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
546 debugserver_exists = debugserver_file_spec.Exists();
547 if (debugserver_exists)
548 {
549 g_debugserver_file_spec = debugserver_file_spec;
550 }
551 else
552 {
553 g_debugserver_file_spec.Clear();
554 debugserver_file_spec.Clear();
555 }
556 }
557 }
558
559 if (debugserver_exists)
560 {
561 debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
562
563 Args &debugserver_args = launch_info.GetArguments();
564 debugserver_args.Clear();
565 char arg_cstr[PATH_MAX];
566
567 // Start args with "debugserver /file/path -r --"
568 debugserver_args.AppendArgument(debugserver_path);
569 debugserver_args.AppendArgument(debugserver_url);
570 // use native registers, not the GDB registers
571 debugserver_args.AppendArgument("--native-regs");
572 // make debugserver run in its own session so signals generated by
573 // special terminal key sequences (^C) don't affect debugserver
574 debugserver_args.AppendArgument("--setsid");
575
576 if (unix_socket_name && unix_socket_name[0])
577 {
578 debugserver_args.AppendArgument("--unix-socket");
579 debugserver_args.AppendArgument(unix_socket_name);
580 }
581
582 const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
583 if (env_debugserver_log_file)
584 {
585 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
586 debugserver_args.AppendArgument(arg_cstr);
587 }
588
589 const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
590 if (env_debugserver_log_flags)
591 {
592 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
593 debugserver_args.AppendArgument(arg_cstr);
594 }
595 // debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
596 // debugserver_args.AppendArgument("--log-flags=0x802e0e");
597
598 // We currently send down all arguments, attach pids, or attach
599 // process names in dedicated GDB server packets, so we don't need
600 // to pass them as arguments. This is currently because of all the
601 // things we need to setup prior to launching: the environment,
602 // current working dir, file actions, etc.
603#if 0
604 // Now append the program arguments
605 if (inferior_argv)
606 {
607 // Terminate the debugserver args so we can now append the inferior args
608 debugserver_args.AppendArgument("--");
609
610 for (int i = 0; inferior_argv[i] != NULL; ++i)
611 debugserver_args.AppendArgument (inferior_argv[i]);
612 }
613 else if (attach_pid != LLDB_INVALID_PROCESS_ID)
614 {
615 ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
616 debugserver_args.AppendArgument (arg_cstr);
617 }
618 else if (attach_name && attach_name[0])
619 {
620 if (wait_for_launch)
621 debugserver_args.AppendArgument ("--waitfor");
622 else
623 debugserver_args.AppendArgument ("--attach");
624 debugserver_args.AppendArgument (attach_name);
625 }
626#endif
627
628 // Close STDIN, STDOUT and STDERR. We might need to redirect them
629 // to "/dev/null" if we run into any problems.
630// launch_info.AppendCloseFileAction (STDIN_FILENO);
631// launch_info.AppendCloseFileAction (STDOUT_FILENO);
632// launch_info.AppendCloseFileAction (STDERR_FILENO);
633
634 error = Host::LaunchProcess(launch_info);
635 }
636 else
637 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000638 error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME );
Greg Clayton8b82f082011-04-12 05:54:46 +0000639 }
640 return error;
641}
642
Greg Claytonc1422c12012-04-09 22:46:21 +0000643void
Greg Claytond451c1a2012-04-13 21:24:18 +0000644GDBRemoteCommunication::DumpHistory(Stream &strm)
Greg Claytonc1422c12012-04-09 22:46:21 +0000645{
Greg Claytond451c1a2012-04-13 21:24:18 +0000646 m_history.Dump (strm);
Greg Claytonc1422c12012-04-09 22:46:21 +0000647}