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 char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX"; 766 if (::mkstemp (unix_socket_name) == -1) 767 { 768 error.SetErrorStringWithFormat("failed to make temporary path for a unix socket with errno: %s", strerror(errno)); 769 } 770 else 771 { 772 packet.SetFilePos(::strlen ("qLaunchGDBServer:")); 773 std::string name; 774 std::string value; 775 uint16_t port = UINT16_MAX; 776 while (packet.GetNameColonValue(name, value)) 777 { 778 if (name.compare ("host") == 0) 779 hostname.swap(value); 780 else if (name.compare ("port") == 0) 781 port = Args::StringToUInt32(value.c_str(), 0, 0); 782 } 783 if (port == UINT16_MAX) 784 port = GetAndUpdateNextPort(); 785 786 ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name); 787 // Spawn a new thread to accept the port that gets bound after 788 // binding to port 0 (zero). 789 lldb::thread_t accept_thread = LLDB_INVALID_HOST_THREAD; 790 791 if (port == 0) 792 { 793 accept_thread = Host::ThreadCreate (unix_socket_name, 794 AcceptPortFromInferior, 795 connect_url, 796 &error); 797 } 798 799 if (IS_VALID_LLDB_HOST_THREAD(accept_thread)) 800 { 801 // Spawn a debugserver and try to get the port it listens to. 802 ProcessLaunchInfo debugserver_launch_info; 803 StreamString host_and_port; 804 if (hostname.empty()) 805 hostname = "localhost"; 806 host_and_port.Printf("%s:%u", hostname.c_str(), port); 807 const char *host_and_port_cstr = host_and_port.GetString().c_str(); 808 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 809 if (log) 810 log->Printf("Launching debugserver with: %s...\n", host_and_port_cstr); 811 error = StartDebugserverProcess (host_and_port_cstr, 812 unix_socket_name, 813 debugserver_launch_info); 814 815 lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); 816 817 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 818 { 819 { 820 Mutex::Locker locker (m_spawned_pids_mutex); 821 m_spawned_pids.insert(debugserver_pid); 822 } 823 Host::StartMonitoringChildProcess (ReapDebugserverProcess, this, debugserver_pid, false); 824 } 825 826 if (error.Success()) 827 { 828 bool success = false; 829 830 if (accept_thread) 831 { 832 thread_result_t accept_thread_result = NULL; 833 if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error)) 834 { 835 if (accept_thread_result) 836 { 837 port = (intptr_t)accept_thread_result; 838 char response[256]; 839 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port); 840 assert (response_len < sizeof(response)); 841 //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); 842 success = SendPacketNoLock (response, response_len) > 0; 843 } 844 } 845 } 846 else 847 { 848 char response[256]; 849 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port); 850 assert (response_len < sizeof(response)); 851 //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); 852 success = SendPacketNoLock (response, response_len) > 0; 853 854 } 855 ::unlink (unix_socket_name); 856 857 if (!success) 858 { 859 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 860 ::kill (debugserver_pid, SIGINT); 861 } 862 return success; 863 } 864 } 865 } 866 } 867 return SendErrorResponse (9); 868 #endif 869 } 870 871 bool 872 GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet) 873 { 874 // Spawn a local debugserver as a platform so we can then attach or launch 875 // a process... 876 877 if (m_is_platform) 878 { 879 packet.SetFilePos(::strlen ("qKillSpawnedProcess:")); 880 881 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID); 882 883 // Scope for locker 884 { 885 Mutex::Locker locker (m_spawned_pids_mutex); 886 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 887 return SendErrorResponse (10); 888 } 889 Host::Kill (pid, SIGTERM); 890 891 for (size_t i=0; i<10; ++i) 892 { 893 // Scope for locker 894 { 895 Mutex::Locker locker (m_spawned_pids_mutex); 896 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 897 return true; 898 } 899 usleep (10000); 900 } 901 902 // Scope for locker 903 { 904 Mutex::Locker locker (m_spawned_pids_mutex); 905 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 906 return true; 907 } 908 Host::Kill (pid, SIGKILL); 909 910 for (size_t i=0; i<10; ++i) 911 { 912 // Scope for locker 913 { 914 Mutex::Locker locker (m_spawned_pids_mutex); 915 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 916 return true; 917 } 918 usleep (10000); 919 } 920 } 921 return SendErrorResponse (10); 922 } 923 924 bool 925 GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet) 926 { 927 if (m_process_launch_error.Success()) 928 return SendOKResponse(); 929 StreamString response; 930 response.PutChar('E'); 931 response.PutCString(m_process_launch_error.AsCString("<unknown error>")); 932 return SendPacketNoLock (response.GetData(), response.GetSize()); 933 } 934 935 bool 936 GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &packet) 937 { 938 packet.SetFilePos(::strlen ("QEnvironment:")); 939 const uint32_t bytes_left = packet.GetBytesLeft(); 940 if (bytes_left > 0) 941 { 942 m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek()); 943 return SendOKResponse (); 944 } 945 return SendErrorResponse (11); 946 } 947 948 bool 949 GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &packet) 950 { 951 packet.SetFilePos(::strlen ("QLaunchArch:")); 952 const uint32_t bytes_left = packet.GetBytesLeft(); 953 if (bytes_left > 0) 954 { 955 const char* arch_triple = packet.Peek(); 956 ArchSpec arch_spec(arch_triple,NULL); 957 m_process_launch_info.SetArchitecture(arch_spec); 958 return SendOKResponse(); 959 } 960 return SendErrorResponse(12); 961 } 962 963 bool 964 GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet) 965 { 966 packet.SetFilePos(::strlen ("QSetDisableASLR:")); 967 if (packet.GetU32(0)) 968 m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR); 969 else 970 m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); 971 return SendOKResponse (); 972 } 973 974 bool 975 GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet) 976 { 977 packet.SetFilePos(::strlen ("QSetWorkingDir:")); 978 std::string path; 979 packet.GetHexByteString(path); 980 m_process_launch_info.SwapWorkingDirectory (path); 981 return SendOKResponse (); 982 } 983 984 bool 985 GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet) 986 { 987 packet.SetFilePos(::strlen ("QSetSTDIN:")); 988 ProcessLaunchInfo::FileAction file_action; 989 std::string path; 990 packet.GetHexByteString(path); 991 const bool read = false; 992 const bool write = true; 993 if (file_action.Open(STDIN_FILENO, path.c_str(), read, write)) 994 { 995 m_process_launch_info.AppendFileAction(file_action); 996 return SendOKResponse (); 997 } 998 return SendErrorResponse (13); 999 } 1000 1001 bool 1002 GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet) 1003 { 1004 packet.SetFilePos(::strlen ("QSetSTDOUT:")); 1005 ProcessLaunchInfo::FileAction file_action; 1006 std::string path; 1007 packet.GetHexByteString(path); 1008 const bool read = true; 1009 const bool write = false; 1010 if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write)) 1011 { 1012 m_process_launch_info.AppendFileAction(file_action); 1013 return SendOKResponse (); 1014 } 1015 return SendErrorResponse (14); 1016 } 1017 1018 bool 1019 GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet) 1020 { 1021 packet.SetFilePos(::strlen ("QSetSTDERR:")); 1022 ProcessLaunchInfo::FileAction file_action; 1023 std::string path; 1024 packet.GetHexByteString(path); 1025 const bool read = true; 1026 const bool write = false; 1027 if (file_action.Open(STDERR_FILENO, path.c_str(), read, write)) 1028 { 1029 m_process_launch_info.AppendFileAction(file_action); 1030 return SendOKResponse (); 1031 } 1032 return SendErrorResponse (15); 1033 } 1034 1035 bool 1036 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet) 1037 { 1038 // Send response first before changing m_send_acks to we ack this packet 1039 SendOKResponse (); 1040 m_send_acks = false; 1041 return true; 1042 } 1043 1044 bool 1045 GDBRemoteCommunicationServer::Handle_qPlatform_IO_MkDir (StringExtractorGDBRemote &packet) 1046 { 1047 packet.SetFilePos(::strlen("qPlatform_IO_MkDir:")); 1048 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1049 if (packet.GetChar() != ',') 1050 return false; 1051 std::string path; 1052 packet.GetHexByteString(path); 1053 uint32_t retcode = Host::MakeDirectory(path.c_str(),mode); 1054 StreamString response; 1055 response.PutHex32(retcode); 1056 SendPacketNoLock(response.GetData(), response.GetSize()); 1057 return true; 1058 } 1059 1060 bool 1061 GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet) 1062 { 1063 packet.SetFilePos(::strlen("vFile:open:")); 1064 std::string path; 1065 packet.GetHexByteStringTerminatedBy(path,','); 1066 if (path.size() == 0) 1067 return false; 1068 if (packet.GetChar() != ',') 1069 return false; 1070 uint32_t flags = packet.GetHexMaxU32(false, UINT32_MAX); 1071 if (packet.GetChar() != ',') 1072 return false; 1073 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1074 Error error; 1075 int fd = ::open (path.c_str(), flags, mode); 1076 const int save_errno = fd == -1 ? errno : 0; 1077 StreamString response; 1078 response.PutChar('F'); 1079 response.Printf("%i", fd); 1080 if (save_errno) 1081 response.Printf(",%i", save_errno); 1082 SendPacketNoLock(response.GetData(), response.GetSize()); 1083 return true; 1084 } 1085 1086 bool 1087 GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet) 1088 { 1089 packet.SetFilePos(::strlen("vFile:close:")); 1090 int fd = packet.GetS32(-1); 1091 Error error; 1092 int err = -1; 1093 int save_errno = 0; 1094 if (fd >= 0) 1095 { 1096 err = close(fd); 1097 save_errno = err == -1 ? errno : 0; 1098 } 1099 else 1100 { 1101 save_errno = EINVAL; 1102 } 1103 StreamString response; 1104 response.PutChar('F'); 1105 response.Printf("%i", err); 1106 if (save_errno) 1107 response.Printf(",%i", save_errno); 1108 SendPacketNoLock(response.GetData(), response.GetSize()); 1109 return true; 1110 } 1111 1112 bool 1113 GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet) 1114 { 1115 #ifdef _WIN32 1116 // Not implemented on Windows 1117 return false; 1118 #else 1119 StreamGDBRemote response; 1120 packet.SetFilePos(::strlen("vFile:pread:")); 1121 int fd = packet.GetS32(-1); 1122 if (packet.GetChar() != ',') 1123 return false; 1124 uint64_t count = packet.GetU64(UINT64_MAX); 1125 if (packet.GetChar() != ',') 1126 return false; 1127 uint64_t offset = packet.GetU64(UINT32_MAX); 1128 if (count == UINT64_MAX) 1129 { 1130 response.Printf("F-1:%i", EINVAL); 1131 SendPacketNoLock(response.GetData(), response.GetSize()); 1132 return true; 1133 } 1134 std::string buffer(count, 0); 1135 const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset); 1136 const int save_errno = bytes_read == -1 ? errno : 0; 1137 response.PutChar('F'); 1138 response.Printf("%zi", bytes_read); 1139 if (save_errno) 1140 response.Printf(",%i", save_errno); 1141 else 1142 { 1143 response.PutChar(';'); 1144 response.PutEscapedBytes(&buffer[0], bytes_read); 1145 } 1146 SendPacketNoLock(response.GetData(), response.GetSize()); 1147 return true; 1148 #endif 1149 } 1150 1151 bool 1152 GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet) 1153 { 1154 #ifdef _WIN32 1155 // Not implemented on Windows 1156 return false; 1157 #else 1158 packet.SetFilePos(::strlen("vFile:pwrite:")); 1159 1160 StreamGDBRemote response; 1161 response.PutChar('F'); 1162 1163 int fd = packet.GetU32(UINT32_MAX); 1164 if (packet.GetChar() != ',') 1165 return false; 1166 off_t offset = packet.GetU64(UINT32_MAX); 1167 if (packet.GetChar() != ',') 1168 return false; 1169 std::string buffer; 1170 if (packet.GetEscapedBinaryData(buffer)) 1171 { 1172 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset); 1173 const int save_errno = bytes_written == -1 ? errno : 0; 1174 response.Printf("%zi", bytes_written); 1175 if (save_errno) 1176 response.Printf(",%i", save_errno); 1177 } 1178 else 1179 { 1180 response.Printf ("-1,%i", EINVAL); 1181 } 1182 1183 SendPacketNoLock(response.GetData(), response.GetSize()); 1184 return true; 1185 #endif 1186 } 1187 1188 bool 1189 GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packet) 1190 { 1191 packet.SetFilePos(::strlen("vFile:size:")); 1192 std::string path; 1193 packet.GetHexByteString(path); 1194 if (path.empty()) 1195 return false; 1196 lldb::user_id_t retcode = Host::GetFileSize(FileSpec(path.c_str(), false)); 1197 StreamString response; 1198 response.PutChar('F'); 1199 response.PutHex64(retcode); 1200 if (retcode == UINT64_MAX) 1201 { 1202 response.PutChar(','); 1203 response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode() 1204 } 1205 SendPacketNoLock(response.GetData(), response.GetSize()); 1206 return true; 1207 } 1208 1209 bool 1210 GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packet) 1211 { 1212 packet.SetFilePos(::strlen("vFile:mode:")); 1213 std::string path; 1214 packet.GetHexByteString(path); 1215 if (path.empty()) 1216 return false; 1217 Error error; 1218 const uint32_t mode = File::GetPermissions(path.c_str(), error); 1219 StreamString response; 1220 response.Printf("F%u", mode); 1221 if (mode == 0 || error.Fail()) 1222 response.Printf(",%i", (int)error.GetError()); 1223 SendPacketNoLock(response.GetData(), response.GetSize()); 1224 return true; 1225 } 1226 1227 bool 1228 GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &packet) 1229 { 1230 packet.SetFilePos(::strlen("vFile:exists:")); 1231 std::string path; 1232 packet.GetHexByteString(path); 1233 if (path.empty()) 1234 return false; 1235 bool retcode = Host::GetFileExists(FileSpec(path.c_str(), false)); 1236 StreamString response; 1237 response.PutChar('F'); 1238 response.PutChar(','); 1239 if (retcode) 1240 response.PutChar('1'); 1241 else 1242 response.PutChar('0'); 1243 SendPacketNoLock(response.GetData(), response.GetSize()); 1244 return true; 1245 } 1246 1247 bool 1248 GDBRemoteCommunicationServer::Handle_qPlatform_RunCommand (StringExtractorGDBRemote &packet) 1249 { 1250 packet.SetFilePos(::strlen("qPlatform_RunCommand:")); 1251 std::string path; 1252 std::string working_dir; 1253 packet.GetHexByteStringTerminatedBy(path,','); 1254 if (path.size() == 0) 1255 return false; 1256 if (packet.GetChar() != ',') 1257 return false; 1258 // FIXME: add timeout to qPlatform_RunCommand packet 1259 // uint32_t timeout = packet.GetHexMaxU32(false, 32); 1260 uint32_t timeout = 10; 1261 if (packet.GetChar() == ',') 1262 packet.GetHexByteString(working_dir); 1263 int status, signo; 1264 std::string output; 1265 Error err = Host::RunShellCommand(path.c_str(), 1266 working_dir.empty() ? NULL : working_dir.c_str(), 1267 &status, &signo, &output, timeout); 1268 StreamGDBRemote response; 1269 if (err.Fail()) 1270 { 1271 response.PutCString("F,"); 1272 response.PutHex32(UINT32_MAX); 1273 } 1274 else 1275 { 1276 response.PutCString("F,"); 1277 response.PutHex32(status); 1278 response.PutChar(','); 1279 response.PutHex32(signo); 1280 response.PutChar(','); 1281 response.PutEscapedBytes(output.c_str(), output.size()); 1282 } 1283 SendPacketNoLock(response.GetData(), response.GetSize()); 1284 return true; 1285 } 1286 1287 bool 1288 GDBRemoteCommunicationServer::Handle_vFile_Stat (StringExtractorGDBRemote &packet) 1289 { 1290 return false; 1291 } 1292 1293 bool 1294 GDBRemoteCommunicationServer::Handle_vFile_MD5 (StringExtractorGDBRemote &packet) 1295 { 1296 packet.SetFilePos(::strlen("vFile:exists:")); 1297 std::string path; 1298 packet.GetHexByteString(path); 1299 if (path.size() == 0) 1300 return false; 1301 uint64_t a,b; 1302 StreamGDBRemote response; 1303 if (Host::CalculateMD5(FileSpec(path.c_str(),false),a,b) == false) 1304 { 1305 response.PutCString("F,"); 1306 response.PutCString("x"); 1307 } 1308 else 1309 { 1310 response.PutCString("F,"); 1311 response.PutHex64(a); 1312 response.PutHex64(b); 1313 } 1314 SendPacketNoLock(response.GetData(), response.GetSize()); 1315 return true; 1316 } 1317