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