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/Platform.h" 29 #include "lldb/Target/Process.h" 30 31 // Project includes 32 #include "Utility/StringExtractorGDBRemote.h" 33 #include "ProcessGDBRemote.h" 34 #include "ProcessGDBRemoteLog.h" 35 36 using namespace lldb; 37 using namespace lldb_private; 38 39 //---------------------------------------------------------------------- 40 // GDBRemoteCommunicationServer constructor 41 //---------------------------------------------------------------------- 42 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) : 43 GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform), 44 m_platform_sp (Platform::GetDefaultPlatform ()), 45 m_async_thread (LLDB_INVALID_HOST_THREAD), 46 m_process_launch_info (), 47 m_process_launch_error (), 48 m_spawned_pids (), 49 m_spawned_pids_mutex (Mutex::eMutexTypeRecursive), 50 m_proc_infos (), 51 m_proc_infos_index (0), 52 m_port_map (), 53 m_port_offset(0) 54 { 55 } 56 57 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform, 58 const lldb::PlatformSP& platform_sp) : 59 GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform), 60 m_platform_sp (platform_sp), 61 m_async_thread (LLDB_INVALID_HOST_THREAD), 62 m_process_launch_info (), 63 m_process_launch_error (), 64 m_spawned_pids (), 65 m_spawned_pids_mutex (Mutex::eMutexTypeRecursive), 66 m_proc_infos (), 67 m_proc_infos_index (0), 68 m_port_map (), 69 m_port_offset(0) 70 { 71 assert(platform_sp); 72 } 73 74 //---------------------------------------------------------------------- 75 // Destructor 76 //---------------------------------------------------------------------- 77 GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() 78 { 79 } 80 81 82 //void * 83 //GDBRemoteCommunicationServer::AsyncThread (void *arg) 84 //{ 85 // GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg; 86 // 87 // Log *log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 88 // if (log) 89 // log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID()); 90 // 91 // StringExtractorGDBRemote packet; 92 // 93 // while () 94 // { 95 // if (packet. 96 // } 97 // 98 // if (log) 99 // log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID()); 100 // 101 // process->m_async_thread = LLDB_INVALID_HOST_THREAD; 102 // return NULL; 103 //} 104 // 105 bool 106 GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec, 107 Error &error, 108 bool &interrupt, 109 bool &quit) 110 { 111 StringExtractorGDBRemote packet; 112 PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec); 113 if (packet_result == PacketResult::Success) 114 { 115 const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType (); 116 switch (packet_type) 117 { 118 case StringExtractorGDBRemote::eServerPacketType_nack: 119 case StringExtractorGDBRemote::eServerPacketType_ack: 120 break; 121 122 case StringExtractorGDBRemote::eServerPacketType_invalid: 123 error.SetErrorString("invalid packet"); 124 quit = true; 125 break; 126 127 case StringExtractorGDBRemote::eServerPacketType_interrupt: 128 error.SetErrorString("interrupt received"); 129 interrupt = true; 130 break; 131 132 default: 133 case StringExtractorGDBRemote::eServerPacketType_unimplemented: 134 packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str()); 135 break; 136 137 case StringExtractorGDBRemote::eServerPacketType_A: 138 packet_result = Handle_A (packet); 139 break; 140 141 case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo: 142 packet_result = Handle_qfProcessInfo (packet); 143 break; 144 145 case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo: 146 packet_result = Handle_qsProcessInfo (packet); 147 break; 148 149 case StringExtractorGDBRemote::eServerPacketType_qC: 150 packet_result = Handle_qC (packet); 151 break; 152 153 case StringExtractorGDBRemote::eServerPacketType_qHostInfo: 154 packet_result = Handle_qHostInfo (packet); 155 break; 156 157 case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer: 158 packet_result = Handle_qLaunchGDBServer (packet); 159 break; 160 161 case StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess: 162 packet_result = Handle_qKillSpawnedProcess (packet); 163 break; 164 165 case StringExtractorGDBRemote::eServerPacketType_k: 166 packet_result = Handle_k (packet); 167 break; 168 169 case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess: 170 packet_result = Handle_qLaunchSuccess (packet); 171 break; 172 173 case StringExtractorGDBRemote::eServerPacketType_qGroupName: 174 packet_result = Handle_qGroupName (packet); 175 break; 176 177 case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID: 178 packet_result = Handle_qProcessInfoPID (packet); 179 break; 180 181 case StringExtractorGDBRemote::eServerPacketType_qSpeedTest: 182 packet_result = Handle_qSpeedTest (packet); 183 break; 184 185 case StringExtractorGDBRemote::eServerPacketType_qUserName: 186 packet_result = Handle_qUserName (packet); 187 break; 188 189 case StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir: 190 packet_result = Handle_qGetWorkingDir(packet); 191 break; 192 193 case StringExtractorGDBRemote::eServerPacketType_QEnvironment: 194 packet_result = Handle_QEnvironment (packet); 195 break; 196 197 case StringExtractorGDBRemote::eServerPacketType_QLaunchArch: 198 packet_result = Handle_QLaunchArch (packet); 199 break; 200 201 case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR: 202 packet_result = Handle_QSetDisableASLR (packet); 203 break; 204 205 case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN: 206 packet_result = Handle_QSetSTDIN (packet); 207 break; 208 209 case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT: 210 packet_result = Handle_QSetSTDOUT (packet); 211 break; 212 213 case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR: 214 packet_result = Handle_QSetSTDERR (packet); 215 break; 216 217 case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir: 218 packet_result = Handle_QSetWorkingDir (packet); 219 break; 220 221 case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode: 222 packet_result = Handle_QStartNoAckMode (packet); 223 break; 224 225 case StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir: 226 packet_result = Handle_qPlatform_mkdir (packet); 227 break; 228 229 case StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod: 230 packet_result = Handle_qPlatform_chmod (packet); 231 break; 232 233 case StringExtractorGDBRemote::eServerPacketType_qPlatform_shell: 234 packet_result = Handle_qPlatform_shell (packet); 235 break; 236 237 case StringExtractorGDBRemote::eServerPacketType_vFile_open: 238 packet_result = Handle_vFile_Open (packet); 239 break; 240 241 case StringExtractorGDBRemote::eServerPacketType_vFile_close: 242 packet_result = Handle_vFile_Close (packet); 243 break; 244 245 case StringExtractorGDBRemote::eServerPacketType_vFile_pread: 246 packet_result = Handle_vFile_pRead (packet); 247 break; 248 249 case StringExtractorGDBRemote::eServerPacketType_vFile_pwrite: 250 packet_result = Handle_vFile_pWrite (packet); 251 break; 252 253 case StringExtractorGDBRemote::eServerPacketType_vFile_size: 254 packet_result = Handle_vFile_Size (packet); 255 break; 256 257 case StringExtractorGDBRemote::eServerPacketType_vFile_mode: 258 packet_result = Handle_vFile_Mode (packet); 259 break; 260 261 case StringExtractorGDBRemote::eServerPacketType_vFile_exists: 262 packet_result = Handle_vFile_Exists (packet); 263 break; 264 265 case StringExtractorGDBRemote::eServerPacketType_vFile_stat: 266 packet_result = Handle_vFile_Stat (packet); 267 break; 268 269 case StringExtractorGDBRemote::eServerPacketType_vFile_md5: 270 packet_result = Handle_vFile_MD5 (packet); 271 break; 272 273 case StringExtractorGDBRemote::eServerPacketType_vFile_symlink: 274 packet_result = Handle_vFile_symlink (packet); 275 break; 276 277 case StringExtractorGDBRemote::eServerPacketType_vFile_unlink: 278 packet_result = Handle_vFile_unlink (packet); 279 break; 280 } 281 } 282 else 283 { 284 if (!IsConnected()) 285 { 286 error.SetErrorString("lost connection"); 287 quit = true; 288 } 289 else 290 { 291 error.SetErrorString("timeout"); 292 } 293 } 294 return packet_result == PacketResult::Success; 295 } 296 297 lldb_private::Error 298 GDBRemoteCommunicationServer::SetLaunchArguments (const char *const args[], int argc) 299 { 300 if ((argc < 1) || !args || !args[0] || !args[0][0]) 301 return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__); 302 303 m_process_launch_info.SetArguments (const_cast<const char**> (args), true); 304 return lldb_private::Error (); 305 } 306 307 lldb_private::Error 308 GDBRemoteCommunicationServer::SetLaunchFlags (unsigned int launch_flags) 309 { 310 m_process_launch_info.GetFlags ().Set (launch_flags); 311 return lldb_private::Error (); 312 } 313 314 lldb_private::Error 315 GDBRemoteCommunicationServer::LaunchProcess () 316 { 317 if (!m_process_launch_info.GetArguments ().GetArgumentCount ()) 318 return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__); 319 320 // specify the process monitor if not already set. This should 321 // generally be what happens since we need to reap started 322 // processes. 323 if (!m_process_launch_info.GetMonitorProcessCallback ()) 324 m_process_launch_info.SetMonitorProcessCallback(ReapDebuggedProcess, this, false); 325 326 lldb_private::Error error = m_platform_sp->LaunchProcess (m_process_launch_info); 327 if (!error.Success ()) 328 { 329 fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0)); 330 return error; 331 } 332 333 printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID()); 334 335 // add to list of spawned processes. On an lldb-gdbserver, we 336 // would expect there to be only one. 337 lldb::pid_t pid; 338 if ( (pid = m_process_launch_info.GetProcessID()) != LLDB_INVALID_PROCESS_ID ) 339 { 340 Mutex::Locker locker (m_spawned_pids_mutex); 341 m_spawned_pids.insert(pid); 342 } 343 344 return error; 345 } 346 347 GDBRemoteCommunication::PacketResult 348 GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *) 349 { 350 // TODO: Log the packet we aren't handling... 351 return SendPacketNoLock ("", 0); 352 } 353 354 GDBRemoteCommunication::PacketResult 355 GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err) 356 { 357 char packet[16]; 358 int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err); 359 assert (packet_len < (int)sizeof(packet)); 360 return SendPacketNoLock (packet, packet_len); 361 } 362 363 364 GDBRemoteCommunication::PacketResult 365 GDBRemoteCommunicationServer::SendOKResponse () 366 { 367 return SendPacketNoLock ("OK", 2); 368 } 369 370 bool 371 GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) 372 { 373 return GetAck() == PacketResult::Success; 374 } 375 376 GDBRemoteCommunication::PacketResult 377 GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet) 378 { 379 StreamString response; 380 381 // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 382 383 ArchSpec host_arch (Host::GetArchitecture ()); 384 const llvm::Triple &host_triple = host_arch.GetTriple(); 385 response.PutCString("triple:"); 386 response.PutCStringAsRawHex8(host_triple.getTriple().c_str()); 387 response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize()); 388 389 const char* distribution_id = host_arch.GetDistributionId ().AsCString (); 390 if (distribution_id) 391 { 392 response.PutCString("distribution_id:"); 393 response.PutCStringAsRawHex8(distribution_id); 394 response.PutCString(";"); 395 } 396 397 uint32_t cpu = host_arch.GetMachOCPUType(); 398 uint32_t sub = host_arch.GetMachOCPUSubType(); 399 if (cpu != LLDB_INVALID_CPUTYPE) 400 response.Printf ("cputype:%u;", cpu); 401 if (sub != LLDB_INVALID_CPUTYPE) 402 response.Printf ("cpusubtype:%u;", sub); 403 404 if (cpu == ArchSpec::kCore_arm_any) 405 response.Printf("watchpoint_exceptions_received:before;"); // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 406 else 407 response.Printf("watchpoint_exceptions_received:after;"); 408 409 switch (lldb::endian::InlHostByteOrder()) 410 { 411 case eByteOrderBig: response.PutCString ("endian:big;"); break; 412 case eByteOrderLittle: response.PutCString ("endian:little;"); break; 413 case eByteOrderPDP: response.PutCString ("endian:pdp;"); break; 414 default: response.PutCString ("endian:unknown;"); break; 415 } 416 417 uint32_t major = UINT32_MAX; 418 uint32_t minor = UINT32_MAX; 419 uint32_t update = UINT32_MAX; 420 if (Host::GetOSVersion (major, minor, update)) 421 { 422 if (major != UINT32_MAX) 423 { 424 response.Printf("os_version:%u", major); 425 if (minor != UINT32_MAX) 426 { 427 response.Printf(".%u", minor); 428 if (update != UINT32_MAX) 429 response.Printf(".%u", update); 430 } 431 response.PutChar(';'); 432 } 433 } 434 435 std::string s; 436 if (Host::GetOSBuildString (s)) 437 { 438 response.PutCString ("os_build:"); 439 response.PutCStringAsRawHex8(s.c_str()); 440 response.PutChar(';'); 441 } 442 if (Host::GetOSKernelDescription (s)) 443 { 444 response.PutCString ("os_kernel:"); 445 response.PutCStringAsRawHex8(s.c_str()); 446 response.PutChar(';'); 447 } 448 #if defined(__APPLE__) 449 450 #if defined(__arm__) || defined(__arm64__) 451 // For iOS devices, we are connected through a USB Mux so we never pretend 452 // to actually have a hostname as far as the remote lldb that is connecting 453 // to this lldb-platform is concerned 454 response.PutCString ("hostname:"); 455 response.PutCStringAsRawHex8("127.0.0.1"); 456 response.PutChar(';'); 457 #else // #if defined(__arm__) || defined(__arm64__) 458 if (Host::GetHostname (s)) 459 { 460 response.PutCString ("hostname:"); 461 response.PutCStringAsRawHex8(s.c_str()); 462 response.PutChar(';'); 463 } 464 #endif // #if defined(__arm__) || defined(__arm64__) 465 466 #else // #if defined(__APPLE__) 467 if (Host::GetHostname (s)) 468 { 469 response.PutCString ("hostname:"); 470 response.PutCStringAsRawHex8(s.c_str()); 471 response.PutChar(';'); 472 } 473 #endif // #if defined(__APPLE__) 474 475 return SendPacketNoLock (response.GetData(), response.GetSize()); 476 } 477 478 static void 479 CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response) 480 { 481 response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;", 482 proc_info.GetProcessID(), 483 proc_info.GetParentProcessID(), 484 proc_info.GetUserID(), 485 proc_info.GetGroupID(), 486 proc_info.GetEffectiveUserID(), 487 proc_info.GetEffectiveGroupID()); 488 response.PutCString ("name:"); 489 response.PutCStringAsRawHex8(proc_info.GetName()); 490 response.PutChar(';'); 491 const ArchSpec &proc_arch = proc_info.GetArchitecture(); 492 if (proc_arch.IsValid()) 493 { 494 const llvm::Triple &proc_triple = proc_arch.GetTriple(); 495 response.PutCString("triple:"); 496 response.PutCStringAsRawHex8(proc_triple.getTriple().c_str()); 497 response.PutChar(';'); 498 } 499 } 500 501 GDBRemoteCommunication::PacketResult 502 GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet) 503 { 504 // Packet format: "qProcessInfoPID:%i" where %i is the pid 505 packet.SetFilePos(::strlen ("qProcessInfoPID:")); 506 lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID); 507 if (pid != LLDB_INVALID_PROCESS_ID) 508 { 509 ProcessInstanceInfo proc_info; 510 if (Host::GetProcessInfo(pid, proc_info)) 511 { 512 StreamString response; 513 CreateProcessInfoResponse (proc_info, response); 514 return SendPacketNoLock (response.GetData(), response.GetSize()); 515 } 516 } 517 return SendErrorResponse (1); 518 } 519 520 GDBRemoteCommunication::PacketResult 521 GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet) 522 { 523 m_proc_infos_index = 0; 524 m_proc_infos.Clear(); 525 526 ProcessInstanceInfoMatch match_info; 527 packet.SetFilePos(::strlen ("qfProcessInfo")); 528 if (packet.GetChar() == ':') 529 { 530 531 std::string key; 532 std::string value; 533 while (packet.GetNameColonValue(key, value)) 534 { 535 bool success = true; 536 if (key.compare("name") == 0) 537 { 538 StringExtractor extractor; 539 extractor.GetStringRef().swap(value); 540 extractor.GetHexByteString (value); 541 match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false); 542 } 543 else if (key.compare("name_match") == 0) 544 { 545 if (value.compare("equals") == 0) 546 { 547 match_info.SetNameMatchType (eNameMatchEquals); 548 } 549 else if (value.compare("starts_with") == 0) 550 { 551 match_info.SetNameMatchType (eNameMatchStartsWith); 552 } 553 else if (value.compare("ends_with") == 0) 554 { 555 match_info.SetNameMatchType (eNameMatchEndsWith); 556 } 557 else if (value.compare("contains") == 0) 558 { 559 match_info.SetNameMatchType (eNameMatchContains); 560 } 561 else if (value.compare("regex") == 0) 562 { 563 match_info.SetNameMatchType (eNameMatchRegularExpression); 564 } 565 else 566 { 567 success = false; 568 } 569 } 570 else if (key.compare("pid") == 0) 571 { 572 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); 573 } 574 else if (key.compare("parent_pid") == 0) 575 { 576 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); 577 } 578 else if (key.compare("uid") == 0) 579 { 580 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 581 } 582 else if (key.compare("gid") == 0) 583 { 584 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 585 } 586 else if (key.compare("euid") == 0) 587 { 588 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 589 } 590 else if (key.compare("egid") == 0) 591 { 592 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 593 } 594 else if (key.compare("all_users") == 0) 595 { 596 match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success)); 597 } 598 else if (key.compare("triple") == 0) 599 { 600 match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL); 601 } 602 else 603 { 604 success = false; 605 } 606 607 if (!success) 608 return SendErrorResponse (2); 609 } 610 } 611 612 if (Host::FindProcesses (match_info, m_proc_infos)) 613 { 614 // We found something, return the first item by calling the get 615 // subsequent process info packet handler... 616 return Handle_qsProcessInfo (packet); 617 } 618 return SendErrorResponse (3); 619 } 620 621 GDBRemoteCommunication::PacketResult 622 GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet) 623 { 624 if (m_proc_infos_index < m_proc_infos.GetSize()) 625 { 626 StreamString response; 627 CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response); 628 ++m_proc_infos_index; 629 return SendPacketNoLock (response.GetData(), response.GetSize()); 630 } 631 return SendErrorResponse (4); 632 } 633 634 GDBRemoteCommunication::PacketResult 635 GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet) 636 { 637 // Packet format: "qUserName:%i" where %i is the uid 638 packet.SetFilePos(::strlen ("qUserName:")); 639 uint32_t uid = packet.GetU32 (UINT32_MAX); 640 if (uid != UINT32_MAX) 641 { 642 std::string name; 643 if (Host::GetUserName (uid, name)) 644 { 645 StreamString response; 646 response.PutCStringAsRawHex8 (name.c_str()); 647 return SendPacketNoLock (response.GetData(), response.GetSize()); 648 } 649 } 650 return SendErrorResponse (5); 651 652 } 653 654 GDBRemoteCommunication::PacketResult 655 GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet) 656 { 657 // Packet format: "qGroupName:%i" where %i is the gid 658 packet.SetFilePos(::strlen ("qGroupName:")); 659 uint32_t gid = packet.GetU32 (UINT32_MAX); 660 if (gid != UINT32_MAX) 661 { 662 std::string name; 663 if (Host::GetGroupName (gid, name)) 664 { 665 StreamString response; 666 response.PutCStringAsRawHex8 (name.c_str()); 667 return SendPacketNoLock (response.GetData(), response.GetSize()); 668 } 669 } 670 return SendErrorResponse (6); 671 } 672 673 GDBRemoteCommunication::PacketResult 674 GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet) 675 { 676 packet.SetFilePos(::strlen ("qSpeedTest:")); 677 678 std::string key; 679 std::string value; 680 bool success = packet.GetNameColonValue(key, value); 681 if (success && key.compare("response_size") == 0) 682 { 683 uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success); 684 if (success) 685 { 686 if (response_size == 0) 687 return SendOKResponse(); 688 StreamString response; 689 uint32_t bytes_left = response_size; 690 response.PutCString("data:"); 691 while (bytes_left > 0) 692 { 693 if (bytes_left >= 26) 694 { 695 response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 696 bytes_left -= 26; 697 } 698 else 699 { 700 response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 701 bytes_left = 0; 702 } 703 } 704 return SendPacketNoLock (response.GetData(), response.GetSize()); 705 } 706 } 707 return SendErrorResponse (7); 708 } 709 710 // 711 //static bool 712 //WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) 713 //{ 714 // const int time_delta_usecs = 100000; 715 // const int num_retries = timeout_in_seconds/time_delta_usecs; 716 // for (int i=0; i<num_retries; i++) 717 // { 718 // struct proc_bsdinfo bsd_info; 719 // int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO, 720 // (uint64_t) 0, 721 // &bsd_info, 722 // PROC_PIDTBSDINFO_SIZE); 723 // 724 // switch (error) 725 // { 726 // case EINVAL: 727 // case ENOTSUP: 728 // case ESRCH: 729 // case EPERM: 730 // return false; 731 // 732 // default: 733 // break; 734 // 735 // case 0: 736 // if (bsd_info.pbi_status == SSTOP) 737 // return true; 738 // } 739 // ::usleep (time_delta_usecs); 740 // } 741 // return false; 742 //} 743 744 GDBRemoteCommunication::PacketResult 745 GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet) 746 { 747 // The 'A' packet is the most over designed packet ever here with 748 // redundant argument indexes, redundant argument lengths and needed hex 749 // encoded argument string values. Really all that is needed is a comma 750 // separated hex encoded argument value list, but we will stay true to the 751 // documented version of the 'A' packet here... 752 753 packet.SetFilePos(1); // Skip the 'A' 754 bool success = true; 755 while (success && packet.GetBytesLeft() > 0) 756 { 757 // Decode the decimal argument string length. This length is the 758 // number of hex nibbles in the argument string value. 759 const uint32_t arg_len = packet.GetU32(UINT32_MAX); 760 if (arg_len == UINT32_MAX) 761 success = false; 762 else 763 { 764 // Make sure the argument hex string length is followed by a comma 765 if (packet.GetChar() != ',') 766 success = false; 767 else 768 { 769 // Decode the argument index. We ignore this really becuase 770 // who would really send down the arguments in a random order??? 771 const uint32_t arg_idx = packet.GetU32(UINT32_MAX); 772 if (arg_idx == UINT32_MAX) 773 success = false; 774 else 775 { 776 // Make sure the argument index is followed by a comma 777 if (packet.GetChar() != ',') 778 success = false; 779 else 780 { 781 // Decode the argument string value from hex bytes 782 // back into a UTF8 string and make sure the length 783 // matches the one supplied in the packet 784 std::string arg; 785 if (packet.GetHexByteString(arg) != (arg_len / 2)) 786 success = false; 787 else 788 { 789 // If there are any bytes lft 790 if (packet.GetBytesLeft()) 791 { 792 if (packet.GetChar() != ',') 793 success = false; 794 } 795 796 if (success) 797 { 798 if (arg_idx == 0) 799 m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false); 800 m_process_launch_info.GetArguments().AppendArgument(arg.c_str()); 801 } 802 } 803 } 804 } 805 } 806 } 807 } 808 809 if (success) 810 { 811 // FIXME: remove linux restriction once eLaunchFlagDebug is supported 812 #if !defined (__linux__) 813 m_process_launch_info.GetFlags().Set (eLaunchFlagDebug); 814 #endif 815 m_process_launch_error = LaunchProcess (); 816 if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 817 { 818 return SendOKResponse (); 819 } 820 } 821 return SendErrorResponse (8); 822 } 823 824 GDBRemoteCommunication::PacketResult 825 GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet) 826 { 827 lldb::pid_t pid = m_process_launch_info.GetProcessID(); 828 StreamString response; 829 response.Printf("QC%" PRIx64, pid); 830 if (m_is_platform) 831 { 832 // If we launch a process and this GDB server is acting as a platform, 833 // then we need to clear the process launch state so we can start 834 // launching another process. In order to launch a process a bunch or 835 // packets need to be sent: environment packets, working directory, 836 // disable ASLR, and many more settings. When we launch a process we 837 // then need to know when to clear this information. Currently we are 838 // selecting the 'qC' packet as that packet which seems to make the most 839 // sense. 840 if (pid != LLDB_INVALID_PROCESS_ID) 841 { 842 m_process_launch_info.Clear(); 843 } 844 } 845 return SendPacketNoLock (response.GetData(), response.GetSize()); 846 } 847 848 bool 849 GDBRemoteCommunicationServer::DebugserverProcessReaped (lldb::pid_t pid) 850 { 851 Mutex::Locker locker (m_spawned_pids_mutex); 852 FreePortForProcess(pid); 853 return m_spawned_pids.erase(pid) > 0; 854 } 855 bool 856 GDBRemoteCommunicationServer::ReapDebugserverProcess (void *callback_baton, 857 lldb::pid_t pid, 858 bool exited, 859 int signal, // Zero for no signal 860 int status) // Exit value of process if signal is zero 861 { 862 GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton; 863 server->DebugserverProcessReaped (pid); 864 return true; 865 } 866 867 bool 868 GDBRemoteCommunicationServer::DebuggedProcessReaped (lldb::pid_t pid) 869 { 870 // reap a process that we were debugging (but not debugserver) 871 Mutex::Locker locker (m_spawned_pids_mutex); 872 return m_spawned_pids.erase(pid) > 0; 873 } 874 875 bool 876 GDBRemoteCommunicationServer::ReapDebuggedProcess (void *callback_baton, 877 lldb::pid_t pid, 878 bool exited, 879 int signal, // Zero for no signal 880 int status) // Exit value of process if signal is zero 881 { 882 GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton; 883 server->DebuggedProcessReaped (pid); 884 return true; 885 } 886 887 GDBRemoteCommunication::PacketResult 888 GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet) 889 { 890 #ifdef _WIN32 891 return SendErrorResponse(9); 892 #else 893 // Spawn a local debugserver as a platform so we can then attach or launch 894 // a process... 895 896 if (m_is_platform) 897 { 898 // Sleep and wait a bit for debugserver to start to listen... 899 ConnectionFileDescriptor file_conn; 900 Error error; 901 std::string hostname; 902 // TODO: /tmp/ should not be hardcoded. User might want to override /tmp 903 // with the TMPDIR environnement variable 904 packet.SetFilePos(::strlen ("qLaunchGDBServer;")); 905 std::string name; 906 std::string value; 907 uint16_t port = UINT16_MAX; 908 while (packet.GetNameColonValue(name, value)) 909 { 910 if (name.compare ("host") == 0) 911 hostname.swap(value); 912 else if (name.compare ("port") == 0) 913 port = Args::StringToUInt32(value.c_str(), 0, 0); 914 } 915 if (port == UINT16_MAX) 916 port = GetNextAvailablePort(); 917 918 // Spawn a new thread to accept the port that gets bound after 919 // binding to port 0 (zero). 920 921 if (error.Success()) 922 { 923 // Spawn a debugserver and try to get the port it listens to. 924 ProcessLaunchInfo debugserver_launch_info; 925 if (hostname.empty()) 926 hostname = "127.0.0.1"; 927 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 928 if (log) 929 log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port); 930 931 debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); 932 933 error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(), 934 port, 935 debugserver_launch_info, 936 port); 937 938 lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); 939 940 941 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 942 { 943 Mutex::Locker locker (m_spawned_pids_mutex); 944 m_spawned_pids.insert(debugserver_pid); 945 if (port > 0) 946 AssociatePortWithProcess(port, debugserver_pid); 947 } 948 else 949 { 950 if (port > 0) 951 FreePort (port); 952 } 953 954 if (error.Success()) 955 { 956 char response[256]; 957 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset); 958 assert (response_len < (int)sizeof(response)); 959 PacketResult packet_result = SendPacketNoLock (response, response_len); 960 961 if (packet_result != PacketResult::Success) 962 { 963 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 964 ::kill (debugserver_pid, SIGINT); 965 } 966 return packet_result; 967 } 968 } 969 } 970 return SendErrorResponse (9); 971 #endif 972 } 973 974 bool 975 GDBRemoteCommunicationServer::KillSpawnedProcess (lldb::pid_t pid) 976 { 977 // make sure we know about this process 978 { 979 Mutex::Locker locker (m_spawned_pids_mutex); 980 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 981 return false; 982 } 983 984 // first try a SIGTERM (standard kill) 985 Host::Kill (pid, SIGTERM); 986 987 // check if that worked 988 for (size_t i=0; i<10; ++i) 989 { 990 { 991 Mutex::Locker locker (m_spawned_pids_mutex); 992 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 993 { 994 // it is now killed 995 return true; 996 } 997 } 998 usleep (10000); 999 } 1000 1001 // check one more time after the final usleep 1002 { 1003 Mutex::Locker locker (m_spawned_pids_mutex); 1004 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1005 return true; 1006 } 1007 1008 // the launched process still lives. Now try killling it again, 1009 // this time with an unblockable signal. 1010 Host::Kill (pid, SIGKILL); 1011 1012 for (size_t i=0; i<10; ++i) 1013 { 1014 { 1015 Mutex::Locker locker (m_spawned_pids_mutex); 1016 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1017 { 1018 // it is now killed 1019 return true; 1020 } 1021 } 1022 usleep (10000); 1023 } 1024 1025 // check one more time after the final usleep 1026 // Scope for locker 1027 { 1028 Mutex::Locker locker (m_spawned_pids_mutex); 1029 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1030 return true; 1031 } 1032 1033 // no luck - the process still lives 1034 return false; 1035 } 1036 1037 GDBRemoteCommunication::PacketResult 1038 GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet) 1039 { 1040 packet.SetFilePos(::strlen ("qKillSpawnedProcess:")); 1041 1042 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID); 1043 1044 // verify that we know anything about this pid. 1045 // Scope for locker 1046 { 1047 Mutex::Locker locker (m_spawned_pids_mutex); 1048 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1049 { 1050 // not a pid we know about 1051 return SendErrorResponse (10); 1052 } 1053 } 1054 1055 // go ahead and attempt to kill the spawned process 1056 if (KillSpawnedProcess (pid)) 1057 return SendOKResponse (); 1058 else 1059 return SendErrorResponse (11); 1060 } 1061 1062 GDBRemoteCommunication::PacketResult 1063 GDBRemoteCommunicationServer::Handle_k (StringExtractorGDBRemote &packet) 1064 { 1065 // ignore for now if we're lldb_platform 1066 if (m_is_platform) 1067 return SendUnimplementedResponse (packet.GetStringRef().c_str()); 1068 1069 // shutdown all spawned processes 1070 std::set<lldb::pid_t> spawned_pids_copy; 1071 1072 // copy pids 1073 { 1074 Mutex::Locker locker (m_spawned_pids_mutex); 1075 spawned_pids_copy.insert (m_spawned_pids.begin (), m_spawned_pids.end ()); 1076 } 1077 1078 // nuke the spawned processes 1079 for (auto it = spawned_pids_copy.begin (); it != spawned_pids_copy.end (); ++it) 1080 { 1081 lldb::pid_t spawned_pid = *it; 1082 if (!KillSpawnedProcess (spawned_pid)) 1083 { 1084 fprintf (stderr, "%s: failed to kill spawned pid %" PRIu64 ", ignoring.\n", __FUNCTION__, spawned_pid); 1085 } 1086 } 1087 1088 // TODO figure out how to shut down gracefully at this point 1089 return SendOKResponse (); 1090 } 1091 1092 GDBRemoteCommunication::PacketResult 1093 GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet) 1094 { 1095 if (m_process_launch_error.Success()) 1096 return SendOKResponse(); 1097 StreamString response; 1098 response.PutChar('E'); 1099 response.PutCString(m_process_launch_error.AsCString("<unknown error>")); 1100 return SendPacketNoLock (response.GetData(), response.GetSize()); 1101 } 1102 1103 GDBRemoteCommunication::PacketResult 1104 GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &packet) 1105 { 1106 packet.SetFilePos(::strlen ("QEnvironment:")); 1107 const uint32_t bytes_left = packet.GetBytesLeft(); 1108 if (bytes_left > 0) 1109 { 1110 m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek()); 1111 return SendOKResponse (); 1112 } 1113 return SendErrorResponse (12); 1114 } 1115 1116 GDBRemoteCommunication::PacketResult 1117 GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &packet) 1118 { 1119 packet.SetFilePos(::strlen ("QLaunchArch:")); 1120 const uint32_t bytes_left = packet.GetBytesLeft(); 1121 if (bytes_left > 0) 1122 { 1123 const char* arch_triple = packet.Peek(); 1124 ArchSpec arch_spec(arch_triple,NULL); 1125 m_process_launch_info.SetArchitecture(arch_spec); 1126 return SendOKResponse(); 1127 } 1128 return SendErrorResponse(13); 1129 } 1130 1131 GDBRemoteCommunication::PacketResult 1132 GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet) 1133 { 1134 packet.SetFilePos(::strlen ("QSetDisableASLR:")); 1135 if (packet.GetU32(0)) 1136 m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR); 1137 else 1138 m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); 1139 return SendOKResponse (); 1140 } 1141 1142 GDBRemoteCommunication::PacketResult 1143 GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet) 1144 { 1145 packet.SetFilePos(::strlen ("QSetWorkingDir:")); 1146 std::string path; 1147 packet.GetHexByteString(path); 1148 if (m_is_platform) 1149 { 1150 #ifdef _WIN32 1151 // Not implemented on Windows 1152 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_QSetWorkingDir unimplemented"); 1153 #else 1154 // If this packet is sent to a platform, then change the current working directory 1155 if (::chdir(path.c_str()) != 0) 1156 return SendErrorResponse(errno); 1157 #endif 1158 } 1159 else 1160 { 1161 m_process_launch_info.SwapWorkingDirectory (path); 1162 } 1163 return SendOKResponse (); 1164 } 1165 1166 GDBRemoteCommunication::PacketResult 1167 GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet) 1168 { 1169 StreamString response; 1170 1171 if (m_is_platform) 1172 { 1173 // If this packet is sent to a platform, then change the current working directory 1174 char cwd[PATH_MAX]; 1175 if (getcwd(cwd, sizeof(cwd)) == NULL) 1176 { 1177 return SendErrorResponse(errno); 1178 } 1179 else 1180 { 1181 response.PutBytesAsRawHex8(cwd, strlen(cwd)); 1182 return SendPacketNoLock(response.GetData(), response.GetSize()); 1183 } 1184 } 1185 else 1186 { 1187 const char *working_dir = m_process_launch_info.GetWorkingDirectory(); 1188 if (working_dir && working_dir[0]) 1189 { 1190 response.PutBytesAsRawHex8(working_dir, strlen(working_dir)); 1191 return SendPacketNoLock(response.GetData(), response.GetSize()); 1192 } 1193 else 1194 { 1195 return SendErrorResponse(14); 1196 } 1197 } 1198 } 1199 1200 GDBRemoteCommunication::PacketResult 1201 GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet) 1202 { 1203 packet.SetFilePos(::strlen ("QSetSTDIN:")); 1204 ProcessLaunchInfo::FileAction file_action; 1205 std::string path; 1206 packet.GetHexByteString(path); 1207 const bool read = false; 1208 const bool write = true; 1209 if (file_action.Open(STDIN_FILENO, path.c_str(), read, write)) 1210 { 1211 m_process_launch_info.AppendFileAction(file_action); 1212 return SendOKResponse (); 1213 } 1214 return SendErrorResponse (15); 1215 } 1216 1217 GDBRemoteCommunication::PacketResult 1218 GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet) 1219 { 1220 packet.SetFilePos(::strlen ("QSetSTDOUT:")); 1221 ProcessLaunchInfo::FileAction file_action; 1222 std::string path; 1223 packet.GetHexByteString(path); 1224 const bool read = true; 1225 const bool write = false; 1226 if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write)) 1227 { 1228 m_process_launch_info.AppendFileAction(file_action); 1229 return SendOKResponse (); 1230 } 1231 return SendErrorResponse (16); 1232 } 1233 1234 GDBRemoteCommunication::PacketResult 1235 GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet) 1236 { 1237 packet.SetFilePos(::strlen ("QSetSTDERR:")); 1238 ProcessLaunchInfo::FileAction file_action; 1239 std::string path; 1240 packet.GetHexByteString(path); 1241 const bool read = true; 1242 const bool write = false; 1243 if (file_action.Open(STDERR_FILENO, path.c_str(), read, write)) 1244 { 1245 m_process_launch_info.AppendFileAction(file_action); 1246 return SendOKResponse (); 1247 } 1248 return SendErrorResponse (17); 1249 } 1250 1251 GDBRemoteCommunication::PacketResult 1252 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet) 1253 { 1254 // Send response first before changing m_send_acks to we ack this packet 1255 PacketResult packet_result = SendOKResponse (); 1256 m_send_acks = false; 1257 return packet_result; 1258 } 1259 1260 GDBRemoteCommunication::PacketResult 1261 GDBRemoteCommunicationServer::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet) 1262 { 1263 packet.SetFilePos(::strlen("qPlatform_mkdir:")); 1264 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1265 if (packet.GetChar() == ',') 1266 { 1267 std::string path; 1268 packet.GetHexByteString(path); 1269 Error error = Host::MakeDirectory(path.c_str(),mode); 1270 if (error.Success()) 1271 return SendPacketNoLock ("OK", 2); 1272 else 1273 return SendErrorResponse(error.GetError()); 1274 } 1275 return SendErrorResponse(20); 1276 } 1277 1278 GDBRemoteCommunication::PacketResult 1279 GDBRemoteCommunicationServer::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet) 1280 { 1281 packet.SetFilePos(::strlen("qPlatform_chmod:")); 1282 1283 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1284 if (packet.GetChar() == ',') 1285 { 1286 std::string path; 1287 packet.GetHexByteString(path); 1288 Error error = Host::SetFilePermissions (path.c_str(), mode); 1289 if (error.Success()) 1290 return SendPacketNoLock ("OK", 2); 1291 else 1292 return SendErrorResponse(error.GetError()); 1293 } 1294 return SendErrorResponse(19); 1295 } 1296 1297 GDBRemoteCommunication::PacketResult 1298 GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet) 1299 { 1300 packet.SetFilePos(::strlen("vFile:open:")); 1301 std::string path; 1302 packet.GetHexByteStringTerminatedBy(path,','); 1303 if (!path.empty()) 1304 { 1305 if (packet.GetChar() == ',') 1306 { 1307 uint32_t flags = packet.GetHexMaxU32(false, 0); 1308 if (packet.GetChar() == ',') 1309 { 1310 mode_t mode = packet.GetHexMaxU32(false, 0600); 1311 Error error; 1312 int fd = ::open (path.c_str(), flags, mode); 1313 const int save_errno = fd == -1 ? errno : 0; 1314 StreamString response; 1315 response.PutChar('F'); 1316 response.Printf("%i", fd); 1317 if (save_errno) 1318 response.Printf(",%i", save_errno); 1319 return SendPacketNoLock(response.GetData(), response.GetSize()); 1320 } 1321 } 1322 } 1323 return SendErrorResponse(18); 1324 } 1325 1326 GDBRemoteCommunication::PacketResult 1327 GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet) 1328 { 1329 packet.SetFilePos(::strlen("vFile:close:")); 1330 int fd = packet.GetS32(-1); 1331 Error error; 1332 int err = -1; 1333 int save_errno = 0; 1334 if (fd >= 0) 1335 { 1336 err = close(fd); 1337 save_errno = err == -1 ? errno : 0; 1338 } 1339 else 1340 { 1341 save_errno = EINVAL; 1342 } 1343 StreamString response; 1344 response.PutChar('F'); 1345 response.Printf("%i", err); 1346 if (save_errno) 1347 response.Printf(",%i", save_errno); 1348 return SendPacketNoLock(response.GetData(), response.GetSize()); 1349 } 1350 1351 GDBRemoteCommunication::PacketResult 1352 GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet) 1353 { 1354 #ifdef _WIN32 1355 // Not implemented on Windows 1356 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pRead() unimplemented"); 1357 #else 1358 StreamGDBRemote response; 1359 packet.SetFilePos(::strlen("vFile:pread:")); 1360 int fd = packet.GetS32(-1); 1361 if (packet.GetChar() == ',') 1362 { 1363 uint64_t count = packet.GetU64(UINT64_MAX); 1364 if (packet.GetChar() == ',') 1365 { 1366 uint64_t offset = packet.GetU64(UINT32_MAX); 1367 if (count == UINT64_MAX) 1368 { 1369 response.Printf("F-1:%i", EINVAL); 1370 return SendPacketNoLock(response.GetData(), response.GetSize()); 1371 } 1372 1373 std::string buffer(count, 0); 1374 const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset); 1375 const int save_errno = bytes_read == -1 ? errno : 0; 1376 response.PutChar('F'); 1377 response.Printf("%zi", bytes_read); 1378 if (save_errno) 1379 response.Printf(",%i", save_errno); 1380 else 1381 { 1382 response.PutChar(';'); 1383 response.PutEscapedBytes(&buffer[0], bytes_read); 1384 } 1385 return SendPacketNoLock(response.GetData(), response.GetSize()); 1386 } 1387 } 1388 return SendErrorResponse(21); 1389 1390 #endif 1391 } 1392 1393 GDBRemoteCommunication::PacketResult 1394 GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet) 1395 { 1396 #ifdef _WIN32 1397 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pWrite() unimplemented"); 1398 #else 1399 packet.SetFilePos(::strlen("vFile:pwrite:")); 1400 1401 StreamGDBRemote response; 1402 response.PutChar('F'); 1403 1404 int fd = packet.GetU32(UINT32_MAX); 1405 if (packet.GetChar() == ',') 1406 { 1407 off_t offset = packet.GetU64(UINT32_MAX); 1408 if (packet.GetChar() == ',') 1409 { 1410 std::string buffer; 1411 if (packet.GetEscapedBinaryData(buffer)) 1412 { 1413 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset); 1414 const int save_errno = bytes_written == -1 ? errno : 0; 1415 response.Printf("%zi", bytes_written); 1416 if (save_errno) 1417 response.Printf(",%i", save_errno); 1418 } 1419 else 1420 { 1421 response.Printf ("-1,%i", EINVAL); 1422 } 1423 return SendPacketNoLock(response.GetData(), response.GetSize()); 1424 } 1425 } 1426 return SendErrorResponse(27); 1427 #endif 1428 } 1429 1430 GDBRemoteCommunication::PacketResult 1431 GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packet) 1432 { 1433 packet.SetFilePos(::strlen("vFile:size:")); 1434 std::string path; 1435 packet.GetHexByteString(path); 1436 if (!path.empty()) 1437 { 1438 lldb::user_id_t retcode = Host::GetFileSize(FileSpec(path.c_str(), false)); 1439 StreamString response; 1440 response.PutChar('F'); 1441 response.PutHex64(retcode); 1442 if (retcode == UINT64_MAX) 1443 { 1444 response.PutChar(','); 1445 response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode() 1446 } 1447 return SendPacketNoLock(response.GetData(), response.GetSize()); 1448 } 1449 return SendErrorResponse(22); 1450 } 1451 1452 GDBRemoteCommunication::PacketResult 1453 GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packet) 1454 { 1455 packet.SetFilePos(::strlen("vFile:mode:")); 1456 std::string path; 1457 packet.GetHexByteString(path); 1458 if (!path.empty()) 1459 { 1460 Error error; 1461 const uint32_t mode = File::GetPermissions(path.c_str(), error); 1462 StreamString response; 1463 response.Printf("F%u", mode); 1464 if (mode == 0 || error.Fail()) 1465 response.Printf(",%i", (int)error.GetError()); 1466 return SendPacketNoLock(response.GetData(), response.GetSize()); 1467 } 1468 return SendErrorResponse(23); 1469 } 1470 1471 GDBRemoteCommunication::PacketResult 1472 GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &packet) 1473 { 1474 packet.SetFilePos(::strlen("vFile:exists:")); 1475 std::string path; 1476 packet.GetHexByteString(path); 1477 if (!path.empty()) 1478 { 1479 bool retcode = Host::GetFileExists(FileSpec(path.c_str(), false)); 1480 StreamString response; 1481 response.PutChar('F'); 1482 response.PutChar(','); 1483 if (retcode) 1484 response.PutChar('1'); 1485 else 1486 response.PutChar('0'); 1487 return SendPacketNoLock(response.GetData(), response.GetSize()); 1488 } 1489 return SendErrorResponse(24); 1490 } 1491 1492 GDBRemoteCommunication::PacketResult 1493 GDBRemoteCommunicationServer::Handle_vFile_symlink (StringExtractorGDBRemote &packet) 1494 { 1495 packet.SetFilePos(::strlen("vFile:symlink:")); 1496 std::string dst, src; 1497 packet.GetHexByteStringTerminatedBy(dst, ','); 1498 packet.GetChar(); // Skip ',' char 1499 packet.GetHexByteString(src); 1500 Error error = Host::Symlink(src.c_str(), dst.c_str()); 1501 StreamString response; 1502 response.Printf("F%u,%u", error.GetError(), error.GetError()); 1503 return SendPacketNoLock(response.GetData(), response.GetSize()); 1504 } 1505 1506 GDBRemoteCommunication::PacketResult 1507 GDBRemoteCommunicationServer::Handle_vFile_unlink (StringExtractorGDBRemote &packet) 1508 { 1509 packet.SetFilePos(::strlen("vFile:unlink:")); 1510 std::string path; 1511 packet.GetHexByteString(path); 1512 Error error = Host::Unlink(path.c_str()); 1513 StreamString response; 1514 response.Printf("F%u,%u", error.GetError(), error.GetError()); 1515 return SendPacketNoLock(response.GetData(), response.GetSize()); 1516 } 1517 1518 GDBRemoteCommunication::PacketResult 1519 GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &packet) 1520 { 1521 packet.SetFilePos(::strlen("qPlatform_shell:")); 1522 std::string path; 1523 std::string working_dir; 1524 packet.GetHexByteStringTerminatedBy(path,','); 1525 if (!path.empty()) 1526 { 1527 if (packet.GetChar() == ',') 1528 { 1529 // FIXME: add timeout to qPlatform_shell packet 1530 // uint32_t timeout = packet.GetHexMaxU32(false, 32); 1531 uint32_t timeout = 10; 1532 if (packet.GetChar() == ',') 1533 packet.GetHexByteString(working_dir); 1534 int status, signo; 1535 std::string output; 1536 Error err = Host::RunShellCommand(path.c_str(), 1537 working_dir.empty() ? NULL : working_dir.c_str(), 1538 &status, &signo, &output, timeout); 1539 StreamGDBRemote response; 1540 if (err.Fail()) 1541 { 1542 response.PutCString("F,"); 1543 response.PutHex32(UINT32_MAX); 1544 } 1545 else 1546 { 1547 response.PutCString("F,"); 1548 response.PutHex32(status); 1549 response.PutChar(','); 1550 response.PutHex32(signo); 1551 response.PutChar(','); 1552 response.PutEscapedBytes(output.c_str(), output.size()); 1553 } 1554 return SendPacketNoLock(response.GetData(), response.GetSize()); 1555 } 1556 } 1557 return SendErrorResponse(24); 1558 } 1559 1560 GDBRemoteCommunication::PacketResult 1561 GDBRemoteCommunicationServer::Handle_vFile_Stat (StringExtractorGDBRemote &packet) 1562 { 1563 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_Stat() unimplemented"); 1564 } 1565 1566 GDBRemoteCommunication::PacketResult 1567 GDBRemoteCommunicationServer::Handle_vFile_MD5 (StringExtractorGDBRemote &packet) 1568 { 1569 packet.SetFilePos(::strlen("vFile:MD5:")); 1570 std::string path; 1571 packet.GetHexByteString(path); 1572 if (!path.empty()) 1573 { 1574 uint64_t a,b; 1575 StreamGDBRemote response; 1576 if (Host::CalculateMD5(FileSpec(path.c_str(),false),a,b) == false) 1577 { 1578 response.PutCString("F,"); 1579 response.PutCString("x"); 1580 } 1581 else 1582 { 1583 response.PutCString("F,"); 1584 response.PutHex64(a); 1585 response.PutHex64(b); 1586 } 1587 return SendPacketNoLock(response.GetData(), response.GetSize()); 1588 } 1589 return SendErrorResponse(25); 1590 } 1591 1592