1 //===-- GDBRemoteCommunicationServer.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 "GDBRemoteCommunicationServer.h" 12 #include "lldb/Core/StreamGDBRemote.h" 13 14 // C Includes 15 // C++ Includes 16 // Other libraries and framework includes 17 #include "llvm/ADT/Triple.h" 18 #include "lldb/Interpreter/Args.h" 19 #include "lldb/Core/ConnectionFileDescriptor.h" 20 #include "lldb/Core/Log.h" 21 #include "lldb/Core/State.h" 22 #include "lldb/Core/StreamString.h" 23 #include "lldb/Host/Endian.h" 24 #include "lldb/Host/File.h" 25 #include "lldb/Host/Host.h" 26 #include "lldb/Host/TimeValue.h" 27 #include "lldb/Target/Process.h" 28 29 // Project includes 30 #include "Utility/StringExtractorGDBRemote.h" 31 #include "ProcessGDBRemote.h" 32 #include "ProcessGDBRemoteLog.h" 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 //---------------------------------------------------------------------- 38 // GDBRemoteCommunicationServer constructor 39 //---------------------------------------------------------------------- 40 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) : 41 GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform), 42 m_async_thread (LLDB_INVALID_HOST_THREAD), 43 m_process_launch_info (), 44 m_process_launch_error (), 45 m_spawned_pids (), 46 m_spawned_pids_mutex (Mutex::eMutexTypeRecursive), 47 m_proc_infos (), 48 m_proc_infos_index (0), 49 m_lo_port_num (0), 50 m_hi_port_num (0), 51 m_next_port (0), 52 m_use_port_range (false) 53 { 54 // We seldom need to override the port number that the debugserver process 55 // starts with. We just pass in 0 to let the system choose a random port. 56 // In rare situation where the need arises, use two environment variables 57 // to override. 58 uint16_t lo_port_num = 0; 59 uint16_t hi_port_num = 0; 60 const char *lo_port_c_str = getenv("LLDB_PLATFORM_START_DEBUG_SERVER_LO_PORT"); 61 if (lo_port_c_str) 62 lo_port_num = ::atoi(lo_port_c_str); 63 const char *hi_port_c_str = getenv("LLDB_PLATFORM_START_DEBUG_SERVER_HI_PORT"); 64 if (hi_port_c_str) 65 hi_port_num = ::atoi(hi_port_c_str); 66 if (lo_port_num && hi_port_num && lo_port_num < hi_port_num) 67 { 68 SetPortRange(lo_port_num, hi_port_num); 69 } 70 } 71 72 //---------------------------------------------------------------------- 73 // Destructor 74 //---------------------------------------------------------------------- 75 GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() 76 { 77 } 78 79 80 //void * 81 //GDBRemoteCommunicationServer::AsyncThread (void *arg) 82 //{ 83 // GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg; 84 // 85 // Log *log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 86 // if (log) 87 // log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID()); 88 // 89 // StringExtractorGDBRemote packet; 90 // 91 // while () 92 // { 93 // if (packet. 94 // } 95 // 96 // if (log) 97 // log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID()); 98 // 99 // process->m_async_thread = LLDB_INVALID_HOST_THREAD; 100 // return NULL; 101 //} 102 // 103 bool 104 GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec, 105 Error &error, 106 bool &interrupt, 107 bool &quit) 108 { 109 StringExtractorGDBRemote packet; 110 if (WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec)) 111 { 112 const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType (); 113 switch (packet_type) 114 { 115 case StringExtractorGDBRemote::eServerPacketType_nack: 116 case StringExtractorGDBRemote::eServerPacketType_ack: 117 break; 118 119 case StringExtractorGDBRemote::eServerPacketType_invalid: 120 error.SetErrorString("invalid packet"); 121 quit = true; 122 break; 123 124 case StringExtractorGDBRemote::eServerPacketType_interrupt: 125 error.SetErrorString("interrupt received"); 126 interrupt = true; 127 break; 128 129 case StringExtractorGDBRemote::eServerPacketType_unimplemented: 130 return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0; 131 132 case StringExtractorGDBRemote::eServerPacketType_A: 133 return Handle_A (packet); 134 135 case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo: 136 return Handle_qfProcessInfo (packet); 137 138 case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo: 139 return Handle_qsProcessInfo (packet); 140 141 case StringExtractorGDBRemote::eServerPacketType_qC: 142 return Handle_qC (packet); 143 144 case StringExtractorGDBRemote::eServerPacketType_qHostInfo: 145 return Handle_qHostInfo (packet); 146 147 case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer: 148 return Handle_qLaunchGDBServer (packet); 149 150 case StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess: 151 return Handle_qKillSpawnedProcess (packet); 152 153 case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess: 154 return Handle_qLaunchSuccess (packet); 155 156 case StringExtractorGDBRemote::eServerPacketType_qGroupName: 157 return Handle_qGroupName (packet); 158 159 case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID: 160 return Handle_qProcessInfoPID (packet); 161 162 case StringExtractorGDBRemote::eServerPacketType_qSpeedTest: 163 return Handle_qSpeedTest (packet); 164 165 case StringExtractorGDBRemote::eServerPacketType_qUserName: 166 return Handle_qUserName (packet); 167 168 case StringExtractorGDBRemote::eServerPacketType_QEnvironment: 169 return Handle_QEnvironment (packet); 170 171 case StringExtractorGDBRemote::eServerPacketType_QLaunchArch: 172 return Handle_QLaunchArch (packet); 173 174 case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR: 175 return Handle_QSetDisableASLR (packet); 176 177 case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN: 178 return Handle_QSetSTDIN (packet); 179 180 case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT: 181 return Handle_QSetSTDOUT (packet); 182 183 case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR: 184 return Handle_QSetSTDERR (packet); 185 186 case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir: 187 return Handle_QSetWorkingDir (packet); 188 189 case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode: 190 return Handle_QStartNoAckMode (packet); 191 192 case StringExtractorGDBRemote::eServerPacketType_qPlatform_IO_MkDir: 193 return Handle_qPlatform_IO_MkDir (packet); 194 195 case StringExtractorGDBRemote::eServerPacketType_qPlatform_RunCommand: 196 return Handle_qPlatform_RunCommand (packet); 197 198 case StringExtractorGDBRemote::eServerPacketType_vFile_Open: 199 return Handle_vFile_Open (packet); 200 201 case StringExtractorGDBRemote::eServerPacketType_vFile_Close: 202 return Handle_vFile_Close (packet); 203 204 case StringExtractorGDBRemote::eServerPacketType_vFile_pRead: 205 return Handle_vFile_pRead (packet); 206 207 case StringExtractorGDBRemote::eServerPacketType_vFile_pWrite: 208 return Handle_vFile_pWrite (packet); 209 210 case StringExtractorGDBRemote::eServerPacketType_vFile_Size: 211 return Handle_vFile_Size (packet); 212 213 case StringExtractorGDBRemote::eServerPacketType_vFile_Mode: 214 return Handle_vFile_Mode (packet); 215 216 case StringExtractorGDBRemote::eServerPacketType_vFile_Exists: 217 return Handle_vFile_Exists (packet); 218 219 case StringExtractorGDBRemote::eServerPacketType_vFile_Stat: 220 return Handle_vFile_Stat (packet); 221 222 case StringExtractorGDBRemote::eServerPacketType_vFile_MD5: 223 return Handle_vFile_MD5 (packet); 224 } 225 return true; 226 } 227 else 228 { 229 if (!IsConnected()) 230 error.SetErrorString("lost connection"); 231 else 232 error.SetErrorString("timeout"); 233 } 234 235 return false; 236 } 237 238 size_t 239 GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *) 240 { 241 // TODO: Log the packet we aren't handling... 242 return SendPacketNoLock ("", 0); 243 } 244 245 size_t 246 GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err) 247 { 248 char packet[16]; 249 int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err); 250 assert (packet_len < (int)sizeof(packet)); 251 return SendPacketNoLock (packet, packet_len); 252 } 253 254 255 size_t 256 GDBRemoteCommunicationServer::SendOKResponse () 257 { 258 return SendPacketNoLock ("OK", 2); 259 } 260 261 bool 262 GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) 263 { 264 return GetAck(); 265 } 266 267 bool 268 GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet) 269 { 270 StreamString response; 271 272 // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 273 274 ArchSpec host_arch (Host::GetArchitecture ()); 275 const llvm::Triple &host_triple = host_arch.GetTriple(); 276 response.PutCString("triple:"); 277 response.PutCStringAsRawHex8(host_triple.getTriple().c_str()); 278 response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize()); 279 280 uint32_t cpu = host_arch.GetMachOCPUType(); 281 uint32_t sub = host_arch.GetMachOCPUSubType(); 282 if (cpu != LLDB_INVALID_CPUTYPE) 283 response.Printf ("cputype:%u;", cpu); 284 if (sub != LLDB_INVALID_CPUTYPE) 285 response.Printf ("cpusubtype:%u;", sub); 286 287 if (cpu == ArchSpec::kCore_arm_any) 288 response.Printf("watchpoint_exceptions_received:before;"); // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 289 else 290 response.Printf("watchpoint_exceptions_received:after;"); 291 292 switch (lldb::endian::InlHostByteOrder()) 293 { 294 case eByteOrderBig: response.PutCString ("endian:big;"); break; 295 case eByteOrderLittle: response.PutCString ("endian:little;"); break; 296 case eByteOrderPDP: response.PutCString ("endian:pdp;"); break; 297 default: response.PutCString ("endian:unknown;"); break; 298 } 299 300 uint32_t major = UINT32_MAX; 301 uint32_t minor = UINT32_MAX; 302 uint32_t update = UINT32_MAX; 303 if (Host::GetOSVersion (major, minor, update)) 304 { 305 if (major != UINT32_MAX) 306 { 307 response.Printf("os_version:%u", major); 308 if (minor != UINT32_MAX) 309 { 310 response.Printf(".%u", minor); 311 if (update != UINT32_MAX) 312 response.Printf(".%u", update); 313 } 314 response.PutChar(';'); 315 } 316 } 317 318 std::string s; 319 if (Host::GetOSBuildString (s)) 320 { 321 response.PutCString ("os_build:"); 322 response.PutCStringAsRawHex8(s.c_str()); 323 response.PutChar(';'); 324 } 325 if (Host::GetOSKernelDescription (s)) 326 { 327 response.PutCString ("os_kernel:"); 328 response.PutCStringAsRawHex8(s.c_str()); 329 response.PutChar(';'); 330 } 331 if (Host::GetHostname (s)) 332 { 333 response.PutCString ("hostname:"); 334 response.PutCStringAsRawHex8(s.c_str()); 335 response.PutChar(';'); 336 } 337 338 return SendPacketNoLock (response.GetData(), response.GetSize()) > 0; 339 } 340 341 static void 342 CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response) 343 { 344 response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;", 345 proc_info.GetProcessID(), 346 proc_info.GetParentProcessID(), 347 proc_info.GetUserID(), 348 proc_info.GetGroupID(), 349 proc_info.GetEffectiveUserID(), 350 proc_info.GetEffectiveGroupID()); 351 response.PutCString ("name:"); 352 response.PutCStringAsRawHex8(proc_info.GetName()); 353 response.PutChar(';'); 354 const ArchSpec &proc_arch = proc_info.GetArchitecture(); 355 if (proc_arch.IsValid()) 356 { 357 const llvm::Triple &proc_triple = proc_arch.GetTriple(); 358 response.PutCString("triple:"); 359 response.PutCStringAsRawHex8(proc_triple.getTriple().c_str()); 360 response.PutChar(';'); 361 } 362 } 363 364 bool 365 GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet) 366 { 367 // Packet format: "qProcessInfoPID:%i" where %i is the pid 368 packet.SetFilePos(::strlen ("qProcessInfoPID:")); 369 lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID); 370 if (pid != LLDB_INVALID_PROCESS_ID) 371 { 372 ProcessInstanceInfo proc_info; 373 if (Host::GetProcessInfo(pid, proc_info)) 374 { 375 StreamString response; 376 CreateProcessInfoResponse (proc_info, response); 377 return SendPacketNoLock (response.GetData(), response.GetSize()); 378 } 379 } 380 return SendErrorResponse (1); 381 } 382 383 bool 384 GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet) 385 { 386 m_proc_infos_index = 0; 387 m_proc_infos.Clear(); 388 389 ProcessInstanceInfoMatch match_info; 390 packet.SetFilePos(::strlen ("qfProcessInfo")); 391 if (packet.GetChar() == ':') 392 { 393 394 std::string key; 395 std::string value; 396 while (packet.GetNameColonValue(key, value)) 397 { 398 bool success = true; 399 if (key.compare("name") == 0) 400 { 401 StringExtractor extractor; 402 extractor.GetStringRef().swap(value); 403 extractor.GetHexByteString (value); 404 match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false); 405 } 406 else if (key.compare("name_match") == 0) 407 { 408 if (value.compare("equals") == 0) 409 { 410 match_info.SetNameMatchType (eNameMatchEquals); 411 } 412 else if (value.compare("starts_with") == 0) 413 { 414 match_info.SetNameMatchType (eNameMatchStartsWith); 415 } 416 else if (value.compare("ends_with") == 0) 417 { 418 match_info.SetNameMatchType (eNameMatchEndsWith); 419 } 420 else if (value.compare("contains") == 0) 421 { 422 match_info.SetNameMatchType (eNameMatchContains); 423 } 424 else if (value.compare("regex") == 0) 425 { 426 match_info.SetNameMatchType (eNameMatchRegularExpression); 427 } 428 else 429 { 430 success = false; 431 } 432 } 433 else if (key.compare("pid") == 0) 434 { 435 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); 436 } 437 else if (key.compare("parent_pid") == 0) 438 { 439 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); 440 } 441 else if (key.compare("uid") == 0) 442 { 443 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 444 } 445 else if (key.compare("gid") == 0) 446 { 447 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 448 } 449 else if (key.compare("euid") == 0) 450 { 451 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 452 } 453 else if (key.compare("egid") == 0) 454 { 455 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 456 } 457 else if (key.compare("all_users") == 0) 458 { 459 match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success)); 460 } 461 else if (key.compare("triple") == 0) 462 { 463 match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL); 464 } 465 else 466 { 467 success = false; 468 } 469 470 if (!success) 471 return SendErrorResponse (2); 472 } 473 } 474 475 if (Host::FindProcesses (match_info, m_proc_infos)) 476 { 477 // We found something, return the first item by calling the get 478 // subsequent process info packet handler... 479 return Handle_qsProcessInfo (packet); 480 } 481 return SendErrorResponse (3); 482 } 483 484 bool 485 GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet) 486 { 487 if (m_proc_infos_index < m_proc_infos.GetSize()) 488 { 489 StreamString response; 490 CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response); 491 ++m_proc_infos_index; 492 return SendPacketNoLock (response.GetData(), response.GetSize()); 493 } 494 return SendErrorResponse (4); 495 } 496 497 bool 498 GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet) 499 { 500 // Packet format: "qUserName:%i" where %i is the uid 501 packet.SetFilePos(::strlen ("qUserName:")); 502 uint32_t uid = packet.GetU32 (UINT32_MAX); 503 if (uid != UINT32_MAX) 504 { 505 std::string name; 506 if (Host::GetUserName (uid, name)) 507 { 508 StreamString response; 509 response.PutCStringAsRawHex8 (name.c_str()); 510 return SendPacketNoLock (response.GetData(), response.GetSize()); 511 } 512 } 513 return SendErrorResponse (5); 514 515 } 516 517 bool 518 GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet) 519 { 520 // Packet format: "qGroupName:%i" where %i is the gid 521 packet.SetFilePos(::strlen ("qGroupName:")); 522 uint32_t gid = packet.GetU32 (UINT32_MAX); 523 if (gid != UINT32_MAX) 524 { 525 std::string name; 526 if (Host::GetGroupName (gid, name)) 527 { 528 StreamString response; 529 response.PutCStringAsRawHex8 (name.c_str()); 530 return SendPacketNoLock (response.GetData(), response.GetSize()); 531 } 532 } 533 return SendErrorResponse (6); 534 } 535 536 bool 537 GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet) 538 { 539 packet.SetFilePos(::strlen ("qSpeedTest:")); 540 541 std::string key; 542 std::string value; 543 bool success = packet.GetNameColonValue(key, value); 544 if (success && key.compare("response_size") == 0) 545 { 546 uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success); 547 if (success) 548 { 549 if (response_size == 0) 550 return SendOKResponse(); 551 StreamString response; 552 uint32_t bytes_left = response_size; 553 response.PutCString("data:"); 554 while (bytes_left > 0) 555 { 556 if (bytes_left >= 26) 557 { 558 response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 559 bytes_left -= 26; 560 } 561 else 562 { 563 response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 564 bytes_left = 0; 565 } 566 } 567 return SendPacketNoLock (response.GetData(), response.GetSize()); 568 } 569 } 570 return SendErrorResponse (7); 571 } 572 573 574 static void * 575 AcceptPortFromInferior (void *arg) 576 { 577 const char *connect_url = (const char *)arg; 578 ConnectionFileDescriptor file_conn; 579 Error error; 580 if (file_conn.Connect (connect_url, &error) == eConnectionStatusSuccess) 581 { 582 char pid_str[256]; 583 ::memset (pid_str, 0, sizeof(pid_str)); 584 ConnectionStatus status; 585 const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), 0, status, NULL); 586 if (pid_str_len > 0) 587 { 588 int pid = atoi (pid_str); 589 return (void *)(intptr_t)pid; 590 } 591 } 592 return NULL; 593 } 594 // 595 //static bool 596 //WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) 597 //{ 598 // const int time_delta_usecs = 100000; 599 // const int num_retries = timeout_in_seconds/time_delta_usecs; 600 // for (int i=0; i<num_retries; i++) 601 // { 602 // struct proc_bsdinfo bsd_info; 603 // int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO, 604 // (uint64_t) 0, 605 // &bsd_info, 606 // PROC_PIDTBSDINFO_SIZE); 607 // 608 // switch (error) 609 // { 610 // case EINVAL: 611 // case ENOTSUP: 612 // case ESRCH: 613 // case EPERM: 614 // return false; 615 // 616 // default: 617 // break; 618 // 619 // case 0: 620 // if (bsd_info.pbi_status == SSTOP) 621 // return true; 622 // } 623 // ::usleep (time_delta_usecs); 624 // } 625 // return false; 626 //} 627 628 bool 629 GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet) 630 { 631 // The 'A' packet is the most over designed packet ever here with 632 // redundant argument indexes, redundant argument lengths and needed hex 633 // encoded argument string values. Really all that is needed is a comma 634 // separated hex encoded argument value list, but we will stay true to the 635 // documented version of the 'A' packet here... 636 637 packet.SetFilePos(1); // Skip the 'A' 638 bool success = true; 639 while (success && packet.GetBytesLeft() > 0) 640 { 641 // Decode the decimal argument string length. This length is the 642 // number of hex nibbles in the argument string value. 643 const uint32_t arg_len = packet.GetU32(UINT32_MAX); 644 if (arg_len == UINT32_MAX) 645 success = false; 646 else 647 { 648 // Make sure the argument hex string length is followed by a comma 649 if (packet.GetChar() != ',') 650 success = false; 651 else 652 { 653 // Decode the argument index. We ignore this really becuase 654 // who would really send down the arguments in a random order??? 655 const uint32_t arg_idx = packet.GetU32(UINT32_MAX); 656 if (arg_idx == UINT32_MAX) 657 success = false; 658 else 659 { 660 // Make sure the argument index is followed by a comma 661 if (packet.GetChar() != ',') 662 success = false; 663 else 664 { 665 // Decode the argument string value from hex bytes 666 // back into a UTF8 string and make sure the length 667 // matches the one supplied in the packet 668 std::string arg; 669 if (packet.GetHexByteString(arg) != (arg_len / 2)) 670 success = false; 671 else 672 { 673 // If there are any bytes lft 674 if (packet.GetBytesLeft()) 675 { 676 if (packet.GetChar() != ',') 677 success = false; 678 } 679 680 if (success) 681 { 682 if (arg_idx == 0) 683 m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false); 684 m_process_launch_info.GetArguments().AppendArgument(arg.c_str()); 685 } 686 } 687 } 688 } 689 } 690 } 691 } 692 693 if (success) 694 { 695 m_process_launch_info.GetFlags().Set (eLaunchFlagDebug); 696 m_process_launch_error = Host::LaunchProcess (m_process_launch_info); 697 if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 698 { 699 return SendOKResponse (); 700 } 701 } 702 return SendErrorResponse (8); 703 } 704 705 bool 706 GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet) 707 { 708 lldb::pid_t pid = m_process_launch_info.GetProcessID(); 709 StreamString response; 710 response.Printf("QC%" PRIx64, pid); 711 if (m_is_platform) 712 { 713 // If we launch a process and this GDB server is acting as a platform, 714 // then we need to clear the process launch state so we can start 715 // launching another process. In order to launch a process a bunch or 716 // packets need to be sent: environment packets, working directory, 717 // disable ASLR, and many more settings. When we launch a process we 718 // then need to know when to clear this information. Currently we are 719 // selecting the 'qC' packet as that packet which seems to make the most 720 // sense. 721 if (pid != LLDB_INVALID_PROCESS_ID) 722 { 723 m_process_launch_info.Clear(); 724 } 725 } 726 return SendPacketNoLock (response.GetData(), response.GetSize()); 727 } 728 729 bool 730 GDBRemoteCommunicationServer::DebugserverProcessReaped (lldb::pid_t pid) 731 { 732 Mutex::Locker locker (m_spawned_pids_mutex); 733 return m_spawned_pids.erase(pid) > 0; 734 } 735 bool 736 GDBRemoteCommunicationServer::ReapDebugserverProcess (void *callback_baton, 737 lldb::pid_t pid, 738 bool exited, 739 int signal, // Zero for no signal 740 int status) // Exit value of process if signal is zero 741 { 742 GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton; 743 server->DebugserverProcessReaped (pid); 744 return true; 745 } 746 747 bool 748 GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet) 749 { 750 #ifdef _WIN32 751 // No unix sockets on windows 752 return false; 753 #else 754 // Spawn a local debugserver as a platform so we can then attach or launch 755 // a process... 756 757 if (m_is_platform) 758 { 759 // Sleep and wait a bit for debugserver to start to listen... 760 ConnectionFileDescriptor file_conn; 761 char connect_url[PATH_MAX]; 762 Error error; 763 std::string hostname; 764 char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX"; 765 if (::mktemp (unix_socket_name) == NULL) 766 { 767 error.SetErrorString ("failed to make temporary path for a unix socket"); 768 } 769 else 770 { 771 packet.SetFilePos(::strlen ("qLaunchGDBServer:")); 772 std::string name; 773 std::string value; 774 uint16_t port = UINT16_MAX; 775 while (packet.GetNameColonValue(name, value)) 776 { 777 if (name.compare ("host") == 0) 778 hostname.swap(value); 779 else if (name.compare ("port") == 0) 780 port = Args::StringToUInt32(value.c_str(), 0, 0); 781 } 782 if (port == UINT16_MAX) 783 port = GetAndUpdateNextPort(); 784 785 ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name); 786 // Spawn a new thread to accept the port that gets bound after 787 // binding to port 0 (zero). 788 lldb::thread_t accept_thread = LLDB_INVALID_HOST_THREAD; 789 790 if (port == 0) 791 { 792 accept_thread = Host::ThreadCreate (unix_socket_name, 793 AcceptPortFromInferior, 794 connect_url, 795 &error); 796 } 797 798 if (IS_VALID_LLDB_HOST_THREAD(accept_thread)) 799 { 800 // Spawn a debugserver and try to get the port it listens to. 801 ProcessLaunchInfo debugserver_launch_info; 802 StreamString host_and_port; 803 if (hostname.empty()) 804 hostname = "localhost"; 805 host_and_port.Printf("%s:%u", hostname.c_str(), port); 806 const char *host_and_port_cstr = host_and_port.GetString().c_str(); 807 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 808 if (log) 809 log->Printf("Launching debugserver with: %s...\n", host_and_port_cstr); 810 error = StartDebugserverProcess (host_and_port_cstr, 811 unix_socket_name, 812 debugserver_launch_info); 813 814 lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); 815 816 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 817 { 818 { 819 Mutex::Locker locker (m_spawned_pids_mutex); 820 m_spawned_pids.insert(debugserver_pid); 821 } 822 Host::StartMonitoringChildProcess (ReapDebugserverProcess, this, debugserver_pid, false); 823 } 824 825 if (error.Success()) 826 { 827 bool success = false; 828 829 if (accept_thread) 830 { 831 thread_result_t accept_thread_result = NULL; 832 if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error)) 833 { 834 if (accept_thread_result) 835 { 836 port = (intptr_t)accept_thread_result; 837 char response[256]; 838 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port); 839 assert (response_len < sizeof(response)); 840 //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); 841 success = SendPacketNoLock (response, response_len) > 0; 842 } 843 } 844 } 845 else 846 { 847 char response[256]; 848 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port); 849 assert (response_len < sizeof(response)); 850 //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); 851 success = SendPacketNoLock (response, response_len) > 0; 852 853 } 854 ::unlink (unix_socket_name); 855 856 if (!success) 857 { 858 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 859 ::kill (debugserver_pid, SIGINT); 860 } 861 return success; 862 } 863 } 864 } 865 } 866 return SendErrorResponse (9); 867 #endif 868 } 869 870 bool 871 GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet) 872 { 873 // Spawn a local debugserver as a platform so we can then attach or launch 874 // a process... 875 876 if (m_is_platform) 877 { 878 packet.SetFilePos(::strlen ("qKillSpawnedProcess:")); 879 880 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID); 881 882 // Scope for locker 883 { 884 Mutex::Locker locker (m_spawned_pids_mutex); 885 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 886 return SendErrorResponse (10); 887 } 888 Host::Kill (pid, SIGTERM); 889 890 for (size_t i=0; i<10; ++i) 891 { 892 // Scope for locker 893 { 894 Mutex::Locker locker (m_spawned_pids_mutex); 895 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 896 return true; 897 } 898 usleep (10000); 899 } 900 901 // Scope for locker 902 { 903 Mutex::Locker locker (m_spawned_pids_mutex); 904 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 905 return true; 906 } 907 Host::Kill (pid, SIGKILL); 908 909 for (size_t i=0; i<10; ++i) 910 { 911 // Scope for locker 912 { 913 Mutex::Locker locker (m_spawned_pids_mutex); 914 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 915 return true; 916 } 917 usleep (10000); 918 } 919 } 920 return SendErrorResponse (10); 921 } 922 923 bool 924 GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet) 925 { 926 if (m_process_launch_error.Success()) 927 return SendOKResponse(); 928 StreamString response; 929 response.PutChar('E'); 930 response.PutCString(m_process_launch_error.AsCString("<unknown error>")); 931 return SendPacketNoLock (response.GetData(), response.GetSize()); 932 } 933 934 bool 935 GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &packet) 936 { 937 packet.SetFilePos(::strlen ("QEnvironment:")); 938 const uint32_t bytes_left = packet.GetBytesLeft(); 939 if (bytes_left > 0) 940 { 941 m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek()); 942 return SendOKResponse (); 943 } 944 return SendErrorResponse (11); 945 } 946 947 bool 948 GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &packet) 949 { 950 packet.SetFilePos(::strlen ("QLaunchArch:")); 951 const uint32_t bytes_left = packet.GetBytesLeft(); 952 if (bytes_left > 0) 953 { 954 const char* arch_triple = packet.Peek(); 955 ArchSpec arch_spec(arch_triple,NULL); 956 m_process_launch_info.SetArchitecture(arch_spec); 957 return SendOKResponse(); 958 } 959 return SendErrorResponse(12); 960 } 961 962 bool 963 GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet) 964 { 965 packet.SetFilePos(::strlen ("QSetDisableASLR:")); 966 if (packet.GetU32(0)) 967 m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR); 968 else 969 m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); 970 return SendOKResponse (); 971 } 972 973 bool 974 GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet) 975 { 976 packet.SetFilePos(::strlen ("QSetWorkingDir:")); 977 std::string path; 978 packet.GetHexByteString(path); 979 m_process_launch_info.SwapWorkingDirectory (path); 980 return SendOKResponse (); 981 } 982 983 bool 984 GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet) 985 { 986 packet.SetFilePos(::strlen ("QSetSTDIN:")); 987 ProcessLaunchInfo::FileAction file_action; 988 std::string path; 989 packet.GetHexByteString(path); 990 const bool read = false; 991 const bool write = true; 992 if (file_action.Open(STDIN_FILENO, path.c_str(), read, write)) 993 { 994 m_process_launch_info.AppendFileAction(file_action); 995 return SendOKResponse (); 996 } 997 return SendErrorResponse (13); 998 } 999 1000 bool 1001 GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet) 1002 { 1003 packet.SetFilePos(::strlen ("QSetSTDOUT:")); 1004 ProcessLaunchInfo::FileAction file_action; 1005 std::string path; 1006 packet.GetHexByteString(path); 1007 const bool read = true; 1008 const bool write = false; 1009 if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write)) 1010 { 1011 m_process_launch_info.AppendFileAction(file_action); 1012 return SendOKResponse (); 1013 } 1014 return SendErrorResponse (14); 1015 } 1016 1017 bool 1018 GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet) 1019 { 1020 packet.SetFilePos(::strlen ("QSetSTDERR:")); 1021 ProcessLaunchInfo::FileAction file_action; 1022 std::string path; 1023 packet.GetHexByteString(path); 1024 const bool read = true; 1025 const bool write = false; 1026 if (file_action.Open(STDERR_FILENO, path.c_str(), read, write)) 1027 { 1028 m_process_launch_info.AppendFileAction(file_action); 1029 return SendOKResponse (); 1030 } 1031 return SendErrorResponse (15); 1032 } 1033 1034 bool 1035 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet) 1036 { 1037 // Send response first before changing m_send_acks to we ack this packet 1038 SendOKResponse (); 1039 m_send_acks = false; 1040 return true; 1041 } 1042 1043 bool 1044 GDBRemoteCommunicationServer::Handle_qPlatform_IO_MkDir (StringExtractorGDBRemote &packet) 1045 { 1046 packet.SetFilePos(::strlen("qPlatform_IO_MkDir:")); 1047 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1048 if (packet.GetChar() != ',') 1049 return false; 1050 std::string path; 1051 packet.GetHexByteString(path); 1052 uint32_t retcode = Host::MakeDirectory(path.c_str(),mode); 1053 StreamString response; 1054 response.PutHex32(retcode); 1055 SendPacketNoLock(response.GetData(), response.GetSize()); 1056 return true; 1057 } 1058 1059 bool 1060 GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet) 1061 { 1062 packet.SetFilePos(::strlen("vFile:open:")); 1063 std::string path; 1064 packet.GetHexByteStringTerminatedBy(path,','); 1065 if (path.size() == 0) 1066 return false; 1067 if (packet.GetChar() != ',') 1068 return false; 1069 uint32_t flags = packet.GetHexMaxU32(false, UINT32_MAX); 1070 if (packet.GetChar() != ',') 1071 return false; 1072 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1073 Error error; 1074 int fd = ::open (path.c_str(), flags, mode); 1075 const int save_errno = fd == -1 ? errno : 0; 1076 StreamString response; 1077 response.PutChar('F'); 1078 response.Printf("%i", fd); 1079 if (save_errno) 1080 response.Printf(",%i", save_errno); 1081 SendPacketNoLock(response.GetData(), response.GetSize()); 1082 return true; 1083 } 1084 1085 bool 1086 GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet) 1087 { 1088 packet.SetFilePos(::strlen("vFile:close:")); 1089 int fd = packet.GetS32(-1); 1090 Error error; 1091 int err = -1; 1092 int save_errno = 0; 1093 if (fd >= 0) 1094 { 1095 err = close(fd); 1096 save_errno = err == -1 ? errno : 0; 1097 } 1098 else 1099 { 1100 save_errno = EINVAL; 1101 } 1102 StreamString response; 1103 response.PutChar('F'); 1104 response.Printf("%i", err); 1105 if (save_errno) 1106 response.Printf(",%i", save_errno); 1107 SendPacketNoLock(response.GetData(), response.GetSize()); 1108 return true; 1109 } 1110 1111 bool 1112 GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet) 1113 { 1114 #ifdef _WIN32 1115 // Not implemented on Windows 1116 return false; 1117 #else 1118 StreamGDBRemote response; 1119 packet.SetFilePos(::strlen("vFile:pread:")); 1120 int fd = packet.GetS32(-1); 1121 if (packet.GetChar() != ',') 1122 return false; 1123 uint64_t count = packet.GetU64(UINT64_MAX); 1124 if (packet.GetChar() != ',') 1125 return false; 1126 uint64_t offset = packet.GetU64(UINT32_MAX); 1127 if (count == UINT64_MAX) 1128 { 1129 response.Printf("F-1:%i", EINVAL); 1130 SendPacketNoLock(response.GetData(), response.GetSize()); 1131 return true; 1132 } 1133 std::string buffer(count, 0); 1134 const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset); 1135 const int save_errno = bytes_read == -1 ? errno : 0; 1136 response.PutChar('F'); 1137 response.Printf("%zi", bytes_read); 1138 if (save_errno) 1139 response.Printf(",%i", save_errno); 1140 else 1141 { 1142 response.PutChar(';'); 1143 response.PutEscapedBytes(&buffer[0], bytes_read); 1144 } 1145 SendPacketNoLock(response.GetData(), response.GetSize()); 1146 return true; 1147 #endif 1148 } 1149 1150 bool 1151 GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet) 1152 { 1153 #ifdef _WIN32 1154 // Not implemented on Windows 1155 return false; 1156 #else 1157 packet.SetFilePos(::strlen("vFile:pwrite:")); 1158 1159 StreamGDBRemote response; 1160 response.PutChar('F'); 1161 1162 int fd = packet.GetU32(UINT32_MAX); 1163 if (packet.GetChar() != ',') 1164 return false; 1165 off_t offset = packet.GetU64(UINT32_MAX); 1166 if (packet.GetChar() != ',') 1167 return false; 1168 std::string buffer; 1169 if (packet.GetEscapedBinaryData(buffer)) 1170 { 1171 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset); 1172 const int save_errno = bytes_written == -1 ? errno : 0; 1173 response.Printf("%zi", bytes_written); 1174 if (save_errno) 1175 response.Printf(",%i", save_errno); 1176 } 1177 else 1178 { 1179 response.Printf ("-1,%i", EINVAL); 1180 } 1181 1182 SendPacketNoLock(response.GetData(), response.GetSize()); 1183 return true; 1184 #endif 1185 } 1186 1187 bool 1188 GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packet) 1189 { 1190 packet.SetFilePos(::strlen("vFile:size:")); 1191 std::string path; 1192 packet.GetHexByteString(path); 1193 if (path.empty()) 1194 return false; 1195 lldb::user_id_t retcode = Host::GetFileSize(FileSpec(path.c_str(), false)); 1196 StreamString response; 1197 response.PutChar('F'); 1198 response.PutHex64(retcode); 1199 if (retcode == UINT64_MAX) 1200 { 1201 response.PutChar(','); 1202 response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode() 1203 } 1204 SendPacketNoLock(response.GetData(), response.GetSize()); 1205 return true; 1206 } 1207 1208 bool 1209 GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packet) 1210 { 1211 packet.SetFilePos(::strlen("vFile:mode:")); 1212 std::string path; 1213 packet.GetHexByteString(path); 1214 if (path.empty()) 1215 return false; 1216 Error error; 1217 const uint32_t mode = File::GetPermissions(path.c_str(), error); 1218 StreamString response; 1219 response.Printf("F%u", mode); 1220 if (mode == 0 || error.Fail()) 1221 response.Printf(",%i", (int)error.GetError()); 1222 SendPacketNoLock(response.GetData(), response.GetSize()); 1223 return true; 1224 } 1225 1226 bool 1227 GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &packet) 1228 { 1229 packet.SetFilePos(::strlen("vFile:exists:")); 1230 std::string path; 1231 packet.GetHexByteString(path); 1232 if (path.empty()) 1233 return false; 1234 bool retcode = Host::GetFileExists(FileSpec(path.c_str(), false)); 1235 StreamString response; 1236 response.PutChar('F'); 1237 response.PutChar(','); 1238 if (retcode) 1239 response.PutChar('1'); 1240 else 1241 response.PutChar('0'); 1242 SendPacketNoLock(response.GetData(), response.GetSize()); 1243 return true; 1244 } 1245 1246 bool 1247 GDBRemoteCommunicationServer::Handle_qPlatform_RunCommand (StringExtractorGDBRemote &packet) 1248 { 1249 packet.SetFilePos(::strlen("qPlatform_RunCommand:")); 1250 std::string path; 1251 std::string working_dir; 1252 packet.GetHexByteStringTerminatedBy(path,','); 1253 if (path.size() == 0) 1254 return false; 1255 if (packet.GetChar() != ',') 1256 return false; 1257 // FIXME: add timeout to qPlatform_RunCommand packet 1258 // uint32_t timeout = packet.GetHexMaxU32(false, 32); 1259 uint32_t timeout = 10; 1260 if (packet.GetChar() == ',') 1261 packet.GetHexByteString(working_dir); 1262 int status, signo; 1263 std::string output; 1264 Error err = Host::RunShellCommand(path.c_str(), 1265 working_dir.empty() ? NULL : working_dir.c_str(), 1266 &status, &signo, &output, timeout); 1267 StreamGDBRemote response; 1268 if (err.Fail()) 1269 { 1270 response.PutCString("F,"); 1271 response.PutHex32(UINT32_MAX); 1272 } 1273 else 1274 { 1275 response.PutCString("F,"); 1276 response.PutHex32(status); 1277 response.PutChar(','); 1278 response.PutHex32(signo); 1279 response.PutChar(','); 1280 response.PutEscapedBytes(output.c_str(), output.size()); 1281 } 1282 SendPacketNoLock(response.GetData(), response.GetSize()); 1283 return true; 1284 } 1285 1286 bool 1287 GDBRemoteCommunicationServer::Handle_vFile_Stat (StringExtractorGDBRemote &packet) 1288 { 1289 return false; 1290 } 1291 1292 bool 1293 GDBRemoteCommunicationServer::Handle_vFile_MD5 (StringExtractorGDBRemote &packet) 1294 { 1295 packet.SetFilePos(::strlen("vFile:exists:")); 1296 std::string path; 1297 packet.GetHexByteString(path); 1298 if (path.size() == 0) 1299 return false; 1300 uint64_t a,b; 1301 StreamGDBRemote response; 1302 if (Host::CalculateMD5(FileSpec(path.c_str(),false),a,b) == false) 1303 { 1304 response.PutCString("F,"); 1305 response.PutCString("x"); 1306 } 1307 else 1308 { 1309 response.PutCString("F,"); 1310 response.PutHex64(a); 1311 response.PutHex64(b); 1312 } 1313 SendPacketNoLock(response.GetData(), response.GetSize()); 1314 return true; 1315 } 1316