blob: e9cd2f8642450c89416a2dd4b917ee1f1b80ed58 [file] [log] [blame]
Greg Clayton61d043b2011-03-22 04:00:09 +00001//===-- GDBRemoteCommunicationClient.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 "GDBRemoteCommunicationClient.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16#include "llvm/ADT/Triple.h"
17#include "lldb/Interpreter/Args.h"
18#include "lldb/Core/ConnectionFileDescriptor.h"
19#include "lldb/Core/Log.h"
20#include "lldb/Core/State.h"
21#include "lldb/Core/StreamString.h"
22#include "lldb/Host/Endian.h"
23#include "lldb/Host/Host.h"
24#include "lldb/Host/TimeValue.h"
25
26// Project includes
27#include "Utility/StringExtractorGDBRemote.h"
28#include "ProcessGDBRemote.h"
29#include "ProcessGDBRemoteLog.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
34//----------------------------------------------------------------------
35// GDBRemoteCommunicationClient constructor
36//----------------------------------------------------------------------
Greg Claytonb72d0f02011-04-12 05:54:46 +000037GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
38 GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform),
Greg Clayton61d043b2011-03-22 04:00:09 +000039 m_supports_not_sending_acks (eLazyBoolCalculate),
40 m_supports_thread_suffix (eLazyBoolCalculate),
Greg Clayton61d043b2011-03-22 04:00:09 +000041 m_supports_vCont_all (eLazyBoolCalculate),
42 m_supports_vCont_any (eLazyBoolCalculate),
43 m_supports_vCont_c (eLazyBoolCalculate),
44 m_supports_vCont_C (eLazyBoolCalculate),
45 m_supports_vCont_s (eLazyBoolCalculate),
46 m_supports_vCont_S (eLazyBoolCalculate),
Greg Clayton24bc5d92011-03-30 18:16:51 +000047 m_qHostInfo_is_valid (eLazyBoolCalculate),
Greg Clayton2f085c62011-05-15 01:25:55 +000048 m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
Greg Clayton24bc5d92011-03-30 18:16:51 +000049 m_supports_qProcessInfoPID (true),
50 m_supports_qfProcessInfo (true),
51 m_supports_qUserName (true),
52 m_supports_qGroupName (true),
Greg Claytonb72d0f02011-04-12 05:54:46 +000053 m_supports_qThreadStopInfo (true),
54 m_supports_z0 (true),
55 m_supports_z1 (true),
56 m_supports_z2 (true),
57 m_supports_z3 (true),
58 m_supports_z4 (true),
59 m_curr_tid (LLDB_INVALID_THREAD_ID),
60 m_curr_tid_run (LLDB_INVALID_THREAD_ID),
Greg Clayton61d043b2011-03-22 04:00:09 +000061 m_async_mutex (Mutex::eMutexTypeRecursive),
62 m_async_packet_predicate (false),
63 m_async_packet (),
64 m_async_response (),
65 m_async_signal (-1),
Greg Clayton58e26e02011-03-24 04:28:38 +000066 m_host_arch(),
67 m_os_version_major (UINT32_MAX),
68 m_os_version_minor (UINT32_MAX),
69 m_os_version_update (UINT32_MAX)
Greg Clayton61d043b2011-03-22 04:00:09 +000070{
Greg Clayton61d043b2011-03-22 04:00:09 +000071}
72
73//----------------------------------------------------------------------
74// Destructor
75//----------------------------------------------------------------------
76GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
77{
Greg Clayton61d043b2011-03-22 04:00:09 +000078 if (IsConnected())
Greg Clayton61d043b2011-03-22 04:00:09 +000079 Disconnect();
Greg Clayton61d043b2011-03-22 04:00:09 +000080}
81
82bool
Greg Clayton58e26e02011-03-24 04:28:38 +000083GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
84{
85 // Start the read thread after we send the handshake ack since if we
86 // fail to send the handshake ack, there is no reason to continue...
87 if (SendAck())
Greg Clayton63afdb02011-06-17 01:22:15 +000088 return true;
Greg Clayton58e26e02011-03-24 04:28:38 +000089
90 if (error_ptr)
91 error_ptr->SetErrorString("failed to send the handshake ack");
92 return false;
93}
94
95void
96GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton61d043b2011-03-22 04:00:09 +000097{
98 if (m_supports_not_sending_acks == eLazyBoolCalculate)
99 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000100 m_send_acks = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000101 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton58e26e02011-03-24 04:28:38 +0000102
103 StringExtractorGDBRemote response;
Greg Clayton61d043b2011-03-22 04:00:09 +0000104 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
105 {
106 if (response.IsOKResponse())
Greg Clayton58e26e02011-03-24 04:28:38 +0000107 {
108 m_send_acks = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000109 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton58e26e02011-03-24 04:28:38 +0000110 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000111 }
112 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000113}
114
115void
116GDBRemoteCommunicationClient::ResetDiscoverableSettings()
117{
118 m_supports_not_sending_acks = eLazyBoolCalculate;
119 m_supports_thread_suffix = eLazyBoolCalculate;
Greg Clayton61d043b2011-03-22 04:00:09 +0000120 m_supports_vCont_c = eLazyBoolCalculate;
121 m_supports_vCont_C = eLazyBoolCalculate;
122 m_supports_vCont_s = eLazyBoolCalculate;
123 m_supports_vCont_S = eLazyBoolCalculate;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000124 m_qHostInfo_is_valid = eLazyBoolCalculate;
Greg Clayton2f085c62011-05-15 01:25:55 +0000125 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
Greg Clayton989816b2011-05-14 01:50:35 +0000126
Greg Clayton24bc5d92011-03-30 18:16:51 +0000127 m_supports_qProcessInfoPID = true;
128 m_supports_qfProcessInfo = true;
129 m_supports_qUserName = true;
130 m_supports_qGroupName = true;
Greg Claytonb72d0f02011-04-12 05:54:46 +0000131 m_supports_qThreadStopInfo = true;
132 m_supports_z0 = true;
133 m_supports_z1 = true;
134 m_supports_z2 = true;
135 m_supports_z3 = true;
136 m_supports_z4 = true;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000137 m_host_arch.Clear();
Greg Clayton61d043b2011-03-22 04:00:09 +0000138}
139
140
141bool
142GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
143{
144 if (m_supports_thread_suffix == eLazyBoolCalculate)
145 {
146 StringExtractorGDBRemote response;
147 m_supports_thread_suffix = eLazyBoolNo;
148 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
149 {
150 if (response.IsOKResponse())
151 m_supports_thread_suffix = eLazyBoolYes;
152 }
153 }
154 return m_supports_thread_suffix;
155}
156bool
157GDBRemoteCommunicationClient::GetVContSupported (char flavor)
158{
159 if (m_supports_vCont_c == eLazyBoolCalculate)
160 {
161 StringExtractorGDBRemote response;
162 m_supports_vCont_any = eLazyBoolNo;
163 m_supports_vCont_all = eLazyBoolNo;
164 m_supports_vCont_c = eLazyBoolNo;
165 m_supports_vCont_C = eLazyBoolNo;
166 m_supports_vCont_s = eLazyBoolNo;
167 m_supports_vCont_S = eLazyBoolNo;
168 if (SendPacketAndWaitForResponse("vCont?", response, false))
169 {
170 const char *response_cstr = response.GetStringRef().c_str();
171 if (::strstr (response_cstr, ";c"))
172 m_supports_vCont_c = eLazyBoolYes;
173
174 if (::strstr (response_cstr, ";C"))
175 m_supports_vCont_C = eLazyBoolYes;
176
177 if (::strstr (response_cstr, ";s"))
178 m_supports_vCont_s = eLazyBoolYes;
179
180 if (::strstr (response_cstr, ";S"))
181 m_supports_vCont_S = eLazyBoolYes;
182
183 if (m_supports_vCont_c == eLazyBoolYes &&
184 m_supports_vCont_C == eLazyBoolYes &&
185 m_supports_vCont_s == eLazyBoolYes &&
186 m_supports_vCont_S == eLazyBoolYes)
187 {
188 m_supports_vCont_all = eLazyBoolYes;
189 }
190
191 if (m_supports_vCont_c == eLazyBoolYes ||
192 m_supports_vCont_C == eLazyBoolYes ||
193 m_supports_vCont_s == eLazyBoolYes ||
194 m_supports_vCont_S == eLazyBoolYes)
195 {
196 m_supports_vCont_any = eLazyBoolYes;
197 }
198 }
199 }
200
201 switch (flavor)
202 {
203 case 'a': return m_supports_vCont_any;
204 case 'A': return m_supports_vCont_all;
205 case 'c': return m_supports_vCont_c;
206 case 'C': return m_supports_vCont_C;
207 case 's': return m_supports_vCont_s;
208 case 'S': return m_supports_vCont_S;
209 default: break;
210 }
211 return false;
212}
213
214
215size_t
216GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
217(
218 const char *payload,
219 StringExtractorGDBRemote &response,
220 bool send_async
221)
222{
223 return SendPacketAndWaitForResponse (payload,
224 ::strlen (payload),
225 response,
226 send_async);
227}
228
229size_t
230GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
231(
232 const char *payload,
233 size_t payload_length,
234 StringExtractorGDBRemote &response,
235 bool send_async
236)
237{
238 Mutex::Locker locker;
Greg Clayton61d043b2011-03-22 04:00:09 +0000239 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton801417e2011-07-07 01:59:51 +0000240 size_t response_len = 0;
Greg Clayton61d043b2011-03-22 04:00:09 +0000241 if (GetSequenceMutex (locker))
242 {
Greg Clayton139da722011-05-20 03:15:54 +0000243 if (SendPacketNoLock (payload, payload_length))
Greg Clayton801417e2011-07-07 01:59:51 +0000244 response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
245 else
246 {
247 if (log)
248 log->Printf("error: failed to send '%*s'", payload_length, payload);
249 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000250 }
251 else
252 {
253 if (send_async)
254 {
255 Mutex::Locker async_locker (m_async_mutex);
256 m_async_packet.assign(payload, payload_length);
257 m_async_packet_predicate.SetValue (true, eBroadcastNever);
258
259 if (log)
260 log->Printf ("async: async packet = %s", m_async_packet.c_str());
261
262 bool timed_out = false;
263 bool sent_interrupt = false;
264 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
265 {
266 if (sent_interrupt)
267 {
Greg Clayton63afdb02011-06-17 01:22:15 +0000268 TimeValue timeout_time;
269 timeout_time = TimeValue::Now();
270 timeout_time.OffsetWithSeconds (m_packet_timeout);
271
Greg Clayton61d043b2011-03-22 04:00:09 +0000272 if (log)
273 log->Printf ("async: sent interrupt");
Greg Clayton801417e2011-07-07 01:59:51 +0000274
Greg Clayton61d043b2011-03-22 04:00:09 +0000275 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
276 {
277 if (log)
278 log->Printf ("async: got response");
Greg Clayton801417e2011-07-07 01:59:51 +0000279
280 // Swap the response buffer to avoid malloc and string copy
281 response.GetStringRef().swap (m_async_response.GetStringRef());
282 response_len = response.GetStringRef().size();
Greg Clayton61d043b2011-03-22 04:00:09 +0000283 }
284 else
285 {
286 if (log)
287 log->Printf ("async: timed out waiting for response");
288 }
289
290 // Make sure we wait until the continue packet has been sent again...
291 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
292 {
293 if (log)
294 log->Printf ("async: timed out waiting for process to resume");
295 }
296 }
297 else
298 {
299 // We had a racy condition where we went to send the interrupt
Greg Clayton801417e2011-07-07 01:59:51 +0000300 // yet we were able to get the lock
301 if (log)
302 log->Printf ("async: got lock but failed to send interrupt");
Greg Clayton61d043b2011-03-22 04:00:09 +0000303 }
304 }
305 else
306 {
307 if (log)
308 log->Printf ("async: failed to interrupt");
309 }
310 }
311 else
312 {
313 if (log)
Greg Clayton801417e2011-07-07 01:59:51 +0000314 log->Printf("error: packet mutex taken and send_async == false, not sending packet '%*s'", payload_length, payload);
Greg Clayton61d043b2011-03-22 04:00:09 +0000315 }
316 }
Greg Clayton801417e2011-07-07 01:59:51 +0000317 if (response_len == 0)
318 {
319 if (log)
320 log->Printf("error: failed to get response for '%*s'", payload_length, payload);
321 }
322 return response_len;
Greg Clayton61d043b2011-03-22 04:00:09 +0000323}
324
325//template<typename _Tp>
326//class ScopedValueChanger
327//{
328//public:
329// // Take a value reference and the value to assign it to when this class
330// // instance goes out of scope.
331// ScopedValueChanger (_Tp &value_ref, _Tp value) :
332// m_value_ref (value_ref),
333// m_value (value)
334// {
335// }
336//
337// // This object is going out of scope, change the value pointed to by
338// // m_value_ref to the value we got during construction which was stored in
339// // m_value;
340// ~ScopedValueChanger ()
341// {
342// m_value_ref = m_value;
343// }
344//protected:
345// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
346// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
347//};
348
349StateType
350GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
351(
352 ProcessGDBRemote *process,
353 const char *payload,
354 size_t packet_length,
355 StringExtractorGDBRemote &response
356)
357{
358 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
359 if (log)
360 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
361
362 Mutex::Locker locker(m_sequence_mutex);
363 StateType state = eStateRunning;
364
365 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
366 m_public_is_running.SetValue (true, eBroadcastNever);
367 // Set the starting continue packet into "continue_packet". This packet
368 // make change if we are interrupted and we continue after an async packet...
369 std::string continue_packet(payload, packet_length);
370
Greg Clayton628cead2011-05-19 03:54:16 +0000371 bool got_stdout = false;
372
Greg Clayton61d043b2011-03-22 04:00:09 +0000373 while (state == eStateRunning)
374 {
Greg Clayton628cead2011-05-19 03:54:16 +0000375 if (!got_stdout)
376 {
377 if (log)
378 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
379 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
380 state = eStateInvalid;
Greg Clayton61d043b2011-03-22 04:00:09 +0000381
Greg Clayton628cead2011-05-19 03:54:16 +0000382 m_private_is_running.SetValue (true, eBroadcastNever);
383 }
384
385 got_stdout = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000386
387 if (log)
388 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%.*s)", __FUNCTION__);
389
Greg Clayton63afdb02011-06-17 01:22:15 +0000390 if (WaitForPacketWithTimeoutMicroSeconds (response, UINT32_MAX))
Greg Clayton61d043b2011-03-22 04:00:09 +0000391 {
392 if (response.Empty())
393 state = eStateInvalid;
394 else
395 {
396 const char stop_type = response.GetChar();
397 if (log)
398 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
399 switch (stop_type)
400 {
401 case 'T':
402 case 'S':
403 if (process->GetStopID() == 0)
404 {
405 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
406 {
407 lldb::pid_t pid = GetCurrentProcessID ();
408 if (pid != LLDB_INVALID_PROCESS_ID)
409 process->SetID (pid);
410 }
411 process->BuildDynamicRegisterInfo (true);
412 }
413
414 // Privately notify any internal threads that we have stopped
415 // in case we wanted to interrupt our process, yet we might
416 // send a packet and continue without returning control to the
417 // user.
418 m_private_is_running.SetValue (false, eBroadcastAlways);
419 if (m_async_signal != -1)
420 {
421 if (log)
422 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
423
424 // Save off the async signal we are supposed to send
425 const int async_signal = m_async_signal;
426 // Clear the async signal member so we don't end up
427 // sending the signal multiple times...
428 m_async_signal = -1;
429 // Check which signal we stopped with
430 uint8_t signo = response.GetHexU8(255);
431 if (signo == async_signal)
432 {
433 if (log)
434 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
435
436 // We already stopped with a signal that we wanted
437 // to stop with, so we are done
438 response.SetFilePos (0);
439 }
440 else
441 {
442 // We stopped with a different signal that the one
443 // we wanted to stop with, so now we must resume
444 // with the signal we want
445 char signal_packet[32];
446 int signal_packet_len = 0;
447 signal_packet_len = ::snprintf (signal_packet,
448 sizeof (signal_packet),
449 "C%2.2x",
450 async_signal);
451
452 if (log)
453 log->Printf ("async: stopped with signal %s, resume with %s",
454 Host::GetSignalAsCString (signo),
455 Host::GetSignalAsCString (async_signal));
456
457 // Set the continue packet to resume...
458 continue_packet.assign(signal_packet, signal_packet_len);
459 continue;
460 }
461 }
462 else if (m_async_packet_predicate.GetValue())
463 {
464 // We are supposed to send an asynchronous packet while
465 // we are running.
466 m_async_response.Clear();
467 if (m_async_packet.empty())
468 {
469 if (log)
470 log->Printf ("async: error: empty async packet");
471
472 }
473 else
474 {
475 if (log)
476 log->Printf ("async: sending packet: %s",
477 m_async_packet.c_str());
478
479 SendPacketAndWaitForResponse (&m_async_packet[0],
480 m_async_packet.size(),
481 m_async_response,
482 false);
483 }
484 // Let the other thread that was trying to send the async
485 // packet know that the packet has been sent and response is
486 // ready...
487 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
488
489 // Set the continue packet to resume...
490 continue_packet.assign (1, 'c');
491 continue;
492 }
493 // Stop with signal and thread info
494 state = eStateStopped;
495 break;
496
497 case 'W':
498 case 'X':
499 // process exited
500 state = eStateExited;
501 break;
502
503 case 'O':
504 // STDOUT
505 {
Greg Clayton628cead2011-05-19 03:54:16 +0000506 got_stdout = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000507 std::string inferior_stdout;
508 inferior_stdout.reserve(response.GetBytesLeft () / 2);
509 char ch;
510 while ((ch = response.GetHexU8()) != '\0')
511 inferior_stdout.append(1, ch);
512 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
513 }
514 break;
515
516 case 'E':
517 // ERROR
518 state = eStateInvalid;
519 break;
520
521 default:
522 if (log)
523 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
524 state = eStateInvalid;
525 break;
526 }
527 }
528 }
529 else
530 {
531 if (log)
532 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
533 state = eStateInvalid;
534 }
535 }
536 if (log)
537 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
538 response.SetFilePos(0);
539 m_private_is_running.SetValue (false, eBroadcastAlways);
540 m_public_is_running.SetValue (false, eBroadcastAlways);
541 return state;
542}
543
544bool
545GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
546{
547 m_async_signal = signo;
548 bool timed_out = false;
549 bool sent_interrupt = false;
550 Mutex::Locker locker;
551 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
552 return true;
553 m_async_signal = -1;
554 return false;
555}
556
557// This function takes a mutex locker as a parameter in case the GetSequenceMutex
558// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
559// (the expected result), then it will send the halt packet. If it does succeed
560// then the caller that requested the interrupt will want to keep the sequence
561// locked down so that no one else can send packets while the caller has control.
562// This function usually gets called when we are running and need to stop the
563// target. It can also be used when we are running and and we need to do something
564// else (like read/write memory), so we need to interrupt the running process
565// (gdb remote protocol requires this), and do what we need to do, then resume.
566
567bool
568GDBRemoteCommunicationClient::SendInterrupt
569(
570 Mutex::Locker& locker,
571 uint32_t seconds_to_wait_for_stop,
572 bool &sent_interrupt,
573 bool &timed_out
574)
575{
576 sent_interrupt = false;
577 timed_out = false;
578 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
579
580 if (IsRunning())
581 {
582 // Only send an interrupt if our debugserver is running...
583 if (GetSequenceMutex (locker) == false)
584 {
585 // Someone has the mutex locked waiting for a response or for the
586 // inferior to stop, so send the interrupt on the down low...
587 char ctrl_c = '\x03';
588 ConnectionStatus status = eConnectionStatusSuccess;
589 TimeValue timeout;
590 if (seconds_to_wait_for_stop)
591 {
592 timeout = TimeValue::Now();
593 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
594 }
595 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
596 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
597 if (bytes_written > 0)
598 {
599 sent_interrupt = true;
600 if (seconds_to_wait_for_stop)
601 {
602 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
603 {
604 if (log)
605 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, private state stopped", __FUNCTION__);
606 return true;
607 }
608 else
609 {
610 if (log)
611 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
612 }
613 }
614 else
615 {
616 if (log)
617 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
618 return true;
619 }
620 }
621 else
622 {
623 if (log)
624 log->Printf ("GDBRemoteCommunicationClient::%s () - failed to write interrupt", __FUNCTION__);
625 }
626 return false;
627 }
628 else
629 {
630 if (log)
631 log->Printf ("GDBRemoteCommunicationClient::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
632 }
633 }
634 return true;
635}
636
637lldb::pid_t
638GDBRemoteCommunicationClient::GetCurrentProcessID ()
639{
640 StringExtractorGDBRemote response;
641 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
642 {
643 if (response.GetChar() == 'Q')
644 if (response.GetChar() == 'C')
645 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
646 }
647 return LLDB_INVALID_PROCESS_ID;
648}
649
650bool
651GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
652{
653 error_str.clear();
654 StringExtractorGDBRemote response;
655 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
656 {
657 if (response.IsOKResponse())
658 return true;
659 if (response.GetChar() == 'E')
660 {
661 // A string the describes what failed when launching...
662 error_str = response.GetStringRef().substr(1);
663 }
664 else
665 {
666 error_str.assign ("unknown error occurred launching process");
667 }
668 }
669 else
670 {
671 error_str.assign ("failed to send the qLaunchSuccess packet");
672 }
673 return false;
674}
675
676int
677GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
678{
679 if (argv && argv[0])
680 {
681 StreamString packet;
682 packet.PutChar('A');
683 const char *arg;
684 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
685 {
686 const int arg_len = strlen(arg);
687 if (i > 0)
688 packet.PutChar(',');
689 packet.Printf("%i,%i,", arg_len * 2, i);
690 packet.PutBytesAsRawHex8 (arg, arg_len);
691 }
692
693 StringExtractorGDBRemote response;
694 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
695 {
696 if (response.IsOKResponse())
697 return 0;
698 uint8_t error = response.GetError();
699 if (error)
700 return error;
701 }
702 }
703 return -1;
704}
705
706int
707GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
708{
709 if (name_equal_value && name_equal_value[0])
710 {
711 StreamString packet;
712 packet.Printf("QEnvironment:%s", name_equal_value);
713 StringExtractorGDBRemote response;
714 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
715 {
716 if (response.IsOKResponse())
717 return 0;
718 uint8_t error = response.GetError();
719 if (error)
720 return error;
721 }
722 }
723 return -1;
724}
725
Greg Claytona4582402011-05-08 04:53:50 +0000726int
727GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
728{
729 if (arch && arch[0])
730 {
731 StreamString packet;
732 packet.Printf("QLaunchArch:%s", arch);
733 StringExtractorGDBRemote response;
734 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
735 {
736 if (response.IsOKResponse())
737 return 0;
738 uint8_t error = response.GetError();
739 if (error)
740 return error;
741 }
742 }
743 return -1;
744}
745
Greg Clayton61d043b2011-03-22 04:00:09 +0000746bool
Greg Clayton58e26e02011-03-24 04:28:38 +0000747GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
748 uint32_t &minor,
749 uint32_t &update)
750{
751 if (GetHostInfo ())
752 {
753 if (m_os_version_major != UINT32_MAX)
754 {
755 major = m_os_version_major;
756 minor = m_os_version_minor;
757 update = m_os_version_update;
758 return true;
759 }
760 }
761 return false;
762}
763
764bool
765GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
766{
767 if (GetHostInfo ())
768 {
769 if (!m_os_build.empty())
770 {
771 s = m_os_build;
772 return true;
773 }
774 }
775 s.clear();
776 return false;
777}
778
779
780bool
781GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
782{
783 if (GetHostInfo ())
784 {
785 if (!m_os_kernel.empty())
786 {
787 s = m_os_kernel;
788 return true;
789 }
790 }
791 s.clear();
792 return false;
793}
794
795bool
796GDBRemoteCommunicationClient::GetHostname (std::string &s)
797{
798 if (GetHostInfo ())
799 {
800 if (!m_hostname.empty())
801 {
802 s = m_hostname;
803 return true;
804 }
805 }
806 s.clear();
807 return false;
808}
809
810ArchSpec
811GDBRemoteCommunicationClient::GetSystemArchitecture ()
812{
813 if (GetHostInfo ())
814 return m_host_arch;
815 return ArchSpec();
816}
817
818
819bool
Greg Clayton06d7cc82011-04-04 18:18:57 +0000820GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton61d043b2011-03-22 04:00:09 +0000821{
Greg Clayton06d7cc82011-04-04 18:18:57 +0000822 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +0000823 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000824 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton61d043b2011-03-22 04:00:09 +0000825 StringExtractorGDBRemote response;
826 if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
827 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +0000828 if (response.IsNormalResponse())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000829 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000830 std::string name;
831 std::string value;
832 uint32_t cpu = LLDB_INVALID_CPUTYPE;
833 uint32_t sub = 0;
834 std::string arch_name;
835 std::string os_name;
836 std::string vendor_name;
837 std::string triple;
838 uint32_t pointer_byte_size = 0;
839 StringExtractor extractor;
840 ByteOrder byte_order = eByteOrderInvalid;
841 uint32_t num_keys_decoded = 0;
842 while (response.GetNameColonValue(name, value))
Greg Claytoncb8977d2011-03-23 00:09:55 +0000843 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000844 if (name.compare("cputype") == 0)
Greg Clayton58e26e02011-03-24 04:28:38 +0000845 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000846 // exception type in big endian hex
847 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
848 if (cpu != LLDB_INVALID_CPUTYPE)
849 ++num_keys_decoded;
850 }
851 else if (name.compare("cpusubtype") == 0)
852 {
853 // exception count in big endian hex
854 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
855 if (sub != 0)
856 ++num_keys_decoded;
857 }
858 else if (name.compare("arch") == 0)
859 {
860 arch_name.swap (value);
861 ++num_keys_decoded;
862 }
863 else if (name.compare("triple") == 0)
864 {
865 // The triple comes as ASCII hex bytes since it contains '-' chars
866 extractor.GetStringRef().swap(value);
867 extractor.SetFilePos(0);
868 extractor.GetHexByteString (triple);
869 ++num_keys_decoded;
870 }
871 else if (name.compare("os_build") == 0)
872 {
873 extractor.GetStringRef().swap(value);
874 extractor.SetFilePos(0);
875 extractor.GetHexByteString (m_os_build);
876 ++num_keys_decoded;
877 }
878 else if (name.compare("hostname") == 0)
879 {
880 extractor.GetStringRef().swap(value);
881 extractor.SetFilePos(0);
882 extractor.GetHexByteString (m_hostname);
883 ++num_keys_decoded;
884 }
885 else if (name.compare("os_kernel") == 0)
886 {
887 extractor.GetStringRef().swap(value);
888 extractor.SetFilePos(0);
889 extractor.GetHexByteString (m_os_kernel);
890 ++num_keys_decoded;
891 }
892 else if (name.compare("ostype") == 0)
893 {
894 os_name.swap (value);
895 ++num_keys_decoded;
896 }
897 else if (name.compare("vendor") == 0)
898 {
899 vendor_name.swap(value);
900 ++num_keys_decoded;
901 }
902 else if (name.compare("endian") == 0)
903 {
904 ++num_keys_decoded;
905 if (value.compare("little") == 0)
906 byte_order = eByteOrderLittle;
907 else if (value.compare("big") == 0)
908 byte_order = eByteOrderBig;
909 else if (value.compare("pdp") == 0)
910 byte_order = eByteOrderPDP;
911 else
912 --num_keys_decoded;
913 }
914 else if (name.compare("ptrsize") == 0)
915 {
916 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
917 if (pointer_byte_size != 0)
918 ++num_keys_decoded;
919 }
920 else if (name.compare("os_version") == 0)
921 {
922 Args::StringToVersion (value.c_str(),
923 m_os_version_major,
924 m_os_version_minor,
925 m_os_version_update);
926 if (m_os_version_major != UINT32_MAX)
927 ++num_keys_decoded;
928 }
929 }
930
931 if (num_keys_decoded > 0)
932 m_qHostInfo_is_valid = eLazyBoolYes;
933
934 if (triple.empty())
935 {
936 if (arch_name.empty())
937 {
938 if (cpu != LLDB_INVALID_CPUTYPE)
939 {
940 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
941 if (pointer_byte_size)
942 {
943 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
944 }
945 if (byte_order != eByteOrderInvalid)
946 {
947 assert (byte_order == m_host_arch.GetByteOrder());
948 }
949 if (!vendor_name.empty())
950 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
951 if (!os_name.empty())
952 m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
953
954 }
955 }
956 else
957 {
958 std::string triple;
959 triple += arch_name;
960 triple += '-';
961 if (vendor_name.empty())
962 triple += "unknown";
963 else
964 triple += vendor_name;
965 triple += '-';
966 if (os_name.empty())
967 triple += "unknown";
968 else
969 triple += os_name;
Greg Claytonf15996e2011-04-07 22:46:35 +0000970 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Clayton58e26e02011-03-24 04:28:38 +0000971 if (pointer_byte_size)
972 {
973 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
974 }
975 if (byte_order != eByteOrderInvalid)
976 {
977 assert (byte_order == m_host_arch.GetByteOrder());
978 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000979
Greg Clayton58e26e02011-03-24 04:28:38 +0000980 }
981 }
982 else
983 {
Greg Claytonf15996e2011-04-07 22:46:35 +0000984 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000985 if (pointer_byte_size)
986 {
987 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
988 }
989 if (byte_order != eByteOrderInvalid)
990 {
991 assert (byte_order == m_host_arch.GetByteOrder());
992 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000993 }
Greg Claytoncb8977d2011-03-23 00:09:55 +0000994 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000995 }
996 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000997 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton61d043b2011-03-22 04:00:09 +0000998}
999
1000int
1001GDBRemoteCommunicationClient::SendAttach
1002(
1003 lldb::pid_t pid,
1004 StringExtractorGDBRemote& response
1005)
1006{
1007 if (pid != LLDB_INVALID_PROCESS_ID)
1008 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001009 char packet[64];
1010 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", pid);
1011 assert (packet_len < sizeof(packet));
1012 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001013 {
1014 if (response.IsErrorResponse())
1015 return response.GetError();
1016 return 0;
1017 }
1018 }
1019 return -1;
1020}
1021
1022const lldb_private::ArchSpec &
1023GDBRemoteCommunicationClient::GetHostArchitecture ()
1024{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001025 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +00001026 GetHostInfo ();
Greg Claytoncb8977d2011-03-23 00:09:55 +00001027 return m_host_arch;
Greg Clayton61d043b2011-03-22 04:00:09 +00001028}
1029
1030addr_t
1031GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1032{
Greg Clayton2f085c62011-05-15 01:25:55 +00001033 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001034 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001035 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001036 char packet[64];
1037 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1038 permissions & lldb::ePermissionsReadable ? "r" : "",
1039 permissions & lldb::ePermissionsWritable ? "w" : "",
1040 permissions & lldb::ePermissionsExecutable ? "x" : "");
1041 assert (packet_len < sizeof(packet));
1042 StringExtractorGDBRemote response;
1043 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1044 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001045 if (!response.IsErrorResponse())
Greg Clayton989816b2011-05-14 01:50:35 +00001046 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1047 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001048 else
1049 {
1050 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1051 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001052 }
1053 return LLDB_INVALID_ADDRESS;
1054}
1055
1056bool
1057GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1058{
Greg Clayton2f085c62011-05-15 01:25:55 +00001059 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001060 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001061 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001062 char packet[64];
1063 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1064 assert (packet_len < sizeof(packet));
1065 StringExtractorGDBRemote response;
1066 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1067 {
1068 if (response.IsOKResponse())
1069 return true;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001070 }
1071 else
1072 {
1073 m_supports_alloc_dealloc_memory = eLazyBoolNo;
Greg Clayton989816b2011-05-14 01:50:35 +00001074 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001075 }
1076 return false;
1077}
1078
1079int
1080GDBRemoteCommunicationClient::SetSTDIN (char const *path)
1081{
1082 if (path && path[0])
1083 {
1084 StreamString packet;
1085 packet.PutCString("QSetSTDIN:");
1086 packet.PutBytesAsRawHex8(path, strlen(path));
1087
1088 StringExtractorGDBRemote response;
1089 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1090 {
1091 if (response.IsOKResponse())
1092 return 0;
1093 uint8_t error = response.GetError();
1094 if (error)
1095 return error;
1096 }
1097 }
1098 return -1;
1099}
1100
1101int
1102GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1103{
1104 if (path && path[0])
1105 {
1106 StreamString packet;
1107 packet.PutCString("QSetSTDOUT:");
1108 packet.PutBytesAsRawHex8(path, strlen(path));
1109
1110 StringExtractorGDBRemote response;
1111 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1112 {
1113 if (response.IsOKResponse())
1114 return 0;
1115 uint8_t error = response.GetError();
1116 if (error)
1117 return error;
1118 }
1119 }
1120 return -1;
1121}
1122
1123int
1124GDBRemoteCommunicationClient::SetSTDERR (char const *path)
1125{
1126 if (path && path[0])
1127 {
1128 StreamString packet;
1129 packet.PutCString("QSetSTDERR:");
1130 packet.PutBytesAsRawHex8(path, strlen(path));
1131
1132 StringExtractorGDBRemote response;
1133 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1134 {
1135 if (response.IsOKResponse())
1136 return 0;
1137 uint8_t error = response.GetError();
1138 if (error)
1139 return error;
1140 }
1141 }
1142 return -1;
1143}
1144
1145int
1146GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
1147{
1148 if (path && path[0])
1149 {
1150 StreamString packet;
1151 packet.PutCString("QSetWorkingDir:");
1152 packet.PutBytesAsRawHex8(path, strlen(path));
1153
1154 StringExtractorGDBRemote response;
1155 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1156 {
1157 if (response.IsOKResponse())
1158 return 0;
1159 uint8_t error = response.GetError();
1160 if (error)
1161 return error;
1162 }
1163 }
1164 return -1;
1165}
1166
1167int
1168GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
1169{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001170 char packet[32];
1171 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1172 assert (packet_len < sizeof(packet));
Greg Clayton61d043b2011-03-22 04:00:09 +00001173 StringExtractorGDBRemote response;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001174 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001175 {
1176 if (response.IsOKResponse())
1177 return 0;
1178 uint8_t error = response.GetError();
1179 if (error)
1180 return error;
1181 }
1182 return -1;
1183}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001184
1185bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001186GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001187{
1188 if (response.IsNormalResponse())
1189 {
1190 std::string name;
1191 std::string value;
1192 StringExtractor extractor;
1193
1194 while (response.GetNameColonValue(name, value))
1195 {
1196 if (name.compare("pid") == 0)
1197 {
1198 process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1199 }
1200 else if (name.compare("ppid") == 0)
1201 {
1202 process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1203 }
1204 else if (name.compare("uid") == 0)
1205 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001206 process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001207 }
1208 else if (name.compare("euid") == 0)
1209 {
1210 process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1211 }
1212 else if (name.compare("gid") == 0)
1213 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001214 process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001215 }
1216 else if (name.compare("egid") == 0)
1217 {
1218 process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1219 }
1220 else if (name.compare("triple") == 0)
1221 {
1222 // The triple comes as ASCII hex bytes since it contains '-' chars
1223 extractor.GetStringRef().swap(value);
1224 extractor.SetFilePos(0);
1225 extractor.GetHexByteString (value);
Greg Claytonf15996e2011-04-07 22:46:35 +00001226 process_info.GetArchitecture ().SetTriple (value.c_str(), NULL);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001227 }
1228 else if (name.compare("name") == 0)
1229 {
1230 StringExtractor extractor;
1231 // The the process name from ASCII hex bytes since we can't
1232 // control the characters in a process name
1233 extractor.GetStringRef().swap(value);
1234 extractor.SetFilePos(0);
1235 extractor.GetHexByteString (value);
Greg Claytonff39f742011-04-01 00:29:43 +00001236 process_info.SetName (value.c_str());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001237 }
1238 }
1239
1240 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1241 return true;
1242 }
1243 return false;
1244}
1245
1246bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001247GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001248{
1249 process_info.Clear();
1250
1251 if (m_supports_qProcessInfoPID)
1252 {
1253 char packet[32];
1254 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%i", pid);
1255 assert (packet_len < sizeof(packet));
1256 StringExtractorGDBRemote response;
1257 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1258 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001259 return DecodeProcessInfoResponse (response, process_info);
1260 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001261 else
1262 {
1263 m_supports_qProcessInfoPID = false;
1264 return false;
1265 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001266 }
1267 return false;
1268}
1269
1270uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +00001271GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1272 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001273{
1274 process_infos.Clear();
1275
1276 if (m_supports_qfProcessInfo)
1277 {
1278 StreamString packet;
1279 packet.PutCString ("qfProcessInfo");
1280 if (!match_info.MatchAllProcesses())
1281 {
1282 packet.PutChar (':');
1283 const char *name = match_info.GetProcessInfo().GetName();
1284 bool has_name_match = false;
1285 if (name && name[0])
1286 {
1287 has_name_match = true;
1288 NameMatchType name_match_type = match_info.GetNameMatchType();
1289 switch (name_match_type)
1290 {
1291 case eNameMatchIgnore:
1292 has_name_match = false;
1293 break;
1294
1295 case eNameMatchEquals:
1296 packet.PutCString ("name_match:equals;");
1297 break;
1298
1299 case eNameMatchContains:
1300 packet.PutCString ("name_match:contains;");
1301 break;
1302
1303 case eNameMatchStartsWith:
1304 packet.PutCString ("name_match:starts_with;");
1305 break;
1306
1307 case eNameMatchEndsWith:
1308 packet.PutCString ("name_match:ends_with;");
1309 break;
1310
1311 case eNameMatchRegularExpression:
1312 packet.PutCString ("name_match:regex;");
1313 break;
1314 }
1315 if (has_name_match)
1316 {
1317 packet.PutCString ("name:");
1318 packet.PutBytesAsRawHex8(name, ::strlen(name));
1319 packet.PutChar (';');
1320 }
1321 }
1322
1323 if (match_info.GetProcessInfo().ProcessIDIsValid())
1324 packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID());
1325 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
1326 packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID());
Greg Claytonb72d0f02011-04-12 05:54:46 +00001327 if (match_info.GetProcessInfo().UserIDIsValid())
1328 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
1329 if (match_info.GetProcessInfo().GroupIDIsValid())
1330 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001331 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
1332 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
1333 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1334 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
1335 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1336 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
1337 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
1338 {
1339 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
1340 const llvm::Triple &triple = match_arch.GetTriple();
1341 packet.PutCString("triple:");
1342 packet.PutCStringAsRawHex8(triple.getTriple().c_str());
1343 packet.PutChar (';');
1344 }
1345 }
1346 StringExtractorGDBRemote response;
1347 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1348 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001349 do
1350 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001351 ProcessInstanceInfo process_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001352 if (!DecodeProcessInfoResponse (response, process_info))
1353 break;
1354 process_infos.Append(process_info);
1355 response.GetStringRef().clear();
1356 response.SetFilePos(0);
1357 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
1358 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001359 else
1360 {
1361 m_supports_qfProcessInfo = false;
1362 return 0;
1363 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001364 }
1365 return process_infos.GetSize();
1366
1367}
1368
1369bool
1370GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
1371{
1372 if (m_supports_qUserName)
1373 {
1374 char packet[32];
1375 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
1376 assert (packet_len < sizeof(packet));
1377 StringExtractorGDBRemote response;
1378 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1379 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001380 if (response.IsNormalResponse())
1381 {
1382 // Make sure we parsed the right number of characters. The response is
1383 // the hex encoded user name and should make up the entire packet.
1384 // If there are any non-hex ASCII bytes, the length won't match below..
1385 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1386 return true;
1387 }
1388 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001389 else
1390 {
1391 m_supports_qUserName = false;
1392 return false;
1393 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001394 }
1395 return false;
1396
1397}
1398
1399bool
1400GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
1401{
1402 if (m_supports_qGroupName)
1403 {
1404 char packet[32];
1405 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
1406 assert (packet_len < sizeof(packet));
1407 StringExtractorGDBRemote response;
1408 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1409 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001410 if (response.IsNormalResponse())
1411 {
1412 // Make sure we parsed the right number of characters. The response is
1413 // the hex encoded group name and should make up the entire packet.
1414 // If there are any non-hex ASCII bytes, the length won't match below..
1415 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1416 return true;
1417 }
1418 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001419 else
1420 {
1421 m_supports_qGroupName = false;
1422 return false;
1423 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001424 }
1425 return false;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001426}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001427
Greg Clayton06d7cc82011-04-04 18:18:57 +00001428void
1429GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
1430{
1431 uint32_t i;
1432 TimeValue start_time, end_time;
1433 uint64_t total_time_nsec;
1434 float packets_per_second;
1435 if (SendSpeedTestPacket (0, 0))
1436 {
1437 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
1438 {
1439 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
1440 {
1441 start_time = TimeValue::Now();
1442 for (i=0; i<num_packets; ++i)
1443 {
1444 SendSpeedTestPacket (send_size, recv_size);
1445 }
1446 end_time = TimeValue::Now();
1447 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001448 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001449 printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%09.9llu sec for %f packets/sec.\n",
1450 num_packets,
1451 send_size,
1452 recv_size,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001453 total_time_nsec / TimeValue::NanoSecPerSec,
1454 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001455 packets_per_second);
1456 if (recv_size == 0)
1457 recv_size = 32;
1458 }
1459 if (send_size == 0)
1460 send_size = 32;
1461 }
1462 }
1463 else
1464 {
1465 start_time = TimeValue::Now();
1466 for (i=0; i<num_packets; ++i)
1467 {
1468 GetCurrentProcessID ();
1469 }
1470 end_time = TimeValue::Now();
1471 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001472 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001473 printf ("%u 'qC' packets packets in 0x%llu%09.9llu sec for %f packets/sec.\n",
1474 num_packets,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001475 total_time_nsec / TimeValue::NanoSecPerSec,
1476 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001477 packets_per_second);
1478 }
1479}
1480
1481bool
1482GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
1483{
1484 StreamString packet;
1485 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
1486 uint32_t bytes_left = send_size;
1487 while (bytes_left > 0)
1488 {
1489 if (bytes_left >= 26)
1490 {
1491 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
1492 bytes_left -= 26;
1493 }
1494 else
1495 {
1496 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
1497 bytes_left = 0;
1498 }
1499 }
1500
1501 StringExtractorGDBRemote response;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001502 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001503 return false;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001504}
Greg Claytonb72d0f02011-04-12 05:54:46 +00001505
1506uint16_t
1507GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort ()
1508{
1509 StringExtractorGDBRemote response;
1510 if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false))
1511 {
1512 std::string name;
1513 std::string value;
1514 uint16_t port = 0;
1515 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1516 while (response.GetNameColonValue(name, value))
1517 {
1518 if (name.size() == 4 && name.compare("port") == 0)
1519 port = Args::StringToUInt32(value.c_str(), 0, 0);
1520 if (name.size() == 3 && name.compare("pid") == 0)
1521 pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
1522 }
1523 return port;
1524 }
1525 return 0;
1526}
1527
1528bool
1529GDBRemoteCommunicationClient::SetCurrentThread (int tid)
1530{
1531 if (m_curr_tid == tid)
1532 return true;
1533
1534 char packet[32];
1535 int packet_len;
1536 if (tid <= 0)
1537 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
1538 else
1539 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
1540 assert (packet_len + 1 < sizeof(packet));
1541 StringExtractorGDBRemote response;
1542 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1543 {
1544 if (response.IsOKResponse())
1545 {
1546 m_curr_tid = tid;
1547 return true;
1548 }
1549 }
1550 return false;
1551}
1552
1553bool
1554GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
1555{
1556 if (m_curr_tid_run == tid)
1557 return true;
1558
1559 char packet[32];
1560 int packet_len;
1561 if (tid <= 0)
1562 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
1563 else
1564 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
1565
1566 assert (packet_len + 1 < sizeof(packet));
1567 StringExtractorGDBRemote response;
1568 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1569 {
1570 if (response.IsOKResponse())
1571 {
1572 m_curr_tid_run = tid;
1573 return true;
1574 }
1575 }
1576 return false;
1577}
1578
1579bool
1580GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
1581{
1582 if (SendPacketAndWaitForResponse("?", 1, response, false))
1583 return response.IsNormalResponse();
1584 return false;
1585}
1586
1587bool
1588GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response)
1589{
1590 if (m_supports_qThreadStopInfo)
1591 {
1592 char packet[256];
1593 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid);
1594 assert (packet_len < sizeof(packet));
1595 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1596 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001597 if (response.IsNormalResponse())
Greg Claytonb72d0f02011-04-12 05:54:46 +00001598 return true;
1599 else
1600 return false;
1601 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001602 else
1603 {
1604 m_supports_qThreadStopInfo = false;
1605 }
Greg Claytonb72d0f02011-04-12 05:54:46 +00001606 }
Greg Clayton139da722011-05-20 03:15:54 +00001607// if (SetCurrentThread (tid))
1608// return GetStopReply (response);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001609 return false;
1610}
1611
1612
1613uint8_t
1614GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
1615{
1616 switch (type)
1617 {
1618 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break;
1619 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break;
1620 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
1621 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
1622 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
1623 default: return UINT8_MAX;
1624 }
1625
1626 char packet[64];
1627 const int packet_len = ::snprintf (packet,
1628 sizeof(packet),
1629 "%c%i,%llx,%x",
1630 insert ? 'Z' : 'z',
1631 type,
1632 addr,
1633 length);
1634
1635 assert (packet_len + 1 < sizeof(packet));
1636 StringExtractorGDBRemote response;
1637 if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
1638 {
1639 if (response.IsOKResponse())
1640 return 0;
Greg Claytonb72d0f02011-04-12 05:54:46 +00001641 else if (response.IsErrorResponse())
1642 return response.GetError();
1643 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001644 else
1645 {
1646 switch (type)
1647 {
1648 case eBreakpointSoftware: m_supports_z0 = false; break;
1649 case eBreakpointHardware: m_supports_z1 = false; break;
1650 case eWatchpointWrite: m_supports_z2 = false; break;
1651 case eWatchpointRead: m_supports_z3 = false; break;
1652 case eWatchpointReadWrite: m_supports_z4 = false; break;
1653 default: break;
1654 }
1655 }
1656
Greg Claytonb72d0f02011-04-12 05:54:46 +00001657 return UINT8_MAX;
1658}
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001659
1660size_t
1661GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
1662 bool &sequence_mutex_unavailable)
1663{
1664 Mutex::Locker locker;
1665 thread_ids.clear();
1666
1667 if (GetSequenceMutex (locker))
1668 {
1669 sequence_mutex_unavailable = false;
1670 StringExtractorGDBRemote response;
1671
Greg Clayton63afdb02011-06-17 01:22:15 +00001672 for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001673 response.IsNormalResponse();
Greg Clayton63afdb02011-06-17 01:22:15 +00001674 SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()))
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001675 {
1676 char ch = response.GetChar();
1677 if (ch == 'l')
1678 break;
1679 if (ch == 'm')
1680 {
1681 do
1682 {
1683 tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
1684
1685 if (tid != LLDB_INVALID_THREAD_ID)
1686 {
1687 thread_ids.push_back (tid);
1688 }
1689 ch = response.GetChar(); // Skip the command separator
1690 } while (ch == ','); // Make sure we got a comma separator
1691 }
1692 }
1693 }
1694 else
1695 {
1696 sequence_mutex_unavailable = true;
1697 }
1698 return thread_ids.size();
1699}