GDBRemoteCommunicationClient.cpp revision 139da72165577f073c14f2d5b86191e2c7b21d4c
1//===-- 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//---------------------------------------------------------------------- 37GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : 38 GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform), 39 m_supports_not_sending_acks (eLazyBoolCalculate), 40 m_supports_thread_suffix (eLazyBoolCalculate), 41 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), 47 m_qHostInfo_is_valid (eLazyBoolCalculate), 48 m_supports_alloc_dealloc_memory (eLazyBoolCalculate), 49 m_supports_qProcessInfoPID (true), 50 m_supports_qfProcessInfo (true), 51 m_supports_qUserName (true), 52 m_supports_qGroupName (true), 53 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), 61 m_async_mutex (Mutex::eMutexTypeRecursive), 62 m_async_packet_predicate (false), 63 m_async_packet (), 64 m_async_response (), 65 m_async_signal (-1), 66 m_host_arch(), 67 m_os_version_major (UINT32_MAX), 68 m_os_version_minor (UINT32_MAX), 69 m_os_version_update (UINT32_MAX) 70{ 71 m_rx_packet_listener.StartListeningForEvents(this, 72 Communication::eBroadcastBitPacketAvailable | 73 Communication::eBroadcastBitReadThreadDidExit); 74} 75 76//---------------------------------------------------------------------- 77// Destructor 78//---------------------------------------------------------------------- 79GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() 80{ 81 m_rx_packet_listener.StopListeningForEvents(this, 82 Communication::eBroadcastBitPacketAvailable | 83 Communication::eBroadcastBitReadThreadDidExit); 84 if (IsConnected()) 85 { 86 StopReadThread(); 87 Disconnect(); 88 } 89} 90 91bool 92GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr) 93{ 94 // Start the read thread after we send the handshake ack since if we 95 // fail to send the handshake ack, there is no reason to continue... 96 if (SendAck()) 97 return StartReadThread (error_ptr); 98 99 if (error_ptr) 100 error_ptr->SetErrorString("failed to send the handshake ack"); 101 return false; 102} 103 104void 105GDBRemoteCommunicationClient::QueryNoAckModeSupported () 106{ 107 if (m_supports_not_sending_acks == eLazyBoolCalculate) 108 { 109 m_send_acks = true; 110 m_supports_not_sending_acks = eLazyBoolNo; 111 112 StringExtractorGDBRemote response; 113 if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false)) 114 { 115 if (response.IsOKResponse()) 116 { 117 m_send_acks = false; 118 m_supports_not_sending_acks = eLazyBoolYes; 119 } 120 } 121 } 122} 123 124void 125GDBRemoteCommunicationClient::ResetDiscoverableSettings() 126{ 127 m_supports_not_sending_acks = eLazyBoolCalculate; 128 m_supports_thread_suffix = eLazyBoolCalculate; 129 m_supports_vCont_c = eLazyBoolCalculate; 130 m_supports_vCont_C = eLazyBoolCalculate; 131 m_supports_vCont_s = eLazyBoolCalculate; 132 m_supports_vCont_S = eLazyBoolCalculate; 133 m_qHostInfo_is_valid = eLazyBoolCalculate; 134 m_supports_alloc_dealloc_memory = eLazyBoolCalculate; 135 136 m_supports_qProcessInfoPID = true; 137 m_supports_qfProcessInfo = true; 138 m_supports_qUserName = true; 139 m_supports_qGroupName = true; 140 m_supports_qThreadStopInfo = true; 141 m_supports_z0 = true; 142 m_supports_z1 = true; 143 m_supports_z2 = true; 144 m_supports_z3 = true; 145 m_supports_z4 = true; 146 m_host_arch.Clear(); 147} 148 149 150bool 151GDBRemoteCommunicationClient::GetThreadSuffixSupported () 152{ 153 if (m_supports_thread_suffix == eLazyBoolCalculate) 154 { 155 StringExtractorGDBRemote response; 156 m_supports_thread_suffix = eLazyBoolNo; 157 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false)) 158 { 159 if (response.IsOKResponse()) 160 m_supports_thread_suffix = eLazyBoolYes; 161 } 162 } 163 return m_supports_thread_suffix; 164} 165bool 166GDBRemoteCommunicationClient::GetVContSupported (char flavor) 167{ 168 if (m_supports_vCont_c == eLazyBoolCalculate) 169 { 170 StringExtractorGDBRemote response; 171 m_supports_vCont_any = eLazyBoolNo; 172 m_supports_vCont_all = eLazyBoolNo; 173 m_supports_vCont_c = eLazyBoolNo; 174 m_supports_vCont_C = eLazyBoolNo; 175 m_supports_vCont_s = eLazyBoolNo; 176 m_supports_vCont_S = eLazyBoolNo; 177 if (SendPacketAndWaitForResponse("vCont?", response, false)) 178 { 179 const char *response_cstr = response.GetStringRef().c_str(); 180 if (::strstr (response_cstr, ";c")) 181 m_supports_vCont_c = eLazyBoolYes; 182 183 if (::strstr (response_cstr, ";C")) 184 m_supports_vCont_C = eLazyBoolYes; 185 186 if (::strstr (response_cstr, ";s")) 187 m_supports_vCont_s = eLazyBoolYes; 188 189 if (::strstr (response_cstr, ";S")) 190 m_supports_vCont_S = eLazyBoolYes; 191 192 if (m_supports_vCont_c == eLazyBoolYes && 193 m_supports_vCont_C == eLazyBoolYes && 194 m_supports_vCont_s == eLazyBoolYes && 195 m_supports_vCont_S == eLazyBoolYes) 196 { 197 m_supports_vCont_all = eLazyBoolYes; 198 } 199 200 if (m_supports_vCont_c == eLazyBoolYes || 201 m_supports_vCont_C == eLazyBoolYes || 202 m_supports_vCont_s == eLazyBoolYes || 203 m_supports_vCont_S == eLazyBoolYes) 204 { 205 m_supports_vCont_any = eLazyBoolYes; 206 } 207 } 208 } 209 210 switch (flavor) 211 { 212 case 'a': return m_supports_vCont_any; 213 case 'A': return m_supports_vCont_all; 214 case 'c': return m_supports_vCont_c; 215 case 'C': return m_supports_vCont_C; 216 case 's': return m_supports_vCont_s; 217 case 'S': return m_supports_vCont_S; 218 default: break; 219 } 220 return false; 221} 222 223 224size_t 225GDBRemoteCommunicationClient::SendPacketAndWaitForResponse 226( 227 const char *payload, 228 StringExtractorGDBRemote &response, 229 bool send_async 230) 231{ 232 return SendPacketAndWaitForResponse (payload, 233 ::strlen (payload), 234 response, 235 send_async); 236} 237 238size_t 239GDBRemoteCommunicationClient::SendPacketAndWaitForResponse 240( 241 const char *payload, 242 size_t payload_length, 243 StringExtractorGDBRemote &response, 244 bool send_async 245) 246{ 247 Mutex::Locker locker; 248 TimeValue timeout_time; 249 timeout_time = TimeValue::Now(); 250 timeout_time.OffsetWithSeconds (m_packet_timeout); 251 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 252 253 if (GetSequenceMutex (locker)) 254 { 255 if (SendPacketNoLock (payload, payload_length)) 256 return WaitForPacketNoLock (response, &timeout_time); 257 } 258 else 259 { 260 if (send_async) 261 { 262 Mutex::Locker async_locker (m_async_mutex); 263 m_async_packet.assign(payload, payload_length); 264 m_async_packet_predicate.SetValue (true, eBroadcastNever); 265 266 if (log) 267 log->Printf ("async: async packet = %s", m_async_packet.c_str()); 268 269 bool timed_out = false; 270 bool sent_interrupt = false; 271 if (SendInterrupt(locker, 2, sent_interrupt, timed_out)) 272 { 273 if (sent_interrupt) 274 { 275 if (log) 276 log->Printf ("async: sent interrupt"); 277 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out)) 278 { 279 if (log) 280 log->Printf ("async: got response"); 281 response = m_async_response; 282 return response.GetStringRef().size(); 283 } 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 300 // yet we were able to get the loc 301 } 302 } 303 else 304 { 305 if (log) 306 log->Printf ("async: failed to interrupt"); 307 } 308 } 309 else 310 { 311 if (log) 312 log->Printf ("mutex taken and send_async == false, aborting packet"); 313 } 314 } 315 return 0; 316} 317 318//template<typename _Tp> 319//class ScopedValueChanger 320//{ 321//public: 322// // Take a value reference and the value to assign it to when this class 323// // instance goes out of scope. 324// ScopedValueChanger (_Tp &value_ref, _Tp value) : 325// m_value_ref (value_ref), 326// m_value (value) 327// { 328// } 329// 330// // This object is going out of scope, change the value pointed to by 331// // m_value_ref to the value we got during construction which was stored in 332// // m_value; 333// ~ScopedValueChanger () 334// { 335// m_value_ref = m_value; 336// } 337//protected: 338// _Tp &m_value_ref; // A reference to the value we will change when this object destructs 339// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope. 340//}; 341 342StateType 343GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse 344( 345 ProcessGDBRemote *process, 346 const char *payload, 347 size_t packet_length, 348 StringExtractorGDBRemote &response 349) 350{ 351 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 352 if (log) 353 log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__); 354 355 Mutex::Locker locker(m_sequence_mutex); 356 StateType state = eStateRunning; 357 358 BroadcastEvent(eBroadcastBitRunPacketSent, NULL); 359 m_public_is_running.SetValue (true, eBroadcastNever); 360 // Set the starting continue packet into "continue_packet". This packet 361 // make change if we are interrupted and we continue after an async packet... 362 std::string continue_packet(payload, packet_length); 363 364 bool got_stdout = false; 365 366 while (state == eStateRunning) 367 { 368 if (!got_stdout) 369 { 370 if (log) 371 log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str()); 372 if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0) 373 state = eStateInvalid; 374 375 m_private_is_running.SetValue (true, eBroadcastNever); 376 } 377 378 got_stdout = false; 379 380 if (log) 381 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%.*s)", __FUNCTION__); 382 383 if (WaitForPacket (response, (TimeValue*)NULL)) 384 { 385 if (response.Empty()) 386 state = eStateInvalid; 387 else 388 { 389 const char stop_type = response.GetChar(); 390 if (log) 391 log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str()); 392 switch (stop_type) 393 { 394 case 'T': 395 case 'S': 396 if (process->GetStopID() == 0) 397 { 398 if (process->GetID() == LLDB_INVALID_PROCESS_ID) 399 { 400 lldb::pid_t pid = GetCurrentProcessID (); 401 if (pid != LLDB_INVALID_PROCESS_ID) 402 process->SetID (pid); 403 } 404 process->BuildDynamicRegisterInfo (true); 405 } 406 407 // Privately notify any internal threads that we have stopped 408 // in case we wanted to interrupt our process, yet we might 409 // send a packet and continue without returning control to the 410 // user. 411 m_private_is_running.SetValue (false, eBroadcastAlways); 412 if (m_async_signal != -1) 413 { 414 if (log) 415 log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal)); 416 417 // Save off the async signal we are supposed to send 418 const int async_signal = m_async_signal; 419 // Clear the async signal member so we don't end up 420 // sending the signal multiple times... 421 m_async_signal = -1; 422 // Check which signal we stopped with 423 uint8_t signo = response.GetHexU8(255); 424 if (signo == async_signal) 425 { 426 if (log) 427 log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo)); 428 429 // We already stopped with a signal that we wanted 430 // to stop with, so we are done 431 response.SetFilePos (0); 432 } 433 else 434 { 435 // We stopped with a different signal that the one 436 // we wanted to stop with, so now we must resume 437 // with the signal we want 438 char signal_packet[32]; 439 int signal_packet_len = 0; 440 signal_packet_len = ::snprintf (signal_packet, 441 sizeof (signal_packet), 442 "C%2.2x", 443 async_signal); 444 445 if (log) 446 log->Printf ("async: stopped with signal %s, resume with %s", 447 Host::GetSignalAsCString (signo), 448 Host::GetSignalAsCString (async_signal)); 449 450 // Set the continue packet to resume... 451 continue_packet.assign(signal_packet, signal_packet_len); 452 continue; 453 } 454 } 455 else if (m_async_packet_predicate.GetValue()) 456 { 457 // We are supposed to send an asynchronous packet while 458 // we are running. 459 m_async_response.Clear(); 460 if (m_async_packet.empty()) 461 { 462 if (log) 463 log->Printf ("async: error: empty async packet"); 464 465 } 466 else 467 { 468 if (log) 469 log->Printf ("async: sending packet: %s", 470 m_async_packet.c_str()); 471 472 SendPacketAndWaitForResponse (&m_async_packet[0], 473 m_async_packet.size(), 474 m_async_response, 475 false); 476 } 477 // Let the other thread that was trying to send the async 478 // packet know that the packet has been sent and response is 479 // ready... 480 m_async_packet_predicate.SetValue(false, eBroadcastAlways); 481 482 // Set the continue packet to resume... 483 continue_packet.assign (1, 'c'); 484 continue; 485 } 486 // Stop with signal and thread info 487 state = eStateStopped; 488 break; 489 490 case 'W': 491 case 'X': 492 // process exited 493 state = eStateExited; 494 break; 495 496 case 'O': 497 // STDOUT 498 { 499 got_stdout = true; 500 std::string inferior_stdout; 501 inferior_stdout.reserve(response.GetBytesLeft () / 2); 502 char ch; 503 while ((ch = response.GetHexU8()) != '\0') 504 inferior_stdout.append(1, ch); 505 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size()); 506 } 507 break; 508 509 case 'E': 510 // ERROR 511 state = eStateInvalid; 512 break; 513 514 default: 515 if (log) 516 log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__); 517 state = eStateInvalid; 518 break; 519 } 520 } 521 } 522 else 523 { 524 if (log) 525 log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__); 526 state = eStateInvalid; 527 } 528 } 529 if (log) 530 log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state)); 531 response.SetFilePos(0); 532 m_private_is_running.SetValue (false, eBroadcastAlways); 533 m_public_is_running.SetValue (false, eBroadcastAlways); 534 return state; 535} 536 537bool 538GDBRemoteCommunicationClient::SendAsyncSignal (int signo) 539{ 540 m_async_signal = signo; 541 bool timed_out = false; 542 bool sent_interrupt = false; 543 Mutex::Locker locker; 544 if (SendInterrupt (locker, 1, sent_interrupt, timed_out)) 545 return true; 546 m_async_signal = -1; 547 return false; 548} 549 550// This function takes a mutex locker as a parameter in case the GetSequenceMutex 551// actually succeeds. If it doesn't succeed in acquiring the sequence mutex 552// (the expected result), then it will send the halt packet. If it does succeed 553// then the caller that requested the interrupt will want to keep the sequence 554// locked down so that no one else can send packets while the caller has control. 555// This function usually gets called when we are running and need to stop the 556// target. It can also be used when we are running and and we need to do something 557// else (like read/write memory), so we need to interrupt the running process 558// (gdb remote protocol requires this), and do what we need to do, then resume. 559 560bool 561GDBRemoteCommunicationClient::SendInterrupt 562( 563 Mutex::Locker& locker, 564 uint32_t seconds_to_wait_for_stop, 565 bool &sent_interrupt, 566 bool &timed_out 567) 568{ 569 sent_interrupt = false; 570 timed_out = false; 571 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 572 573 if (IsRunning()) 574 { 575 // Only send an interrupt if our debugserver is running... 576 if (GetSequenceMutex (locker) == false) 577 { 578 // Someone has the mutex locked waiting for a response or for the 579 // inferior to stop, so send the interrupt on the down low... 580 char ctrl_c = '\x03'; 581 ConnectionStatus status = eConnectionStatusSuccess; 582 TimeValue timeout; 583 if (seconds_to_wait_for_stop) 584 { 585 timeout = TimeValue::Now(); 586 timeout.OffsetWithSeconds (seconds_to_wait_for_stop); 587 } 588 size_t bytes_written = Write (&ctrl_c, 1, status, NULL); 589 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03"); 590 if (bytes_written > 0) 591 { 592 sent_interrupt = true; 593 if (seconds_to_wait_for_stop) 594 { 595 if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out)) 596 { 597 if (log) 598 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, private state stopped", __FUNCTION__); 599 return true; 600 } 601 else 602 { 603 if (log) 604 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__); 605 } 606 } 607 else 608 { 609 if (log) 610 log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, not waiting for stop...", __FUNCTION__); 611 return true; 612 } 613 } 614 else 615 { 616 if (log) 617 log->Printf ("GDBRemoteCommunicationClient::%s () - failed to write interrupt", __FUNCTION__); 618 } 619 return false; 620 } 621 else 622 { 623 if (log) 624 log->Printf ("GDBRemoteCommunicationClient::%s () - got sequence mutex without having to interrupt", __FUNCTION__); 625 } 626 } 627 return true; 628} 629 630lldb::pid_t 631GDBRemoteCommunicationClient::GetCurrentProcessID () 632{ 633 StringExtractorGDBRemote response; 634 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false)) 635 { 636 if (response.GetChar() == 'Q') 637 if (response.GetChar() == 'C') 638 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID); 639 } 640 return LLDB_INVALID_PROCESS_ID; 641} 642 643bool 644GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str) 645{ 646 error_str.clear(); 647 StringExtractorGDBRemote response; 648 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false)) 649 { 650 if (response.IsOKResponse()) 651 return true; 652 if (response.GetChar() == 'E') 653 { 654 // A string the describes what failed when launching... 655 error_str = response.GetStringRef().substr(1); 656 } 657 else 658 { 659 error_str.assign ("unknown error occurred launching process"); 660 } 661 } 662 else 663 { 664 error_str.assign ("failed to send the qLaunchSuccess packet"); 665 } 666 return false; 667} 668 669int 670GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[]) 671{ 672 if (argv && argv[0]) 673 { 674 StreamString packet; 675 packet.PutChar('A'); 676 const char *arg; 677 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i) 678 { 679 const int arg_len = strlen(arg); 680 if (i > 0) 681 packet.PutChar(','); 682 packet.Printf("%i,%i,", arg_len * 2, i); 683 packet.PutBytesAsRawHex8 (arg, arg_len); 684 } 685 686 StringExtractorGDBRemote response; 687 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) 688 { 689 if (response.IsOKResponse()) 690 return 0; 691 uint8_t error = response.GetError(); 692 if (error) 693 return error; 694 } 695 } 696 return -1; 697} 698 699int 700GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value) 701{ 702 if (name_equal_value && name_equal_value[0]) 703 { 704 StreamString packet; 705 packet.Printf("QEnvironment:%s", name_equal_value); 706 StringExtractorGDBRemote response; 707 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) 708 { 709 if (response.IsOKResponse()) 710 return 0; 711 uint8_t error = response.GetError(); 712 if (error) 713 return error; 714 } 715 } 716 return -1; 717} 718 719int 720GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch) 721{ 722 if (arch && arch[0]) 723 { 724 StreamString packet; 725 packet.Printf("QLaunchArch:%s", arch); 726 StringExtractorGDBRemote response; 727 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) 728 { 729 if (response.IsOKResponse()) 730 return 0; 731 uint8_t error = response.GetError(); 732 if (error) 733 return error; 734 } 735 } 736 return -1; 737} 738 739bool 740GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major, 741 uint32_t &minor, 742 uint32_t &update) 743{ 744 if (GetHostInfo ()) 745 { 746 if (m_os_version_major != UINT32_MAX) 747 { 748 major = m_os_version_major; 749 minor = m_os_version_minor; 750 update = m_os_version_update; 751 return true; 752 } 753 } 754 return false; 755} 756 757bool 758GDBRemoteCommunicationClient::GetOSBuildString (std::string &s) 759{ 760 if (GetHostInfo ()) 761 { 762 if (!m_os_build.empty()) 763 { 764 s = m_os_build; 765 return true; 766 } 767 } 768 s.clear(); 769 return false; 770} 771 772 773bool 774GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s) 775{ 776 if (GetHostInfo ()) 777 { 778 if (!m_os_kernel.empty()) 779 { 780 s = m_os_kernel; 781 return true; 782 } 783 } 784 s.clear(); 785 return false; 786} 787 788bool 789GDBRemoteCommunicationClient::GetHostname (std::string &s) 790{ 791 if (GetHostInfo ()) 792 { 793 if (!m_hostname.empty()) 794 { 795 s = m_hostname; 796 return true; 797 } 798 } 799 s.clear(); 800 return false; 801} 802 803ArchSpec 804GDBRemoteCommunicationClient::GetSystemArchitecture () 805{ 806 if (GetHostInfo ()) 807 return m_host_arch; 808 return ArchSpec(); 809} 810 811 812bool 813GDBRemoteCommunicationClient::GetHostInfo (bool force) 814{ 815 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) 816 { 817 m_qHostInfo_is_valid = eLazyBoolNo; 818 StringExtractorGDBRemote response; 819 if (SendPacketAndWaitForResponse ("qHostInfo", response, false)) 820 { 821 if (response.IsNormalResponse()) 822 { 823 std::string name; 824 std::string value; 825 uint32_t cpu = LLDB_INVALID_CPUTYPE; 826 uint32_t sub = 0; 827 std::string arch_name; 828 std::string os_name; 829 std::string vendor_name; 830 std::string triple; 831 uint32_t pointer_byte_size = 0; 832 StringExtractor extractor; 833 ByteOrder byte_order = eByteOrderInvalid; 834 uint32_t num_keys_decoded = 0; 835 while (response.GetNameColonValue(name, value)) 836 { 837 if (name.compare("cputype") == 0) 838 { 839 // exception type in big endian hex 840 cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0); 841 if (cpu != LLDB_INVALID_CPUTYPE) 842 ++num_keys_decoded; 843 } 844 else if (name.compare("cpusubtype") == 0) 845 { 846 // exception count in big endian hex 847 sub = Args::StringToUInt32 (value.c_str(), 0, 0); 848 if (sub != 0) 849 ++num_keys_decoded; 850 } 851 else if (name.compare("arch") == 0) 852 { 853 arch_name.swap (value); 854 ++num_keys_decoded; 855 } 856 else if (name.compare("triple") == 0) 857 { 858 // The triple comes as ASCII hex bytes since it contains '-' chars 859 extractor.GetStringRef().swap(value); 860 extractor.SetFilePos(0); 861 extractor.GetHexByteString (triple); 862 ++num_keys_decoded; 863 } 864 else if (name.compare("os_build") == 0) 865 { 866 extractor.GetStringRef().swap(value); 867 extractor.SetFilePos(0); 868 extractor.GetHexByteString (m_os_build); 869 ++num_keys_decoded; 870 } 871 else if (name.compare("hostname") == 0) 872 { 873 extractor.GetStringRef().swap(value); 874 extractor.SetFilePos(0); 875 extractor.GetHexByteString (m_hostname); 876 ++num_keys_decoded; 877 } 878 else if (name.compare("os_kernel") == 0) 879 { 880 extractor.GetStringRef().swap(value); 881 extractor.SetFilePos(0); 882 extractor.GetHexByteString (m_os_kernel); 883 ++num_keys_decoded; 884 } 885 else if (name.compare("ostype") == 0) 886 { 887 os_name.swap (value); 888 ++num_keys_decoded; 889 } 890 else if (name.compare("vendor") == 0) 891 { 892 vendor_name.swap(value); 893 ++num_keys_decoded; 894 } 895 else if (name.compare("endian") == 0) 896 { 897 ++num_keys_decoded; 898 if (value.compare("little") == 0) 899 byte_order = eByteOrderLittle; 900 else if (value.compare("big") == 0) 901 byte_order = eByteOrderBig; 902 else if (value.compare("pdp") == 0) 903 byte_order = eByteOrderPDP; 904 else 905 --num_keys_decoded; 906 } 907 else if (name.compare("ptrsize") == 0) 908 { 909 pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0); 910 if (pointer_byte_size != 0) 911 ++num_keys_decoded; 912 } 913 else if (name.compare("os_version") == 0) 914 { 915 Args::StringToVersion (value.c_str(), 916 m_os_version_major, 917 m_os_version_minor, 918 m_os_version_update); 919 if (m_os_version_major != UINT32_MAX) 920 ++num_keys_decoded; 921 } 922 } 923 924 if (num_keys_decoded > 0) 925 m_qHostInfo_is_valid = eLazyBoolYes; 926 927 if (triple.empty()) 928 { 929 if (arch_name.empty()) 930 { 931 if (cpu != LLDB_INVALID_CPUTYPE) 932 { 933 m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub); 934 if (pointer_byte_size) 935 { 936 assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); 937 } 938 if (byte_order != eByteOrderInvalid) 939 { 940 assert (byte_order == m_host_arch.GetByteOrder()); 941 } 942 if (!vendor_name.empty()) 943 m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name)); 944 if (!os_name.empty()) 945 m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name)); 946 947 } 948 } 949 else 950 { 951 std::string triple; 952 triple += arch_name; 953 triple += '-'; 954 if (vendor_name.empty()) 955 triple += "unknown"; 956 else 957 triple += vendor_name; 958 triple += '-'; 959 if (os_name.empty()) 960 triple += "unknown"; 961 else 962 triple += os_name; 963 m_host_arch.SetTriple (triple.c_str(), NULL); 964 if (pointer_byte_size) 965 { 966 assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); 967 } 968 if (byte_order != eByteOrderInvalid) 969 { 970 assert (byte_order == m_host_arch.GetByteOrder()); 971 } 972 973 } 974 } 975 else 976 { 977 m_host_arch.SetTriple (triple.c_str(), NULL); 978 if (pointer_byte_size) 979 { 980 assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); 981 } 982 if (byte_order != eByteOrderInvalid) 983 { 984 assert (byte_order == m_host_arch.GetByteOrder()); 985 } 986 } 987 } 988 } 989 } 990 return m_qHostInfo_is_valid == eLazyBoolYes; 991} 992 993int 994GDBRemoteCommunicationClient::SendAttach 995( 996 lldb::pid_t pid, 997 StringExtractorGDBRemote& response 998) 999{ 1000 if (pid != LLDB_INVALID_PROCESS_ID) 1001 { 1002 char packet[64]; 1003 const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", pid); 1004 assert (packet_len < sizeof(packet)); 1005 if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) 1006 { 1007 if (response.IsErrorResponse()) 1008 return response.GetError(); 1009 return 0; 1010 } 1011 } 1012 return -1; 1013} 1014 1015const lldb_private::ArchSpec & 1016GDBRemoteCommunicationClient::GetHostArchitecture () 1017{ 1018 if (m_qHostInfo_is_valid == eLazyBoolCalculate) 1019 GetHostInfo (); 1020 return m_host_arch; 1021} 1022 1023addr_t 1024GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions) 1025{ 1026 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) 1027 { 1028 m_supports_alloc_dealloc_memory = eLazyBoolYes; 1029 char packet[64]; 1030 const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size, 1031 permissions & lldb::ePermissionsReadable ? "r" : "", 1032 permissions & lldb::ePermissionsWritable ? "w" : "", 1033 permissions & lldb::ePermissionsExecutable ? "x" : ""); 1034 assert (packet_len < sizeof(packet)); 1035 StringExtractorGDBRemote response; 1036 if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) 1037 { 1038 if (!response.IsErrorResponse()) 1039 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); 1040 } 1041 else 1042 { 1043 m_supports_alloc_dealloc_memory = eLazyBoolNo; 1044 } 1045 } 1046 return LLDB_INVALID_ADDRESS; 1047} 1048 1049bool 1050GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr) 1051{ 1052 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) 1053 { 1054 m_supports_alloc_dealloc_memory = eLazyBoolYes; 1055 char packet[64]; 1056 const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr); 1057 assert (packet_len < sizeof(packet)); 1058 StringExtractorGDBRemote response; 1059 if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) 1060 { 1061 if (response.IsOKResponse()) 1062 return true; 1063 } 1064 else 1065 { 1066 m_supports_alloc_dealloc_memory = eLazyBoolNo; 1067 } 1068 } 1069 return false; 1070} 1071 1072int 1073GDBRemoteCommunicationClient::SetSTDIN (char const *path) 1074{ 1075 if (path && path[0]) 1076 { 1077 StreamString packet; 1078 packet.PutCString("QSetSTDIN:"); 1079 packet.PutBytesAsRawHex8(path, strlen(path)); 1080 1081 StringExtractorGDBRemote response; 1082 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) 1083 { 1084 if (response.IsOKResponse()) 1085 return 0; 1086 uint8_t error = response.GetError(); 1087 if (error) 1088 return error; 1089 } 1090 } 1091 return -1; 1092} 1093 1094int 1095GDBRemoteCommunicationClient::SetSTDOUT (char const *path) 1096{ 1097 if (path && path[0]) 1098 { 1099 StreamString packet; 1100 packet.PutCString("QSetSTDOUT:"); 1101 packet.PutBytesAsRawHex8(path, strlen(path)); 1102 1103 StringExtractorGDBRemote response; 1104 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) 1105 { 1106 if (response.IsOKResponse()) 1107 return 0; 1108 uint8_t error = response.GetError(); 1109 if (error) 1110 return error; 1111 } 1112 } 1113 return -1; 1114} 1115 1116int 1117GDBRemoteCommunicationClient::SetSTDERR (char const *path) 1118{ 1119 if (path && path[0]) 1120 { 1121 StreamString packet; 1122 packet.PutCString("QSetSTDERR:"); 1123 packet.PutBytesAsRawHex8(path, strlen(path)); 1124 1125 StringExtractorGDBRemote response; 1126 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) 1127 { 1128 if (response.IsOKResponse()) 1129 return 0; 1130 uint8_t error = response.GetError(); 1131 if (error) 1132 return error; 1133 } 1134 } 1135 return -1; 1136} 1137 1138int 1139GDBRemoteCommunicationClient::SetWorkingDir (char const *path) 1140{ 1141 if (path && path[0]) 1142 { 1143 StreamString packet; 1144 packet.PutCString("QSetWorkingDir:"); 1145 packet.PutBytesAsRawHex8(path, strlen(path)); 1146 1147 StringExtractorGDBRemote response; 1148 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) 1149 { 1150 if (response.IsOKResponse()) 1151 return 0; 1152 uint8_t error = response.GetError(); 1153 if (error) 1154 return error; 1155 } 1156 } 1157 return -1; 1158} 1159 1160int 1161GDBRemoteCommunicationClient::SetDisableASLR (bool enable) 1162{ 1163 char packet[32]; 1164 const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0); 1165 assert (packet_len < sizeof(packet)); 1166 StringExtractorGDBRemote response; 1167 if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) 1168 { 1169 if (response.IsOKResponse()) 1170 return 0; 1171 uint8_t error = response.GetError(); 1172 if (error) 1173 return error; 1174 } 1175 return -1; 1176} 1177 1178bool 1179GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) 1180{ 1181 if (response.IsNormalResponse()) 1182 { 1183 std::string name; 1184 std::string value; 1185 StringExtractor extractor; 1186 1187 while (response.GetNameColonValue(name, value)) 1188 { 1189 if (name.compare("pid") == 0) 1190 { 1191 process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0)); 1192 } 1193 else if (name.compare("ppid") == 0) 1194 { 1195 process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0)); 1196 } 1197 else if (name.compare("uid") == 0) 1198 { 1199 process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); 1200 } 1201 else if (name.compare("euid") == 0) 1202 { 1203 process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); 1204 } 1205 else if (name.compare("gid") == 0) 1206 { 1207 process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); 1208 } 1209 else if (name.compare("egid") == 0) 1210 { 1211 process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); 1212 } 1213 else if (name.compare("triple") == 0) 1214 { 1215 // The triple comes as ASCII hex bytes since it contains '-' chars 1216 extractor.GetStringRef().swap(value); 1217 extractor.SetFilePos(0); 1218 extractor.GetHexByteString (value); 1219 process_info.GetArchitecture ().SetTriple (value.c_str(), NULL); 1220 } 1221 else if (name.compare("name") == 0) 1222 { 1223 StringExtractor extractor; 1224 // The the process name from ASCII hex bytes since we can't 1225 // control the characters in a process name 1226 extractor.GetStringRef().swap(value); 1227 extractor.SetFilePos(0); 1228 extractor.GetHexByteString (value); 1229 process_info.SetName (value.c_str()); 1230 } 1231 } 1232 1233 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 1234 return true; 1235 } 1236 return false; 1237} 1238 1239bool 1240GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 1241{ 1242 process_info.Clear(); 1243 1244 if (m_supports_qProcessInfoPID) 1245 { 1246 char packet[32]; 1247 const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%i", pid); 1248 assert (packet_len < sizeof(packet)); 1249 StringExtractorGDBRemote response; 1250 if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) 1251 { 1252 return DecodeProcessInfoResponse (response, process_info); 1253 } 1254 else 1255 { 1256 m_supports_qProcessInfoPID = false; 1257 return false; 1258 } 1259 } 1260 return false; 1261} 1262 1263uint32_t 1264GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info, 1265 ProcessInstanceInfoList &process_infos) 1266{ 1267 process_infos.Clear(); 1268 1269 if (m_supports_qfProcessInfo) 1270 { 1271 StreamString packet; 1272 packet.PutCString ("qfProcessInfo"); 1273 if (!match_info.MatchAllProcesses()) 1274 { 1275 packet.PutChar (':'); 1276 const char *name = match_info.GetProcessInfo().GetName(); 1277 bool has_name_match = false; 1278 if (name && name[0]) 1279 { 1280 has_name_match = true; 1281 NameMatchType name_match_type = match_info.GetNameMatchType(); 1282 switch (name_match_type) 1283 { 1284 case eNameMatchIgnore: 1285 has_name_match = false; 1286 break; 1287 1288 case eNameMatchEquals: 1289 packet.PutCString ("name_match:equals;"); 1290 break; 1291 1292 case eNameMatchContains: 1293 packet.PutCString ("name_match:contains;"); 1294 break; 1295 1296 case eNameMatchStartsWith: 1297 packet.PutCString ("name_match:starts_with;"); 1298 break; 1299 1300 case eNameMatchEndsWith: 1301 packet.PutCString ("name_match:ends_with;"); 1302 break; 1303 1304 case eNameMatchRegularExpression: 1305 packet.PutCString ("name_match:regex;"); 1306 break; 1307 } 1308 if (has_name_match) 1309 { 1310 packet.PutCString ("name:"); 1311 packet.PutBytesAsRawHex8(name, ::strlen(name)); 1312 packet.PutChar (';'); 1313 } 1314 } 1315 1316 if (match_info.GetProcessInfo().ProcessIDIsValid()) 1317 packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID()); 1318 if (match_info.GetProcessInfo().ParentProcessIDIsValid()) 1319 packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID()); 1320 if (match_info.GetProcessInfo().UserIDIsValid()) 1321 packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID()); 1322 if (match_info.GetProcessInfo().GroupIDIsValid()) 1323 packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID()); 1324 if (match_info.GetProcessInfo().EffectiveUserIDIsValid()) 1325 packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID()); 1326 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) 1327 packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID()); 1328 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) 1329 packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0); 1330 if (match_info.GetProcessInfo().GetArchitecture().IsValid()) 1331 { 1332 const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture(); 1333 const llvm::Triple &triple = match_arch.GetTriple(); 1334 packet.PutCString("triple:"); 1335 packet.PutCStringAsRawHex8(triple.getTriple().c_str()); 1336 packet.PutChar (';'); 1337 } 1338 } 1339 StringExtractorGDBRemote response; 1340 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) 1341 { 1342 do 1343 { 1344 ProcessInstanceInfo process_info; 1345 if (!DecodeProcessInfoResponse (response, process_info)) 1346 break; 1347 process_infos.Append(process_info); 1348 response.GetStringRef().clear(); 1349 response.SetFilePos(0); 1350 } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false)); 1351 } 1352 else 1353 { 1354 m_supports_qfProcessInfo = false; 1355 return 0; 1356 } 1357 } 1358 return process_infos.GetSize(); 1359 1360} 1361 1362bool 1363GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name) 1364{ 1365 if (m_supports_qUserName) 1366 { 1367 char packet[32]; 1368 const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid); 1369 assert (packet_len < sizeof(packet)); 1370 StringExtractorGDBRemote response; 1371 if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) 1372 { 1373 if (response.IsNormalResponse()) 1374 { 1375 // Make sure we parsed the right number of characters. The response is 1376 // the hex encoded user name and should make up the entire packet. 1377 // If there are any non-hex ASCII bytes, the length won't match below.. 1378 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size()) 1379 return true; 1380 } 1381 } 1382 else 1383 { 1384 m_supports_qUserName = false; 1385 return false; 1386 } 1387 } 1388 return false; 1389 1390} 1391 1392bool 1393GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name) 1394{ 1395 if (m_supports_qGroupName) 1396 { 1397 char packet[32]; 1398 const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid); 1399 assert (packet_len < sizeof(packet)); 1400 StringExtractorGDBRemote response; 1401 if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) 1402 { 1403 if (response.IsNormalResponse()) 1404 { 1405 // Make sure we parsed the right number of characters. The response is 1406 // the hex encoded group name and should make up the entire packet. 1407 // If there are any non-hex ASCII bytes, the length won't match below.. 1408 if (response.GetHexByteString (name) * 2 == response.GetStringRef().size()) 1409 return true; 1410 } 1411 } 1412 else 1413 { 1414 m_supports_qGroupName = false; 1415 return false; 1416 } 1417 } 1418 return false; 1419} 1420 1421void 1422GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets) 1423{ 1424 uint32_t i; 1425 TimeValue start_time, end_time; 1426 uint64_t total_time_nsec; 1427 float packets_per_second; 1428 if (SendSpeedTestPacket (0, 0)) 1429 { 1430 for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2) 1431 { 1432 for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2) 1433 { 1434 start_time = TimeValue::Now(); 1435 for (i=0; i<num_packets; ++i) 1436 { 1437 SendSpeedTestPacket (send_size, recv_size); 1438 } 1439 end_time = TimeValue::Now(); 1440 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970(); 1441 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecondPerSecond; 1442 printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%09.9llu sec for %f packets/sec.\n", 1443 num_packets, 1444 send_size, 1445 recv_size, 1446 total_time_nsec / TimeValue::NanoSecondPerSecond, 1447 total_time_nsec % TimeValue::NanoSecondPerSecond, 1448 packets_per_second); 1449 if (recv_size == 0) 1450 recv_size = 32; 1451 } 1452 if (send_size == 0) 1453 send_size = 32; 1454 } 1455 } 1456 else 1457 { 1458 start_time = TimeValue::Now(); 1459 for (i=0; i<num_packets; ++i) 1460 { 1461 GetCurrentProcessID (); 1462 } 1463 end_time = TimeValue::Now(); 1464 total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970(); 1465 packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecondPerSecond; 1466 printf ("%u 'qC' packets packets in 0x%llu%09.9llu sec for %f packets/sec.\n", 1467 num_packets, 1468 total_time_nsec / TimeValue::NanoSecondPerSecond, 1469 total_time_nsec % TimeValue::NanoSecondPerSecond, 1470 packets_per_second); 1471 } 1472} 1473 1474bool 1475GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size) 1476{ 1477 StreamString packet; 1478 packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size); 1479 uint32_t bytes_left = send_size; 1480 while (bytes_left > 0) 1481 { 1482 if (bytes_left >= 26) 1483 { 1484 packet.PutCString("abcdefghijklmnopqrstuvwxyz"); 1485 bytes_left -= 26; 1486 } 1487 else 1488 { 1489 packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz"); 1490 bytes_left = 0; 1491 } 1492 } 1493 1494 StringExtractorGDBRemote response; 1495 return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0; 1496 return false; 1497} 1498 1499uint16_t 1500GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort () 1501{ 1502 StringExtractorGDBRemote response; 1503 if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false)) 1504 { 1505 std::string name; 1506 std::string value; 1507 uint16_t port = 0; 1508 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 1509 while (response.GetNameColonValue(name, value)) 1510 { 1511 if (name.size() == 4 && name.compare("port") == 0) 1512 port = Args::StringToUInt32(value.c_str(), 0, 0); 1513 if (name.size() == 3 && name.compare("pid") == 0) 1514 pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0); 1515 } 1516 return port; 1517 } 1518 return 0; 1519} 1520 1521bool 1522GDBRemoteCommunicationClient::SetCurrentThread (int tid) 1523{ 1524 if (m_curr_tid == tid) 1525 return true; 1526 1527 char packet[32]; 1528 int packet_len; 1529 if (tid <= 0) 1530 packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid); 1531 else 1532 packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid); 1533 assert (packet_len + 1 < sizeof(packet)); 1534 StringExtractorGDBRemote response; 1535 if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) 1536 { 1537 if (response.IsOKResponse()) 1538 { 1539 m_curr_tid = tid; 1540 return true; 1541 } 1542 } 1543 return false; 1544} 1545 1546bool 1547GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid) 1548{ 1549 if (m_curr_tid_run == tid) 1550 return true; 1551 1552 char packet[32]; 1553 int packet_len; 1554 if (tid <= 0) 1555 packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid); 1556 else 1557 packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid); 1558 1559 assert (packet_len + 1 < sizeof(packet)); 1560 StringExtractorGDBRemote response; 1561 if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) 1562 { 1563 if (response.IsOKResponse()) 1564 { 1565 m_curr_tid_run = tid; 1566 return true; 1567 } 1568 } 1569 return false; 1570} 1571 1572bool 1573GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response) 1574{ 1575 if (SendPacketAndWaitForResponse("?", 1, response, false)) 1576 return response.IsNormalResponse(); 1577 return false; 1578} 1579 1580bool 1581GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response) 1582{ 1583 if (m_supports_qThreadStopInfo) 1584 { 1585 char packet[256]; 1586 int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid); 1587 assert (packet_len < sizeof(packet)); 1588 if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) 1589 { 1590 if (response.IsNormalResponse()) 1591 return true; 1592 else 1593 return false; 1594 } 1595 else 1596 { 1597 m_supports_qThreadStopInfo = false; 1598 } 1599 } 1600// if (SetCurrentThread (tid)) 1601// return GetStopReply (response); 1602 return false; 1603} 1604 1605 1606uint8_t 1607GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length) 1608{ 1609 switch (type) 1610 { 1611 case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break; 1612 case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break; 1613 case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break; 1614 case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break; 1615 case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break; 1616 default: return UINT8_MAX; 1617 } 1618 1619 char packet[64]; 1620 const int packet_len = ::snprintf (packet, 1621 sizeof(packet), 1622 "%c%i,%llx,%x", 1623 insert ? 'Z' : 'z', 1624 type, 1625 addr, 1626 length); 1627 1628 assert (packet_len + 1 < sizeof(packet)); 1629 StringExtractorGDBRemote response; 1630 if (SendPacketAndWaitForResponse(packet, packet_len, response, true)) 1631 { 1632 if (response.IsOKResponse()) 1633 return 0; 1634 else if (response.IsErrorResponse()) 1635 return response.GetError(); 1636 } 1637 else 1638 { 1639 switch (type) 1640 { 1641 case eBreakpointSoftware: m_supports_z0 = false; break; 1642 case eBreakpointHardware: m_supports_z1 = false; break; 1643 case eWatchpointWrite: m_supports_z2 = false; break; 1644 case eWatchpointRead: m_supports_z3 = false; break; 1645 case eWatchpointReadWrite: m_supports_z4 = false; break; 1646 default: break; 1647 } 1648 } 1649 1650 return UINT8_MAX; 1651} 1652