blob: eaa03984f50a9a7d0a8ee17891c2201a1d7fe2e8 [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 Claytona9385532011-11-18 07:03:08 +000049 m_supports_memory_region_info (eLazyBoolCalculate),
Greg Clayton24bc5d92011-03-30 18:16:51 +000050 m_supports_qProcessInfoPID (true),
51 m_supports_qfProcessInfo (true),
52 m_supports_qUserName (true),
53 m_supports_qGroupName (true),
Greg Claytonb72d0f02011-04-12 05:54:46 +000054 m_supports_qThreadStopInfo (true),
55 m_supports_z0 (true),
56 m_supports_z1 (true),
57 m_supports_z2 (true),
58 m_supports_z3 (true),
59 m_supports_z4 (true),
60 m_curr_tid (LLDB_INVALID_THREAD_ID),
61 m_curr_tid_run (LLDB_INVALID_THREAD_ID),
Greg Clayton61d043b2011-03-22 04:00:09 +000062 m_async_mutex (Mutex::eMutexTypeRecursive),
63 m_async_packet_predicate (false),
64 m_async_packet (),
65 m_async_response (),
66 m_async_signal (-1),
Greg Clayton58e26e02011-03-24 04:28:38 +000067 m_host_arch(),
68 m_os_version_major (UINT32_MAX),
69 m_os_version_minor (UINT32_MAX),
70 m_os_version_update (UINT32_MAX)
Greg Clayton61d043b2011-03-22 04:00:09 +000071{
Greg Clayton61d043b2011-03-22 04:00:09 +000072}
73
74//----------------------------------------------------------------------
75// Destructor
76//----------------------------------------------------------------------
77GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
78{
Greg Clayton61d043b2011-03-22 04:00:09 +000079 if (IsConnected())
Greg Clayton61d043b2011-03-22 04:00:09 +000080 Disconnect();
Greg Clayton61d043b2011-03-22 04:00:09 +000081}
82
83bool
Greg Clayton58e26e02011-03-24 04:28:38 +000084GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
85{
86 // Start the read thread after we send the handshake ack since if we
87 // fail to send the handshake ack, there is no reason to continue...
88 if (SendAck())
Greg Clayton63afdb02011-06-17 01:22:15 +000089 return true;
Greg Clayton58e26e02011-03-24 04:28:38 +000090
91 if (error_ptr)
92 error_ptr->SetErrorString("failed to send the handshake ack");
93 return false;
94}
95
96void
97GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
Greg Clayton61d043b2011-03-22 04:00:09 +000098{
99 if (m_supports_not_sending_acks == eLazyBoolCalculate)
100 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000101 m_send_acks = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000102 m_supports_not_sending_acks = eLazyBoolNo;
Greg Clayton58e26e02011-03-24 04:28:38 +0000103
104 StringExtractorGDBRemote response;
Greg Clayton61d043b2011-03-22 04:00:09 +0000105 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
106 {
107 if (response.IsOKResponse())
Greg Clayton58e26e02011-03-24 04:28:38 +0000108 {
109 m_send_acks = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000110 m_supports_not_sending_acks = eLazyBoolYes;
Greg Clayton58e26e02011-03-24 04:28:38 +0000111 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000112 }
113 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000114}
115
116void
117GDBRemoteCommunicationClient::ResetDiscoverableSettings()
118{
119 m_supports_not_sending_acks = eLazyBoolCalculate;
120 m_supports_thread_suffix = eLazyBoolCalculate;
Greg Clayton61d043b2011-03-22 04:00:09 +0000121 m_supports_vCont_c = eLazyBoolCalculate;
122 m_supports_vCont_C = eLazyBoolCalculate;
123 m_supports_vCont_s = eLazyBoolCalculate;
124 m_supports_vCont_S = eLazyBoolCalculate;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000125 m_qHostInfo_is_valid = eLazyBoolCalculate;
Greg Clayton2f085c62011-05-15 01:25:55 +0000126 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
Greg Claytona9385532011-11-18 07:03:08 +0000127 m_supports_memory_region_info = eLazyBoolCalculate;
Greg Clayton989816b2011-05-14 01:50:35 +0000128
Greg Clayton24bc5d92011-03-30 18:16:51 +0000129 m_supports_qProcessInfoPID = true;
130 m_supports_qfProcessInfo = true;
131 m_supports_qUserName = true;
132 m_supports_qGroupName = true;
Greg Claytonb72d0f02011-04-12 05:54:46 +0000133 m_supports_qThreadStopInfo = true;
134 m_supports_z0 = true;
135 m_supports_z1 = true;
136 m_supports_z2 = true;
137 m_supports_z3 = true;
138 m_supports_z4 = true;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000139 m_host_arch.Clear();
Greg Clayton61d043b2011-03-22 04:00:09 +0000140}
141
142
143bool
144GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
145{
146 if (m_supports_thread_suffix == eLazyBoolCalculate)
147 {
148 StringExtractorGDBRemote response;
149 m_supports_thread_suffix = eLazyBoolNo;
150 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
151 {
152 if (response.IsOKResponse())
153 m_supports_thread_suffix = eLazyBoolYes;
154 }
155 }
156 return m_supports_thread_suffix;
157}
158bool
159GDBRemoteCommunicationClient::GetVContSupported (char flavor)
160{
161 if (m_supports_vCont_c == eLazyBoolCalculate)
162 {
163 StringExtractorGDBRemote response;
164 m_supports_vCont_any = eLazyBoolNo;
165 m_supports_vCont_all = eLazyBoolNo;
166 m_supports_vCont_c = eLazyBoolNo;
167 m_supports_vCont_C = eLazyBoolNo;
168 m_supports_vCont_s = eLazyBoolNo;
169 m_supports_vCont_S = eLazyBoolNo;
170 if (SendPacketAndWaitForResponse("vCont?", response, false))
171 {
172 const char *response_cstr = response.GetStringRef().c_str();
173 if (::strstr (response_cstr, ";c"))
174 m_supports_vCont_c = eLazyBoolYes;
175
176 if (::strstr (response_cstr, ";C"))
177 m_supports_vCont_C = eLazyBoolYes;
178
179 if (::strstr (response_cstr, ";s"))
180 m_supports_vCont_s = eLazyBoolYes;
181
182 if (::strstr (response_cstr, ";S"))
183 m_supports_vCont_S = eLazyBoolYes;
184
185 if (m_supports_vCont_c == eLazyBoolYes &&
186 m_supports_vCont_C == eLazyBoolYes &&
187 m_supports_vCont_s == eLazyBoolYes &&
188 m_supports_vCont_S == eLazyBoolYes)
189 {
190 m_supports_vCont_all = eLazyBoolYes;
191 }
192
193 if (m_supports_vCont_c == eLazyBoolYes ||
194 m_supports_vCont_C == eLazyBoolYes ||
195 m_supports_vCont_s == eLazyBoolYes ||
196 m_supports_vCont_S == eLazyBoolYes)
197 {
198 m_supports_vCont_any = eLazyBoolYes;
199 }
200 }
201 }
202
203 switch (flavor)
204 {
205 case 'a': return m_supports_vCont_any;
206 case 'A': return m_supports_vCont_all;
207 case 'c': return m_supports_vCont_c;
208 case 'C': return m_supports_vCont_C;
209 case 's': return m_supports_vCont_s;
210 case 'S': return m_supports_vCont_S;
211 default: break;
212 }
213 return false;
214}
215
216
217size_t
218GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
219(
220 const char *payload,
221 StringExtractorGDBRemote &response,
222 bool send_async
223)
224{
225 return SendPacketAndWaitForResponse (payload,
226 ::strlen (payload),
227 response,
228 send_async);
229}
230
231size_t
232GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
233(
234 const char *payload,
235 size_t payload_length,
236 StringExtractorGDBRemote &response,
237 bool send_async
238)
239{
240 Mutex::Locker locker;
Greg Clayton61d043b2011-03-22 04:00:09 +0000241 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Greg Clayton801417e2011-07-07 01:59:51 +0000242 size_t response_len = 0;
Greg Clayton61d043b2011-03-22 04:00:09 +0000243 if (GetSequenceMutex (locker))
244 {
Greg Clayton139da722011-05-20 03:15:54 +0000245 if (SendPacketNoLock (payload, payload_length))
Greg Clayton801417e2011-07-07 01:59:51 +0000246 response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
247 else
248 {
249 if (log)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000250 log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
Greg Clayton801417e2011-07-07 01:59:51 +0000251 }
Greg Clayton61d043b2011-03-22 04:00:09 +0000252 }
253 else
254 {
255 if (send_async)
256 {
257 Mutex::Locker async_locker (m_async_mutex);
258 m_async_packet.assign(payload, payload_length);
259 m_async_packet_predicate.SetValue (true, eBroadcastNever);
260
261 if (log)
262 log->Printf ("async: async packet = %s", m_async_packet.c_str());
263
264 bool timed_out = false;
265 bool sent_interrupt = false;
266 if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
267 {
268 if (sent_interrupt)
269 {
Greg Clayton63afdb02011-06-17 01:22:15 +0000270 TimeValue timeout_time;
271 timeout_time = TimeValue::Now();
272 timeout_time.OffsetWithSeconds (m_packet_timeout);
273
Greg Clayton61d043b2011-03-22 04:00:09 +0000274 if (log)
275 log->Printf ("async: sent interrupt");
Greg Clayton801417e2011-07-07 01:59:51 +0000276
Greg Clayton61d043b2011-03-22 04:00:09 +0000277 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
278 {
279 if (log)
280 log->Printf ("async: got response");
Greg Clayton801417e2011-07-07 01:59:51 +0000281
282 // Swap the response buffer to avoid malloc and string copy
283 response.GetStringRef().swap (m_async_response.GetStringRef());
284 response_len = response.GetStringRef().size();
Greg Clayton61d043b2011-03-22 04:00:09 +0000285 }
286 else
287 {
288 if (log)
289 log->Printf ("async: timed out waiting for response");
290 }
291
292 // Make sure we wait until the continue packet has been sent again...
293 if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
294 {
Greg Claytonb7669b32011-10-27 22:04:16 +0000295 if (log)
296 {
297 if (timed_out)
298 log->Printf ("async: timed out waiting for process to resume, but process was resumed");
299 else
300 log->Printf ("async: async packet sent");
301 }
302 }
303 else
304 {
Greg Clayton61d043b2011-03-22 04:00:09 +0000305 if (log)
306 log->Printf ("async: timed out waiting for process to resume");
307 }
308 }
309 else
310 {
311 // We had a racy condition where we went to send the interrupt
Greg Clayton801417e2011-07-07 01:59:51 +0000312 // yet we were able to get the lock
313 if (log)
314 log->Printf ("async: got lock but failed to send interrupt");
Greg Clayton61d043b2011-03-22 04:00:09 +0000315 }
316 }
317 else
318 {
319 if (log)
320 log->Printf ("async: failed to interrupt");
321 }
322 }
323 else
324 {
325 if (log)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000326 log->Printf("error: packet mutex taken and send_async == false, not sending packet '%*s'", (int) payload_length, payload);
Greg Clayton61d043b2011-03-22 04:00:09 +0000327 }
328 }
Greg Clayton801417e2011-07-07 01:59:51 +0000329 if (response_len == 0)
330 {
331 if (log)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000332 log->Printf("error: failed to get response for '%*s'", (int) payload_length, payload);
Greg Clayton801417e2011-07-07 01:59:51 +0000333 }
334 return response_len;
Greg Clayton61d043b2011-03-22 04:00:09 +0000335}
336
337//template<typename _Tp>
338//class ScopedValueChanger
339//{
340//public:
341// // Take a value reference and the value to assign it to when this class
342// // instance goes out of scope.
343// ScopedValueChanger (_Tp &value_ref, _Tp value) :
344// m_value_ref (value_ref),
345// m_value (value)
346// {
347// }
348//
349// // This object is going out of scope, change the value pointed to by
350// // m_value_ref to the value we got during construction which was stored in
351// // m_value;
352// ~ScopedValueChanger ()
353// {
354// m_value_ref = m_value;
355// }
356//protected:
357// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
358// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
359//};
360
361StateType
362GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
363(
364 ProcessGDBRemote *process,
365 const char *payload,
366 size_t packet_length,
367 StringExtractorGDBRemote &response
368)
369{
370 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
371 if (log)
372 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
373
374 Mutex::Locker locker(m_sequence_mutex);
375 StateType state = eStateRunning;
376
377 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
378 m_public_is_running.SetValue (true, eBroadcastNever);
379 // Set the starting continue packet into "continue_packet". This packet
380 // make change if we are interrupted and we continue after an async packet...
381 std::string continue_packet(payload, packet_length);
382
Greg Clayton628cead2011-05-19 03:54:16 +0000383 bool got_stdout = false;
384
Greg Clayton61d043b2011-03-22 04:00:09 +0000385 while (state == eStateRunning)
386 {
Greg Clayton628cead2011-05-19 03:54:16 +0000387 if (!got_stdout)
388 {
389 if (log)
390 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
391 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
392 state = eStateInvalid;
Greg Clayton61d043b2011-03-22 04:00:09 +0000393
Greg Claytonb7669b32011-10-27 22:04:16 +0000394 m_private_is_running.SetValue (true, eBroadcastAlways);
Greg Clayton628cead2011-05-19 03:54:16 +0000395 }
396
397 got_stdout = false;
Greg Clayton61d043b2011-03-22 04:00:09 +0000398
399 if (log)
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000400 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str());
Greg Clayton61d043b2011-03-22 04:00:09 +0000401
Greg Clayton63afdb02011-06-17 01:22:15 +0000402 if (WaitForPacketWithTimeoutMicroSeconds (response, UINT32_MAX))
Greg Clayton61d043b2011-03-22 04:00:09 +0000403 {
404 if (response.Empty())
405 state = eStateInvalid;
406 else
407 {
408 const char stop_type = response.GetChar();
409 if (log)
410 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
411 switch (stop_type)
412 {
413 case 'T':
414 case 'S':
415 if (process->GetStopID() == 0)
416 {
417 if (process->GetID() == LLDB_INVALID_PROCESS_ID)
418 {
419 lldb::pid_t pid = GetCurrentProcessID ();
420 if (pid != LLDB_INVALID_PROCESS_ID)
421 process->SetID (pid);
422 }
423 process->BuildDynamicRegisterInfo (true);
424 }
425
426 // Privately notify any internal threads that we have stopped
427 // in case we wanted to interrupt our process, yet we might
428 // send a packet and continue without returning control to the
429 // user.
430 m_private_is_running.SetValue (false, eBroadcastAlways);
431 if (m_async_signal != -1)
432 {
433 if (log)
434 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
435
436 // Save off the async signal we are supposed to send
437 const int async_signal = m_async_signal;
438 // Clear the async signal member so we don't end up
439 // sending the signal multiple times...
440 m_async_signal = -1;
441 // Check which signal we stopped with
442 uint8_t signo = response.GetHexU8(255);
443 if (signo == async_signal)
444 {
445 if (log)
446 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
447
448 // We already stopped with a signal that we wanted
449 // to stop with, so we are done
450 response.SetFilePos (0);
451 }
452 else
453 {
454 // We stopped with a different signal that the one
455 // we wanted to stop with, so now we must resume
456 // with the signal we want
457 char signal_packet[32];
458 int signal_packet_len = 0;
459 signal_packet_len = ::snprintf (signal_packet,
460 sizeof (signal_packet),
461 "C%2.2x",
462 async_signal);
463
464 if (log)
465 log->Printf ("async: stopped with signal %s, resume with %s",
466 Host::GetSignalAsCString (signo),
467 Host::GetSignalAsCString (async_signal));
468
469 // Set the continue packet to resume...
470 continue_packet.assign(signal_packet, signal_packet_len);
471 continue;
472 }
473 }
474 else if (m_async_packet_predicate.GetValue())
475 {
476 // We are supposed to send an asynchronous packet while
477 // we are running.
478 m_async_response.Clear();
479 if (m_async_packet.empty())
480 {
481 if (log)
482 log->Printf ("async: error: empty async packet");
483
484 }
485 else
486 {
487 if (log)
488 log->Printf ("async: sending packet: %s",
489 m_async_packet.c_str());
490
491 SendPacketAndWaitForResponse (&m_async_packet[0],
492 m_async_packet.size(),
493 m_async_response,
494 false);
495 }
496 // Let the other thread that was trying to send the async
497 // packet know that the packet has been sent and response is
498 // ready...
499 m_async_packet_predicate.SetValue(false, eBroadcastAlways);
500
501 // Set the continue packet to resume...
502 continue_packet.assign (1, 'c');
503 continue;
504 }
505 // Stop with signal and thread info
506 state = eStateStopped;
507 break;
508
509 case 'W':
510 case 'X':
511 // process exited
512 state = eStateExited;
513 break;
514
515 case 'O':
516 // STDOUT
517 {
Greg Clayton628cead2011-05-19 03:54:16 +0000518 got_stdout = true;
Greg Clayton61d043b2011-03-22 04:00:09 +0000519 std::string inferior_stdout;
520 inferior_stdout.reserve(response.GetBytesLeft () / 2);
521 char ch;
522 while ((ch = response.GetHexU8()) != '\0')
523 inferior_stdout.append(1, ch);
524 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
525 }
526 break;
527
528 case 'E':
529 // ERROR
530 state = eStateInvalid;
531 break;
532
533 default:
534 if (log)
535 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
536 state = eStateInvalid;
537 break;
538 }
539 }
540 }
541 else
542 {
543 if (log)
544 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
545 state = eStateInvalid;
546 }
547 }
548 if (log)
549 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
550 response.SetFilePos(0);
551 m_private_is_running.SetValue (false, eBroadcastAlways);
552 m_public_is_running.SetValue (false, eBroadcastAlways);
553 return state;
554}
555
556bool
557GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
558{
559 m_async_signal = signo;
560 bool timed_out = false;
561 bool sent_interrupt = false;
562 Mutex::Locker locker;
563 if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
564 return true;
565 m_async_signal = -1;
566 return false;
567}
568
569// This function takes a mutex locker as a parameter in case the GetSequenceMutex
570// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
571// (the expected result), then it will send the halt packet. If it does succeed
572// then the caller that requested the interrupt will want to keep the sequence
573// locked down so that no one else can send packets while the caller has control.
574// This function usually gets called when we are running and need to stop the
575// target. It can also be used when we are running and and we need to do something
576// else (like read/write memory), so we need to interrupt the running process
577// (gdb remote protocol requires this), and do what we need to do, then resume.
578
579bool
580GDBRemoteCommunicationClient::SendInterrupt
581(
582 Mutex::Locker& locker,
583 uint32_t seconds_to_wait_for_stop,
584 bool &sent_interrupt,
585 bool &timed_out
586)
587{
588 sent_interrupt = false;
589 timed_out = false;
590 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
591
592 if (IsRunning())
593 {
594 // Only send an interrupt if our debugserver is running...
595 if (GetSequenceMutex (locker) == false)
596 {
597 // Someone has the mutex locked waiting for a response or for the
598 // inferior to stop, so send the interrupt on the down low...
599 char ctrl_c = '\x03';
600 ConnectionStatus status = eConnectionStatusSuccess;
601 TimeValue timeout;
602 if (seconds_to_wait_for_stop)
603 {
604 timeout = TimeValue::Now();
605 timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
606 }
607 size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
608 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
609 if (bytes_written > 0)
610 {
611 sent_interrupt = true;
612 if (seconds_to_wait_for_stop)
613 {
614 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
615 {
616 if (log)
617 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, private state stopped", __FUNCTION__);
618 return true;
619 }
620 else
621 {
622 if (log)
623 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
624 }
625 }
626 else
627 {
628 if (log)
629 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
630 return true;
631 }
632 }
633 else
634 {
635 if (log)
636 log->Printf ("GDBRemoteCommunicationClient::%s () - failed to write interrupt", __FUNCTION__);
637 }
638 return false;
639 }
640 else
641 {
642 if (log)
643 log->Printf ("GDBRemoteCommunicationClient::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
644 }
645 }
646 return true;
647}
648
649lldb::pid_t
650GDBRemoteCommunicationClient::GetCurrentProcessID ()
651{
652 StringExtractorGDBRemote response;
653 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
654 {
655 if (response.GetChar() == 'Q')
656 if (response.GetChar() == 'C')
657 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
658 }
659 return LLDB_INVALID_PROCESS_ID;
660}
661
662bool
663GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
664{
665 error_str.clear();
666 StringExtractorGDBRemote response;
667 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
668 {
669 if (response.IsOKResponse())
670 return true;
671 if (response.GetChar() == 'E')
672 {
673 // A string the describes what failed when launching...
674 error_str = response.GetStringRef().substr(1);
675 }
676 else
677 {
678 error_str.assign ("unknown error occurred launching process");
679 }
680 }
681 else
682 {
683 error_str.assign ("failed to send the qLaunchSuccess packet");
684 }
685 return false;
686}
687
688int
689GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
690{
691 if (argv && argv[0])
692 {
693 StreamString packet;
694 packet.PutChar('A');
695 const char *arg;
696 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
697 {
698 const int arg_len = strlen(arg);
699 if (i > 0)
700 packet.PutChar(',');
701 packet.Printf("%i,%i,", arg_len * 2, i);
702 packet.PutBytesAsRawHex8 (arg, arg_len);
703 }
704
705 StringExtractorGDBRemote response;
706 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
707 {
708 if (response.IsOKResponse())
709 return 0;
710 uint8_t error = response.GetError();
711 if (error)
712 return error;
713 }
714 }
715 return -1;
716}
717
718int
719GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
720{
721 if (name_equal_value && name_equal_value[0])
722 {
723 StreamString packet;
724 packet.Printf("QEnvironment:%s", name_equal_value);
725 StringExtractorGDBRemote response;
726 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
727 {
728 if (response.IsOKResponse())
729 return 0;
730 uint8_t error = response.GetError();
731 if (error)
732 return error;
733 }
734 }
735 return -1;
736}
737
Greg Claytona4582402011-05-08 04:53:50 +0000738int
739GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
740{
741 if (arch && arch[0])
742 {
743 StreamString packet;
744 packet.Printf("QLaunchArch:%s", arch);
745 StringExtractorGDBRemote response;
746 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
747 {
748 if (response.IsOKResponse())
749 return 0;
750 uint8_t error = response.GetError();
751 if (error)
752 return error;
753 }
754 }
755 return -1;
756}
757
Greg Clayton61d043b2011-03-22 04:00:09 +0000758bool
Greg Clayton58e26e02011-03-24 04:28:38 +0000759GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
760 uint32_t &minor,
761 uint32_t &update)
762{
763 if (GetHostInfo ())
764 {
765 if (m_os_version_major != UINT32_MAX)
766 {
767 major = m_os_version_major;
768 minor = m_os_version_minor;
769 update = m_os_version_update;
770 return true;
771 }
772 }
773 return false;
774}
775
776bool
777GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
778{
779 if (GetHostInfo ())
780 {
781 if (!m_os_build.empty())
782 {
783 s = m_os_build;
784 return true;
785 }
786 }
787 s.clear();
788 return false;
789}
790
791
792bool
793GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
794{
795 if (GetHostInfo ())
796 {
797 if (!m_os_kernel.empty())
798 {
799 s = m_os_kernel;
800 return true;
801 }
802 }
803 s.clear();
804 return false;
805}
806
807bool
808GDBRemoteCommunicationClient::GetHostname (std::string &s)
809{
810 if (GetHostInfo ())
811 {
812 if (!m_hostname.empty())
813 {
814 s = m_hostname;
815 return true;
816 }
817 }
818 s.clear();
819 return false;
820}
821
822ArchSpec
823GDBRemoteCommunicationClient::GetSystemArchitecture ()
824{
825 if (GetHostInfo ())
826 return m_host_arch;
827 return ArchSpec();
828}
829
830
831bool
Greg Clayton06d7cc82011-04-04 18:18:57 +0000832GDBRemoteCommunicationClient::GetHostInfo (bool force)
Greg Clayton61d043b2011-03-22 04:00:09 +0000833{
Greg Clayton06d7cc82011-04-04 18:18:57 +0000834 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +0000835 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000836 m_qHostInfo_is_valid = eLazyBoolNo;
Greg Clayton61d043b2011-03-22 04:00:09 +0000837 StringExtractorGDBRemote response;
838 if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
839 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +0000840 if (response.IsNormalResponse())
Greg Claytoncb8977d2011-03-23 00:09:55 +0000841 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000842 std::string name;
843 std::string value;
844 uint32_t cpu = LLDB_INVALID_CPUTYPE;
845 uint32_t sub = 0;
846 std::string arch_name;
847 std::string os_name;
848 std::string vendor_name;
849 std::string triple;
850 uint32_t pointer_byte_size = 0;
851 StringExtractor extractor;
852 ByteOrder byte_order = eByteOrderInvalid;
853 uint32_t num_keys_decoded = 0;
854 while (response.GetNameColonValue(name, value))
Greg Claytoncb8977d2011-03-23 00:09:55 +0000855 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000856 if (name.compare("cputype") == 0)
Greg Clayton58e26e02011-03-24 04:28:38 +0000857 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000858 // exception type in big endian hex
859 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
860 if (cpu != LLDB_INVALID_CPUTYPE)
861 ++num_keys_decoded;
862 }
863 else if (name.compare("cpusubtype") == 0)
864 {
865 // exception count in big endian hex
866 sub = Args::StringToUInt32 (value.c_str(), 0, 0);
867 if (sub != 0)
868 ++num_keys_decoded;
869 }
870 else if (name.compare("arch") == 0)
871 {
872 arch_name.swap (value);
873 ++num_keys_decoded;
874 }
875 else if (name.compare("triple") == 0)
876 {
877 // The triple comes as ASCII hex bytes since it contains '-' chars
878 extractor.GetStringRef().swap(value);
879 extractor.SetFilePos(0);
880 extractor.GetHexByteString (triple);
881 ++num_keys_decoded;
882 }
883 else if (name.compare("os_build") == 0)
884 {
885 extractor.GetStringRef().swap(value);
886 extractor.SetFilePos(0);
887 extractor.GetHexByteString (m_os_build);
888 ++num_keys_decoded;
889 }
890 else if (name.compare("hostname") == 0)
891 {
892 extractor.GetStringRef().swap(value);
893 extractor.SetFilePos(0);
894 extractor.GetHexByteString (m_hostname);
895 ++num_keys_decoded;
896 }
897 else if (name.compare("os_kernel") == 0)
898 {
899 extractor.GetStringRef().swap(value);
900 extractor.SetFilePos(0);
901 extractor.GetHexByteString (m_os_kernel);
902 ++num_keys_decoded;
903 }
904 else if (name.compare("ostype") == 0)
905 {
906 os_name.swap (value);
907 ++num_keys_decoded;
908 }
909 else if (name.compare("vendor") == 0)
910 {
911 vendor_name.swap(value);
912 ++num_keys_decoded;
913 }
914 else if (name.compare("endian") == 0)
915 {
916 ++num_keys_decoded;
917 if (value.compare("little") == 0)
918 byte_order = eByteOrderLittle;
919 else if (value.compare("big") == 0)
920 byte_order = eByteOrderBig;
921 else if (value.compare("pdp") == 0)
922 byte_order = eByteOrderPDP;
923 else
924 --num_keys_decoded;
925 }
926 else if (name.compare("ptrsize") == 0)
927 {
928 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
929 if (pointer_byte_size != 0)
930 ++num_keys_decoded;
931 }
932 else if (name.compare("os_version") == 0)
933 {
934 Args::StringToVersion (value.c_str(),
935 m_os_version_major,
936 m_os_version_minor,
937 m_os_version_update);
938 if (m_os_version_major != UINT32_MAX)
939 ++num_keys_decoded;
940 }
941 }
942
943 if (num_keys_decoded > 0)
944 m_qHostInfo_is_valid = eLazyBoolYes;
945
946 if (triple.empty())
947 {
948 if (arch_name.empty())
949 {
950 if (cpu != LLDB_INVALID_CPUTYPE)
951 {
952 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
953 if (pointer_byte_size)
954 {
955 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
956 }
957 if (byte_order != eByteOrderInvalid)
958 {
959 assert (byte_order == m_host_arch.GetByteOrder());
960 }
961 if (!vendor_name.empty())
962 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
963 if (!os_name.empty())
Greg Clayton89798cc2011-09-15 00:21:03 +0000964 m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000965
966 }
967 }
968 else
969 {
970 std::string triple;
971 triple += arch_name;
972 triple += '-';
973 if (vendor_name.empty())
974 triple += "unknown";
975 else
976 triple += vendor_name;
977 triple += '-';
978 if (os_name.empty())
979 triple += "unknown";
980 else
981 triple += os_name;
Greg Claytonf15996e2011-04-07 22:46:35 +0000982 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Clayton58e26e02011-03-24 04:28:38 +0000983 if (pointer_byte_size)
984 {
985 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
986 }
987 if (byte_order != eByteOrderInvalid)
988 {
989 assert (byte_order == m_host_arch.GetByteOrder());
990 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000991
Greg Clayton58e26e02011-03-24 04:28:38 +0000992 }
993 }
994 else
995 {
Greg Claytonf15996e2011-04-07 22:46:35 +0000996 m_host_arch.SetTriple (triple.c_str(), NULL);
Greg Claytoncb8977d2011-03-23 00:09:55 +0000997 if (pointer_byte_size)
998 {
999 assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1000 }
1001 if (byte_order != eByteOrderInvalid)
1002 {
1003 assert (byte_order == m_host_arch.GetByteOrder());
1004 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001005 }
Greg Claytoncb8977d2011-03-23 00:09:55 +00001006 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001007 }
1008 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001009 return m_qHostInfo_is_valid == eLazyBoolYes;
Greg Clayton61d043b2011-03-22 04:00:09 +00001010}
1011
1012int
1013GDBRemoteCommunicationClient::SendAttach
1014(
1015 lldb::pid_t pid,
1016 StringExtractorGDBRemote& response
1017)
1018{
1019 if (pid != LLDB_INVALID_PROCESS_ID)
1020 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001021 char packet[64];
Greg Claytond9919d32011-12-01 23:28:38 +00001022 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%llx", pid);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001023 assert (packet_len < sizeof(packet));
1024 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001025 {
1026 if (response.IsErrorResponse())
1027 return response.GetError();
1028 return 0;
1029 }
1030 }
1031 return -1;
1032}
1033
1034const lldb_private::ArchSpec &
1035GDBRemoteCommunicationClient::GetHostArchitecture ()
1036{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001037 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
Greg Clayton61d043b2011-03-22 04:00:09 +00001038 GetHostInfo ();
Greg Claytoncb8977d2011-03-23 00:09:55 +00001039 return m_host_arch;
Greg Clayton61d043b2011-03-22 04:00:09 +00001040}
1041
1042addr_t
1043GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1044{
Greg Clayton2f085c62011-05-15 01:25:55 +00001045 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001046 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001047 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001048 char packet[64];
1049 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
1050 permissions & lldb::ePermissionsReadable ? "r" : "",
1051 permissions & lldb::ePermissionsWritable ? "w" : "",
1052 permissions & lldb::ePermissionsExecutable ? "x" : "");
1053 assert (packet_len < sizeof(packet));
1054 StringExtractorGDBRemote response;
1055 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1056 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001057 if (!response.IsErrorResponse())
Greg Clayton989816b2011-05-14 01:50:35 +00001058 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1059 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001060 else
1061 {
1062 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1063 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001064 }
1065 return LLDB_INVALID_ADDRESS;
1066}
1067
1068bool
1069GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1070{
Greg Clayton2f085c62011-05-15 01:25:55 +00001071 if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
Greg Clayton61d043b2011-03-22 04:00:09 +00001072 {
Greg Clayton2f085c62011-05-15 01:25:55 +00001073 m_supports_alloc_dealloc_memory = eLazyBoolYes;
Greg Clayton989816b2011-05-14 01:50:35 +00001074 char packet[64];
1075 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
1076 assert (packet_len < sizeof(packet));
1077 StringExtractorGDBRemote response;
1078 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1079 {
1080 if (response.IsOKResponse())
1081 return true;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001082 }
1083 else
1084 {
1085 m_supports_alloc_dealloc_memory = eLazyBoolNo;
Greg Clayton989816b2011-05-14 01:50:35 +00001086 }
Greg Clayton61d043b2011-03-22 04:00:09 +00001087 }
1088 return false;
1089}
1090
Greg Claytona9385532011-11-18 07:03:08 +00001091Error
1092GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
1093 lldb_private::MemoryRegionInfo &region_info)
1094{
1095 Error error;
1096 region_info.Clear();
1097
1098 if (m_supports_memory_region_info != eLazyBoolNo)
1099 {
1100 m_supports_memory_region_info = eLazyBoolYes;
1101 char packet[64];
1102 const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%llx", (uint64_t)addr);
1103 assert (packet_len < sizeof(packet));
1104 StringExtractorGDBRemote response;
1105 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1106 {
1107 std::string name;
1108 std::string value;
1109 addr_t addr_value;
1110 bool success = true;
Jason Molenda1f9c39c2011-12-13 05:39:38 +00001111 bool saw_permissions = false;
Greg Claytona9385532011-11-18 07:03:08 +00001112 while (success && response.GetNameColonValue(name, value))
1113 {
1114 if (name.compare ("start") == 0)
1115 {
1116 addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
1117 if (success)
1118 region_info.GetRange().SetRangeBase(addr_value);
1119 }
1120 else if (name.compare ("size") == 0)
1121 {
1122 addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success);
1123 if (success)
1124 region_info.GetRange().SetByteSize (addr_value);
1125 }
Jason Molenda1f9c39c2011-12-13 05:39:38 +00001126 else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
Greg Claytona9385532011-11-18 07:03:08 +00001127 {
Jason Molenda1f9c39c2011-12-13 05:39:38 +00001128 saw_permissions = true;
1129 if (region_info.GetRange().Contains (addr))
1130 {
1131 if (value.find('r') != std::string::npos)
1132 region_info.SetReadable (MemoryRegionInfo::eYes);
1133 else
1134 region_info.SetReadable (MemoryRegionInfo::eNo);
1135
1136 if (value.find('w') != std::string::npos)
1137 region_info.SetWritable (MemoryRegionInfo::eYes);
1138 else
1139 region_info.SetWritable (MemoryRegionInfo::eNo);
1140
1141 if (value.find('x') != std::string::npos)
1142 region_info.SetExecutable (MemoryRegionInfo::eYes);
1143 else
1144 region_info.SetExecutable (MemoryRegionInfo::eNo);
1145 }
1146 else
1147 {
1148 // The reported region does not contain this address -- we're looking at an unmapped page
1149 region_info.SetReadable (MemoryRegionInfo::eNo);
1150 region_info.SetWritable (MemoryRegionInfo::eNo);
1151 region_info.SetExecutable (MemoryRegionInfo::eNo);
1152 }
Greg Claytona9385532011-11-18 07:03:08 +00001153 }
1154 else if (name.compare ("error") == 0)
1155 {
1156 StringExtractorGDBRemote name_extractor;
1157 // Swap "value" over into "name_extractor"
1158 name_extractor.GetStringRef().swap(value);
1159 // Now convert the HEX bytes into a string value
1160 name_extractor.GetHexByteString (value);
1161 error.SetErrorString(value.c_str());
1162 }
1163 }
Jason Molenda1f9c39c2011-12-13 05:39:38 +00001164
1165 // We got a valid address range back but no permissions -- which means this is an unmapped page
1166 if (region_info.GetRange().IsValid() && saw_permissions == false)
1167 {
1168 region_info.SetReadable (MemoryRegionInfo::eNo);
1169 region_info.SetWritable (MemoryRegionInfo::eNo);
1170 region_info.SetExecutable (MemoryRegionInfo::eNo);
1171 }
Greg Claytona9385532011-11-18 07:03:08 +00001172 }
1173 else
1174 {
1175 m_supports_memory_region_info = eLazyBoolNo;
1176 }
1177 }
1178
1179 if (m_supports_memory_region_info == eLazyBoolNo)
1180 {
1181 error.SetErrorString("qMemoryRegionInfo is not supported");
1182 }
1183 if (error.Fail())
1184 region_info.Clear();
1185 return error;
1186
1187}
1188
1189
Greg Clayton61d043b2011-03-22 04:00:09 +00001190int
1191GDBRemoteCommunicationClient::SetSTDIN (char const *path)
1192{
1193 if (path && path[0])
1194 {
1195 StreamString packet;
1196 packet.PutCString("QSetSTDIN:");
1197 packet.PutBytesAsRawHex8(path, strlen(path));
1198
1199 StringExtractorGDBRemote response;
1200 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1201 {
1202 if (response.IsOKResponse())
1203 return 0;
1204 uint8_t error = response.GetError();
1205 if (error)
1206 return error;
1207 }
1208 }
1209 return -1;
1210}
1211
1212int
1213GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1214{
1215 if (path && path[0])
1216 {
1217 StreamString packet;
1218 packet.PutCString("QSetSTDOUT:");
1219 packet.PutBytesAsRawHex8(path, strlen(path));
1220
1221 StringExtractorGDBRemote response;
1222 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1223 {
1224 if (response.IsOKResponse())
1225 return 0;
1226 uint8_t error = response.GetError();
1227 if (error)
1228 return error;
1229 }
1230 }
1231 return -1;
1232}
1233
1234int
1235GDBRemoteCommunicationClient::SetSTDERR (char const *path)
1236{
1237 if (path && path[0])
1238 {
1239 StreamString packet;
1240 packet.PutCString("QSetSTDERR:");
1241 packet.PutBytesAsRawHex8(path, strlen(path));
1242
1243 StringExtractorGDBRemote response;
1244 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1245 {
1246 if (response.IsOKResponse())
1247 return 0;
1248 uint8_t error = response.GetError();
1249 if (error)
1250 return error;
1251 }
1252 }
1253 return -1;
1254}
1255
1256int
1257GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
1258{
1259 if (path && path[0])
1260 {
1261 StreamString packet;
1262 packet.PutCString("QSetWorkingDir:");
1263 packet.PutBytesAsRawHex8(path, strlen(path));
1264
1265 StringExtractorGDBRemote response;
1266 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1267 {
1268 if (response.IsOKResponse())
1269 return 0;
1270 uint8_t error = response.GetError();
1271 if (error)
1272 return error;
1273 }
1274 }
1275 return -1;
1276}
1277
1278int
1279GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
1280{
Greg Clayton24bc5d92011-03-30 18:16:51 +00001281 char packet[32];
1282 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1283 assert (packet_len < sizeof(packet));
Greg Clayton61d043b2011-03-22 04:00:09 +00001284 StringExtractorGDBRemote response;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001285 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
Greg Clayton61d043b2011-03-22 04:00:09 +00001286 {
1287 if (response.IsOKResponse())
1288 return 0;
1289 uint8_t error = response.GetError();
1290 if (error)
1291 return error;
1292 }
1293 return -1;
1294}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001295
1296bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001297GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001298{
1299 if (response.IsNormalResponse())
1300 {
1301 std::string name;
1302 std::string value;
1303 StringExtractor extractor;
1304
1305 while (response.GetNameColonValue(name, value))
1306 {
1307 if (name.compare("pid") == 0)
1308 {
1309 process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1310 }
1311 else if (name.compare("ppid") == 0)
1312 {
1313 process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
1314 }
1315 else if (name.compare("uid") == 0)
1316 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001317 process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001318 }
1319 else if (name.compare("euid") == 0)
1320 {
1321 process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1322 }
1323 else if (name.compare("gid") == 0)
1324 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001325 process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
Greg Clayton24bc5d92011-03-30 18:16:51 +00001326 }
1327 else if (name.compare("egid") == 0)
1328 {
1329 process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
1330 }
1331 else if (name.compare("triple") == 0)
1332 {
1333 // The triple comes as ASCII hex bytes since it contains '-' chars
1334 extractor.GetStringRef().swap(value);
1335 extractor.SetFilePos(0);
1336 extractor.GetHexByteString (value);
Greg Claytonf15996e2011-04-07 22:46:35 +00001337 process_info.GetArchitecture ().SetTriple (value.c_str(), NULL);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001338 }
1339 else if (name.compare("name") == 0)
1340 {
1341 StringExtractor extractor;
1342 // The the process name from ASCII hex bytes since we can't
1343 // control the characters in a process name
1344 extractor.GetStringRef().swap(value);
1345 extractor.SetFilePos(0);
1346 extractor.GetHexByteString (value);
Greg Clayton527154d2011-11-15 03:53:30 +00001347 process_info.GetExecutableFile().SetFile (value.c_str(), false);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001348 }
1349 }
1350
1351 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
1352 return true;
1353 }
1354 return false;
1355}
1356
1357bool
Greg Claytonb72d0f02011-04-12 05:54:46 +00001358GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001359{
1360 process_info.Clear();
1361
1362 if (m_supports_qProcessInfoPID)
1363 {
1364 char packet[32];
Greg Claytond9919d32011-12-01 23:28:38 +00001365 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%llu", pid);
Greg Clayton24bc5d92011-03-30 18:16:51 +00001366 assert (packet_len < sizeof(packet));
1367 StringExtractorGDBRemote response;
1368 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1369 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001370 return DecodeProcessInfoResponse (response, process_info);
1371 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001372 else
1373 {
1374 m_supports_qProcessInfoPID = false;
1375 return false;
1376 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001377 }
1378 return false;
1379}
1380
1381uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +00001382GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
1383 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +00001384{
1385 process_infos.Clear();
1386
1387 if (m_supports_qfProcessInfo)
1388 {
1389 StreamString packet;
1390 packet.PutCString ("qfProcessInfo");
1391 if (!match_info.MatchAllProcesses())
1392 {
1393 packet.PutChar (':');
1394 const char *name = match_info.GetProcessInfo().GetName();
1395 bool has_name_match = false;
1396 if (name && name[0])
1397 {
1398 has_name_match = true;
1399 NameMatchType name_match_type = match_info.GetNameMatchType();
1400 switch (name_match_type)
1401 {
1402 case eNameMatchIgnore:
1403 has_name_match = false;
1404 break;
1405
1406 case eNameMatchEquals:
1407 packet.PutCString ("name_match:equals;");
1408 break;
1409
1410 case eNameMatchContains:
1411 packet.PutCString ("name_match:contains;");
1412 break;
1413
1414 case eNameMatchStartsWith:
1415 packet.PutCString ("name_match:starts_with;");
1416 break;
1417
1418 case eNameMatchEndsWith:
1419 packet.PutCString ("name_match:ends_with;");
1420 break;
1421
1422 case eNameMatchRegularExpression:
1423 packet.PutCString ("name_match:regex;");
1424 break;
1425 }
1426 if (has_name_match)
1427 {
1428 packet.PutCString ("name:");
1429 packet.PutBytesAsRawHex8(name, ::strlen(name));
1430 packet.PutChar (';');
1431 }
1432 }
1433
1434 if (match_info.GetProcessInfo().ProcessIDIsValid())
Greg Claytond9919d32011-12-01 23:28:38 +00001435 packet.Printf("pid:%llu;",match_info.GetProcessInfo().GetProcessID());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001436 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
Greg Claytond9919d32011-12-01 23:28:38 +00001437 packet.Printf("parent_pid:%llu;",match_info.GetProcessInfo().GetParentProcessID());
Greg Claytonb72d0f02011-04-12 05:54:46 +00001438 if (match_info.GetProcessInfo().UserIDIsValid())
1439 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
1440 if (match_info.GetProcessInfo().GroupIDIsValid())
1441 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
Greg Clayton24bc5d92011-03-30 18:16:51 +00001442 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
1443 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
1444 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1445 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
1446 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
1447 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
1448 if (match_info.GetProcessInfo().GetArchitecture().IsValid())
1449 {
1450 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
1451 const llvm::Triple &triple = match_arch.GetTriple();
1452 packet.PutCString("triple:");
1453 packet.PutCStringAsRawHex8(triple.getTriple().c_str());
1454 packet.PutChar (';');
1455 }
1456 }
1457 StringExtractorGDBRemote response;
1458 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
1459 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001460 do
1461 {
Greg Claytonb72d0f02011-04-12 05:54:46 +00001462 ProcessInstanceInfo process_info;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001463 if (!DecodeProcessInfoResponse (response, process_info))
1464 break;
1465 process_infos.Append(process_info);
1466 response.GetStringRef().clear();
1467 response.SetFilePos(0);
1468 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
1469 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001470 else
1471 {
1472 m_supports_qfProcessInfo = false;
1473 return 0;
1474 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001475 }
1476 return process_infos.GetSize();
1477
1478}
1479
1480bool
1481GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
1482{
1483 if (m_supports_qUserName)
1484 {
1485 char packet[32];
1486 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
1487 assert (packet_len < sizeof(packet));
1488 StringExtractorGDBRemote response;
1489 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1490 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001491 if (response.IsNormalResponse())
1492 {
1493 // Make sure we parsed the right number of characters. The response is
1494 // the hex encoded user name and should make up the entire packet.
1495 // If there are any non-hex ASCII bytes, the length won't match below..
1496 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1497 return true;
1498 }
1499 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001500 else
1501 {
1502 m_supports_qUserName = false;
1503 return false;
1504 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001505 }
1506 return false;
1507
1508}
1509
1510bool
1511GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
1512{
1513 if (m_supports_qGroupName)
1514 {
1515 char packet[32];
1516 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
1517 assert (packet_len < sizeof(packet));
1518 StringExtractorGDBRemote response;
1519 if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
1520 {
Greg Clayton24bc5d92011-03-30 18:16:51 +00001521 if (response.IsNormalResponse())
1522 {
1523 // Make sure we parsed the right number of characters. The response is
1524 // the hex encoded group name and should make up the entire packet.
1525 // If there are any non-hex ASCII bytes, the length won't match below..
1526 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
1527 return true;
1528 }
1529 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001530 else
1531 {
1532 m_supports_qGroupName = false;
1533 return false;
1534 }
Greg Clayton24bc5d92011-03-30 18:16:51 +00001535 }
1536 return false;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001537}
Greg Clayton24bc5d92011-03-30 18:16:51 +00001538
Greg Clayton06d7cc82011-04-04 18:18:57 +00001539void
1540GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
1541{
1542 uint32_t i;
1543 TimeValue start_time, end_time;
1544 uint64_t total_time_nsec;
1545 float packets_per_second;
1546 if (SendSpeedTestPacket (0, 0))
1547 {
1548 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2)
1549 {
1550 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2)
1551 {
1552 start_time = TimeValue::Now();
1553 for (i=0; i<num_packets; ++i)
1554 {
1555 SendSpeedTestPacket (send_size, recv_size);
1556 }
1557 end_time = TimeValue::Now();
1558 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001559 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Greg Clayton153ccd72011-08-10 02:10:13 +00001560 printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%9.9llu sec for %f packets/sec.\n",
Greg Clayton06d7cc82011-04-04 18:18:57 +00001561 num_packets,
1562 send_size,
1563 recv_size,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001564 total_time_nsec / TimeValue::NanoSecPerSec,
1565 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001566 packets_per_second);
1567 if (recv_size == 0)
1568 recv_size = 32;
1569 }
1570 if (send_size == 0)
1571 send_size = 32;
1572 }
1573 }
1574 else
1575 {
1576 start_time = TimeValue::Now();
1577 for (i=0; i<num_packets; ++i)
1578 {
1579 GetCurrentProcessID ();
1580 }
1581 end_time = TimeValue::Now();
1582 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001583 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
Greg Clayton153ccd72011-08-10 02:10:13 +00001584 printf ("%u 'qC' packets packets in 0x%llu%9.9llu sec for %f packets/sec.\n",
Greg Clayton06d7cc82011-04-04 18:18:57 +00001585 num_packets,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +00001586 total_time_nsec / TimeValue::NanoSecPerSec,
1587 total_time_nsec % TimeValue::NanoSecPerSec,
Greg Clayton06d7cc82011-04-04 18:18:57 +00001588 packets_per_second);
1589 }
1590}
1591
1592bool
1593GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
1594{
1595 StreamString packet;
1596 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
1597 uint32_t bytes_left = send_size;
1598 while (bytes_left > 0)
1599 {
1600 if (bytes_left >= 26)
1601 {
1602 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
1603 bytes_left -= 26;
1604 }
1605 else
1606 {
1607 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
1608 bytes_left = 0;
1609 }
1610 }
1611
1612 StringExtractorGDBRemote response;
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001613 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0;
Greg Clayton06d7cc82011-04-04 18:18:57 +00001614 return false;
Greg Clayton24bc5d92011-03-30 18:16:51 +00001615}
Greg Claytonb72d0f02011-04-12 05:54:46 +00001616
1617uint16_t
1618GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort ()
1619{
1620 StringExtractorGDBRemote response;
1621 if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false))
1622 {
1623 std::string name;
1624 std::string value;
1625 uint16_t port = 0;
1626 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1627 while (response.GetNameColonValue(name, value))
1628 {
1629 if (name.size() == 4 && name.compare("port") == 0)
1630 port = Args::StringToUInt32(value.c_str(), 0, 0);
1631 if (name.size() == 3 && name.compare("pid") == 0)
1632 pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
1633 }
1634 return port;
1635 }
1636 return 0;
1637}
1638
1639bool
1640GDBRemoteCommunicationClient::SetCurrentThread (int tid)
1641{
1642 if (m_curr_tid == tid)
1643 return true;
1644
1645 char packet[32];
1646 int packet_len;
1647 if (tid <= 0)
1648 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
1649 else
1650 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
1651 assert (packet_len + 1 < sizeof(packet));
1652 StringExtractorGDBRemote response;
1653 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1654 {
1655 if (response.IsOKResponse())
1656 {
1657 m_curr_tid = tid;
1658 return true;
1659 }
1660 }
1661 return false;
1662}
1663
1664bool
1665GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
1666{
1667 if (m_curr_tid_run == tid)
1668 return true;
1669
1670 char packet[32];
1671 int packet_len;
1672 if (tid <= 0)
1673 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
1674 else
1675 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
1676
1677 assert (packet_len + 1 < sizeof(packet));
1678 StringExtractorGDBRemote response;
1679 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1680 {
1681 if (response.IsOKResponse())
1682 {
1683 m_curr_tid_run = tid;
1684 return true;
1685 }
1686 }
1687 return false;
1688}
1689
1690bool
1691GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
1692{
1693 if (SendPacketAndWaitForResponse("?", 1, response, false))
1694 return response.IsNormalResponse();
1695 return false;
1696}
1697
1698bool
1699GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response)
1700{
1701 if (m_supports_qThreadStopInfo)
1702 {
1703 char packet[256];
1704 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid);
1705 assert (packet_len < sizeof(packet));
1706 if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
1707 {
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001708 if (response.IsNormalResponse())
Greg Claytonb72d0f02011-04-12 05:54:46 +00001709 return true;
1710 else
1711 return false;
1712 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001713 else
1714 {
1715 m_supports_qThreadStopInfo = false;
1716 }
Greg Claytonb72d0f02011-04-12 05:54:46 +00001717 }
Greg Clayton139da722011-05-20 03:15:54 +00001718// if (SetCurrentThread (tid))
1719// return GetStopReply (response);
Greg Claytonb72d0f02011-04-12 05:54:46 +00001720 return false;
1721}
1722
1723
1724uint8_t
1725GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
1726{
1727 switch (type)
1728 {
1729 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break;
1730 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break;
1731 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
1732 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
1733 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
1734 default: return UINT8_MAX;
1735 }
1736
1737 char packet[64];
1738 const int packet_len = ::snprintf (packet,
1739 sizeof(packet),
1740 "%c%i,%llx,%x",
1741 insert ? 'Z' : 'z',
1742 type,
1743 addr,
1744 length);
1745
1746 assert (packet_len + 1 < sizeof(packet));
1747 StringExtractorGDBRemote response;
1748 if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
1749 {
1750 if (response.IsOKResponse())
1751 return 0;
Greg Claytonb72d0f02011-04-12 05:54:46 +00001752 else if (response.IsErrorResponse())
1753 return response.GetError();
1754 }
Greg Clayton5b53e8e2011-05-15 23:46:54 +00001755 else
1756 {
1757 switch (type)
1758 {
1759 case eBreakpointSoftware: m_supports_z0 = false; break;
1760 case eBreakpointHardware: m_supports_z1 = false; break;
1761 case eWatchpointWrite: m_supports_z2 = false; break;
1762 case eWatchpointRead: m_supports_z3 = false; break;
1763 case eWatchpointReadWrite: m_supports_z4 = false; break;
1764 default: break;
1765 }
1766 }
1767
Greg Claytonb72d0f02011-04-12 05:54:46 +00001768 return UINT8_MAX;
1769}
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001770
1771size_t
1772GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
1773 bool &sequence_mutex_unavailable)
1774{
1775 Mutex::Locker locker;
1776 thread_ids.clear();
1777
1778 if (GetSequenceMutex (locker))
1779 {
1780 sequence_mutex_unavailable = false;
1781 StringExtractorGDBRemote response;
1782
Greg Clayton63afdb02011-06-17 01:22:15 +00001783 for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001784 response.IsNormalResponse();
Greg Clayton63afdb02011-06-17 01:22:15 +00001785 SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()))
Greg Clayton4a60f9e2011-05-20 23:38:13 +00001786 {
1787 char ch = response.GetChar();
1788 if (ch == 'l')
1789 break;
1790 if (ch == 'm')
1791 {
1792 do
1793 {
1794 tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
1795
1796 if (tid != LLDB_INVALID_THREAD_ID)
1797 {
1798 thread_ids.push_back (tid);
1799 }
1800 ch = response.GetChar(); // Skip the command separator
1801 } while (ch == ','); // Make sure we got a comma separator
1802 }
1803 }
1804 }
1805 else
1806 {
1807 sequence_mutex_unavailable = true;
1808 }
1809 return thread_ids.size();
1810}