1 //===-- PlatformRemoteGDBServer.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 "PlatformRemoteGDBServer.h" 11 #include "lldb/Host/Config.h" 12 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Breakpoint/BreakpointLocation.h" 17 #include "lldb/Core/Debugger.h" 18 #include "lldb/Core/Error.h" 19 #include "lldb/Core/Log.h" 20 #include "lldb/Core/Module.h" 21 #include "lldb/Core/ModuleList.h" 22 #include "lldb/Core/ModuleSpec.h" 23 #include "lldb/Core/PluginManager.h" 24 #include "lldb/Core/StreamString.h" 25 #include "lldb/Host/ConnectionFileDescriptor.h" 26 #include "lldb/Host/FileSpec.h" 27 #include "lldb/Host/Host.h" 28 #include "lldb/Host/HostInfo.h" 29 #include "lldb/Host/StringConvert.h" 30 #include "lldb/Target/Process.h" 31 #include "lldb/Target/Target.h" 32 33 #include "Utility/UriParser.h" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 using namespace lldb_private::platform_gdb_server; 38 39 static bool g_initialized = false; 40 41 static std::string MakeGdbServerUrl( 42 const std::string &platform_scheme, 43 const std::string &platform_hostname, 44 uint16_t port) 45 { 46 const char *override_scheme = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME"); 47 const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME"); 48 const char *port_offset_c_str = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET"); 49 int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0; 50 StreamString result; 51 result.Printf("%s://%s:%u", 52 override_scheme ? override_scheme : platform_scheme.c_str(), 53 override_hostname ? override_hostname : platform_hostname.c_str(), 54 port + port_offset); 55 return result.GetString(); 56 } 57 58 void 59 PlatformRemoteGDBServer::Initialize () 60 { 61 Platform::Initialize (); 62 63 if (g_initialized == false) 64 { 65 g_initialized = true; 66 PluginManager::RegisterPlugin (PlatformRemoteGDBServer::GetPluginNameStatic(), 67 PlatformRemoteGDBServer::GetDescriptionStatic(), 68 PlatformRemoteGDBServer::CreateInstance); 69 } 70 } 71 72 void 73 PlatformRemoteGDBServer::Terminate () 74 { 75 if (g_initialized) 76 { 77 g_initialized = false; 78 PluginManager::UnregisterPlugin (PlatformRemoteGDBServer::CreateInstance); 79 } 80 81 Platform::Terminate (); 82 } 83 84 PlatformSP 85 PlatformRemoteGDBServer::CreateInstance (bool force, const ArchSpec *arch) 86 { 87 bool create = force; 88 if (!create) 89 { 90 create = !arch->TripleVendorWasSpecified() && !arch->TripleOSWasSpecified(); 91 } 92 if (create) 93 return PlatformSP(new PlatformRemoteGDBServer()); 94 return PlatformSP(); 95 } 96 97 98 ConstString 99 PlatformRemoteGDBServer::GetPluginNameStatic() 100 { 101 static ConstString g_name("remote-gdb-server"); 102 return g_name; 103 } 104 105 const char * 106 PlatformRemoteGDBServer::GetDescriptionStatic() 107 { 108 return "A platform that uses the GDB remote protocol as the communication transport."; 109 } 110 111 const char * 112 PlatformRemoteGDBServer::GetDescription () 113 { 114 if (m_platform_description.empty()) 115 { 116 if (IsConnected()) 117 { 118 // Send the get description packet 119 } 120 } 121 122 if (!m_platform_description.empty()) 123 return m_platform_description.c_str(); 124 return GetDescriptionStatic(); 125 } 126 127 Error 128 PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec, 129 lldb::ModuleSP &exe_module_sp, 130 const FileSpecList *module_search_paths_ptr) 131 { 132 // copied from PlatformRemoteiOS 133 134 Error error; 135 // Nothing special to do here, just use the actual file and architecture 136 137 ModuleSpec resolved_module_spec(module_spec); 138 139 // Resolve any executable within an apk on Android? 140 //Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); 141 142 if (resolved_module_spec.GetFileSpec().Exists()) 143 { 144 if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) 145 { 146 error = ModuleList::GetSharedModule (resolved_module_spec, 147 exe_module_sp, 148 NULL, 149 NULL, 150 NULL); 151 152 if (exe_module_sp && exe_module_sp->GetObjectFile()) 153 return error; 154 exe_module_sp.reset(); 155 } 156 // No valid architecture was specified or the exact arch wasn't 157 // found so ask the platform for the architectures that we should be 158 // using (in the correct order) and see if we can find a match that way 159 StreamString arch_names; 160 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) 161 { 162 error = ModuleList::GetSharedModule (resolved_module_spec, 163 exe_module_sp, 164 NULL, 165 NULL, 166 NULL); 167 // Did we find an executable using one of the 168 if (error.Success()) 169 { 170 if (exe_module_sp && exe_module_sp->GetObjectFile()) 171 break; 172 else 173 error.SetErrorToGenericError(); 174 } 175 176 if (idx > 0) 177 arch_names.PutCString (", "); 178 arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); 179 } 180 181 if (error.Fail() || !exe_module_sp) 182 { 183 if (resolved_module_spec.GetFileSpec().Readable()) 184 { 185 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", 186 resolved_module_spec.GetFileSpec().GetPath().c_str(), 187 GetPluginName().GetCString(), 188 arch_names.GetString().c_str()); 189 } 190 else 191 { 192 error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); 193 } 194 } 195 } 196 else 197 { 198 error.SetErrorStringWithFormat ("'%s' does not exist", 199 resolved_module_spec.GetFileSpec().GetPath().c_str()); 200 } 201 202 return error; 203 } 204 205 bool 206 PlatformRemoteGDBServer::GetModuleSpec (const FileSpec& module_file_spec, 207 const ArchSpec& arch, 208 ModuleSpec &module_spec) 209 { 210 Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM); 211 212 const auto module_path = module_file_spec.GetPath (false); 213 214 if (!m_gdb_client.GetModuleInfo (module_file_spec, arch, module_spec)) 215 { 216 if (log) 217 log->Printf ("PlatformRemoteGDBServer::%s - failed to get module info for %s:%s", 218 __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str ()); 219 return false; 220 } 221 222 if (log) 223 { 224 StreamString stream; 225 module_spec.Dump (stream); 226 log->Printf ("PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s", 227 __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str (), stream.GetString ().c_str ()); 228 } 229 230 return true; 231 } 232 233 Error 234 PlatformRemoteGDBServer::GetFileWithUUID (const FileSpec &platform_file, 235 const UUID *uuid_ptr, 236 FileSpec &local_file) 237 { 238 // Default to the local case 239 local_file = platform_file; 240 return Error(); 241 } 242 243 //------------------------------------------------------------------ 244 /// Default Constructor 245 //------------------------------------------------------------------ 246 PlatformRemoteGDBServer::PlatformRemoteGDBServer () : 247 Platform (false), // This is a remote platform 248 m_gdb_client () 249 { 250 } 251 252 //------------------------------------------------------------------ 253 /// Destructor. 254 /// 255 /// The destructor is virtual since this class is designed to be 256 /// inherited from by the plug-in instance. 257 //------------------------------------------------------------------ 258 PlatformRemoteGDBServer::~PlatformRemoteGDBServer() 259 { 260 } 261 262 bool 263 PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 264 { 265 ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture(); 266 267 if (idx == 0) 268 { 269 arch = remote_arch; 270 return arch.IsValid(); 271 } 272 else if (idx == 1 && remote_arch.IsValid() && remote_arch.GetTriple().isArch64Bit()) 273 { 274 arch.SetTriple(remote_arch.GetTriple().get32BitArchVariant()); 275 return arch.IsValid(); 276 } 277 return false; 278 } 279 280 size_t 281 PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) 282 { 283 // This isn't needed if the z/Z packets are supported in the GDB remote 284 // server. But we might need a packet to detect this. 285 return 0; 286 } 287 288 bool 289 PlatformRemoteGDBServer::GetRemoteOSVersion () 290 { 291 uint32_t major, minor, update; 292 if (m_gdb_client.GetOSVersion (major, minor, update)) 293 { 294 m_major_os_version = major; 295 m_minor_os_version = minor; 296 m_update_os_version = update; 297 return true; 298 } 299 return false; 300 } 301 302 bool 303 PlatformRemoteGDBServer::GetRemoteOSBuildString (std::string &s) 304 { 305 return m_gdb_client.GetOSBuildString (s); 306 } 307 308 bool 309 PlatformRemoteGDBServer::GetRemoteOSKernelDescription (std::string &s) 310 { 311 return m_gdb_client.GetOSKernelDescription (s); 312 } 313 314 // Remote Platform subclasses need to override this function 315 ArchSpec 316 PlatformRemoteGDBServer::GetRemoteSystemArchitecture () 317 { 318 return m_gdb_client.GetSystemArchitecture(); 319 } 320 321 FileSpec 322 PlatformRemoteGDBServer::GetRemoteWorkingDirectory() 323 { 324 if (IsConnected()) 325 { 326 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 327 FileSpec working_dir; 328 if (m_gdb_client.GetWorkingDir(working_dir) && log) 329 log->Printf("PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'", 330 working_dir.GetCString()); 331 return working_dir; 332 } 333 else 334 { 335 return Platform::GetRemoteWorkingDirectory(); 336 } 337 } 338 339 bool 340 PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const FileSpec &working_dir) 341 { 342 if (IsConnected()) 343 { 344 // Clear the working directory it case it doesn't get set correctly. This will 345 // for use to re-read it 346 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 347 if (log) 348 log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')", 349 working_dir.GetCString()); 350 return m_gdb_client.SetWorkingDir(working_dir) == 0; 351 } 352 else 353 return Platform::SetRemoteWorkingDirectory(working_dir); 354 } 355 356 bool 357 PlatformRemoteGDBServer::IsConnected () const 358 { 359 return m_gdb_client.IsConnected(); 360 } 361 362 Error 363 PlatformRemoteGDBServer::ConnectRemote (Args& args) 364 { 365 Error error; 366 if (IsConnected()) 367 { 368 error.SetErrorStringWithFormat ("the platform is already connected to '%s', execute 'platform disconnect' to close the current connection", 369 GetHostname()); 370 } 371 else 372 { 373 if (args.GetArgumentCount() == 1) 374 { 375 m_gdb_client.SetConnection(new ConnectionFileDescriptor()); 376 // we're going to reuse the hostname when we connect to the debugserver 377 int port; 378 std::string path; 379 const char *url = args.GetArgumentAtIndex(0); 380 if (!url) 381 return Error("URL is null."); 382 if (!UriParser::Parse(url, m_platform_scheme, m_platform_hostname, port, path)) 383 return Error("Invalid URL: %s", url); 384 385 const ConnectionStatus status = m_gdb_client.Connect(url, &error); 386 if (status == eConnectionStatusSuccess) 387 { 388 if (m_gdb_client.HandshakeWithServer(&error)) 389 { 390 m_gdb_client.GetHostInfo(); 391 // If a working directory was set prior to connecting, send it down now 392 if (m_working_dir) 393 m_gdb_client.SetWorkingDir(m_working_dir); 394 } 395 else 396 { 397 m_gdb_client.Disconnect(); 398 if (error.Success()) 399 error.SetErrorString("handshake failed"); 400 } 401 } 402 } 403 else 404 { 405 error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>"); 406 } 407 } 408 return error; 409 } 410 411 Error 412 PlatformRemoteGDBServer::DisconnectRemote () 413 { 414 Error error; 415 m_gdb_client.Disconnect(&error); 416 return error; 417 } 418 419 const char * 420 PlatformRemoteGDBServer::GetHostname () 421 { 422 m_gdb_client.GetHostname (m_name); 423 if (m_name.empty()) 424 return NULL; 425 return m_name.c_str(); 426 } 427 428 const char * 429 PlatformRemoteGDBServer::GetUserName (uint32_t uid) 430 { 431 // Try and get a cache user name first 432 const char *cached_user_name = Platform::GetUserName(uid); 433 if (cached_user_name) 434 return cached_user_name; 435 std::string name; 436 if (m_gdb_client.GetUserName(uid, name)) 437 return SetCachedUserName(uid, name.c_str(), name.size()); 438 439 SetUserNameNotFound(uid); // Negative cache so we don't keep sending packets 440 return NULL; 441 } 442 443 const char * 444 PlatformRemoteGDBServer::GetGroupName (uint32_t gid) 445 { 446 const char *cached_group_name = Platform::GetGroupName(gid); 447 if (cached_group_name) 448 return cached_group_name; 449 std::string name; 450 if (m_gdb_client.GetGroupName(gid, name)) 451 return SetCachedGroupName(gid, name.c_str(), name.size()); 452 453 SetGroupNameNotFound(gid); // Negative cache so we don't keep sending packets 454 return NULL; 455 } 456 457 uint32_t 458 PlatformRemoteGDBServer::FindProcesses (const ProcessInstanceInfoMatch &match_info, 459 ProcessInstanceInfoList &process_infos) 460 { 461 return m_gdb_client.FindProcesses (match_info, process_infos); 462 } 463 464 bool 465 PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 466 { 467 return m_gdb_client.GetProcessInfo (pid, process_info); 468 } 469 470 471 Error 472 PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) 473 { 474 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); 475 Error error; 476 477 if (log) 478 log->Printf ("PlatformRemoteGDBServer::%s() called", __FUNCTION__); 479 480 auto num_file_actions = launch_info.GetNumFileActions (); 481 for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) 482 { 483 const auto file_action = launch_info.GetFileActionAtIndex (i); 484 if (file_action->GetAction () != FileAction::eFileActionOpen) 485 continue; 486 switch(file_action->GetFD()) 487 { 488 case STDIN_FILENO: 489 m_gdb_client.SetSTDIN(file_action->GetFileSpec()); 490 break; 491 case STDOUT_FILENO: 492 m_gdb_client.SetSTDOUT(file_action->GetFileSpec()); 493 break; 494 case STDERR_FILENO: 495 m_gdb_client.SetSTDERR(file_action->GetFileSpec()); 496 break; 497 } 498 } 499 500 m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)); 501 m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError)); 502 503 FileSpec working_dir = launch_info.GetWorkingDirectory(); 504 if (working_dir) 505 { 506 m_gdb_client.SetWorkingDir(working_dir); 507 } 508 509 // Send the environment and the program + arguments after we connect 510 const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 511 512 if (envp) 513 { 514 const char *env_entry; 515 for (int i=0; (env_entry = envp[i]); ++i) 516 { 517 if (m_gdb_client.SendEnvironmentPacket(env_entry) != 0) 518 break; 519 } 520 } 521 522 ArchSpec arch_spec = launch_info.GetArchitecture(); 523 const char *arch_triple = arch_spec.GetTriple().str().c_str(); 524 525 m_gdb_client.SendLaunchArchPacket(arch_triple); 526 if (log) 527 log->Printf ("PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'", __FUNCTION__, arch_triple ? arch_triple : "<NULL>"); 528 529 int arg_packet_err; 530 { 531 // Scope for the scoped timeout object 532 process_gdb_remote::GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_client, 5); 533 arg_packet_err = m_gdb_client.SendArgumentsPacket (launch_info); 534 } 535 536 if (arg_packet_err == 0) 537 { 538 std::string error_str; 539 if (m_gdb_client.GetLaunchSuccess (error_str)) 540 { 541 const auto pid = m_gdb_client.GetCurrentProcessID (false); 542 if (pid != LLDB_INVALID_PROCESS_ID) 543 { 544 launch_info.SetProcessID (pid); 545 if (log) 546 log->Printf ("PlatformRemoteGDBServer::%s() pid %" PRIu64 " launched successfully", __FUNCTION__, pid); 547 } 548 else 549 { 550 if (log) 551 log->Printf ("PlatformRemoteGDBServer::%s() launch succeeded but we didn't get a valid process id back!", __FUNCTION__); 552 error.SetErrorString ("failed to get PID"); 553 } 554 } 555 else 556 { 557 error.SetErrorString (error_str.c_str()); 558 if (log) 559 log->Printf ("PlatformRemoteGDBServer::%s() launch failed: %s", __FUNCTION__, error.AsCString ()); 560 } 561 } 562 else 563 { 564 error.SetErrorStringWithFormat("'A' packet returned an error: %i", arg_packet_err); 565 } 566 return error; 567 } 568 569 Error 570 PlatformRemoteGDBServer::KillProcess (const lldb::pid_t pid) 571 { 572 if (!KillSpawnedProcess(pid)) 573 return Error("failed to kill remote spawned process"); 574 return Error(); 575 } 576 577 lldb::ProcessSP 578 PlatformRemoteGDBServer::DebugProcess (ProcessLaunchInfo &launch_info, 579 Debugger &debugger, 580 Target *target, // Can be NULL, if NULL create a new target, else use existing one 581 Error &error) 582 { 583 lldb::ProcessSP process_sp; 584 if (IsRemote()) 585 { 586 if (IsConnected()) 587 { 588 lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID; 589 uint16_t port = LaunchGDBserverAndGetPort(debugserver_pid); 590 591 if (port == 0) 592 { 593 error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ()); 594 } 595 else 596 { 597 if (target == NULL) 598 { 599 TargetSP new_target_sp; 600 601 error = debugger.GetTargetList().CreateTarget (debugger, 602 NULL, 603 NULL, 604 false, 605 NULL, 606 new_target_sp); 607 target = new_target_sp.get(); 608 } 609 else 610 error.Clear(); 611 612 if (target && error.Success()) 613 { 614 debugger.GetTargetList().SetSelectedTarget(target); 615 616 // The darwin always currently uses the GDB remote debugger plug-in 617 // so even when debugging locally we are debugging remotely! 618 process_sp = target->CreateProcess (launch_info.GetListenerForProcess(debugger), "gdb-remote", NULL); 619 620 if (process_sp) 621 { 622 std::string connect_url = 623 MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port); 624 error = process_sp->ConnectRemote (nullptr, connect_url.c_str()); 625 // Retry the connect remote one time... 626 if (error.Fail()) 627 error = process_sp->ConnectRemote (nullptr, connect_url.c_str()); 628 if (error.Success()) 629 error = process_sp->Launch(launch_info); 630 else if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 631 { 632 printf ("error: connect remote failed (%s)\n", error.AsCString()); 633 KillSpawnedProcess(debugserver_pid); 634 } 635 } 636 } 637 } 638 } 639 else 640 { 641 error.SetErrorString("not connected to remote gdb server"); 642 } 643 } 644 return process_sp; 645 646 } 647 648 uint16_t 649 PlatformRemoteGDBServer::LaunchGDBserverAndGetPort (lldb::pid_t &pid) 650 { 651 ArchSpec remote_arch = GetRemoteSystemArchitecture (); 652 llvm::Triple &remote_triple = remote_arch.GetTriple (); 653 if (remote_triple.getVendor () == llvm::Triple::Apple && remote_triple.getOS () == llvm::Triple::IOS) 654 { 655 // When remote debugging to iOS, we use a USB mux that always talks 656 // to localhost, so we will need the remote debugserver to accept connections 657 // only from localhost, no matter what our current hostname is 658 return m_gdb_client.LaunchGDBserverAndGetPort (pid, "127.0.0.1"); 659 } 660 else 661 { 662 // All other hosts should use their actual hostname 663 return m_gdb_client.LaunchGDBserverAndGetPort (pid, NULL); 664 } 665 } 666 667 bool 668 PlatformRemoteGDBServer::KillSpawnedProcess (lldb::pid_t pid) 669 { 670 return m_gdb_client.KillSpawnedProcess (pid); 671 } 672 673 lldb::ProcessSP 674 PlatformRemoteGDBServer::Attach (ProcessAttachInfo &attach_info, 675 Debugger &debugger, 676 Target *target, // Can be NULL, if NULL create a new target, else use existing one 677 Error &error) 678 { 679 lldb::ProcessSP process_sp; 680 if (IsRemote()) 681 { 682 if (IsConnected()) 683 { 684 lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID; 685 uint16_t port = LaunchGDBserverAndGetPort(debugserver_pid); 686 687 if (port == 0) 688 { 689 error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ()); 690 } 691 else 692 { 693 if (target == NULL) 694 { 695 TargetSP new_target_sp; 696 697 error = debugger.GetTargetList().CreateTarget (debugger, 698 NULL, 699 NULL, 700 false, 701 NULL, 702 new_target_sp); 703 target = new_target_sp.get(); 704 } 705 else 706 error.Clear(); 707 708 if (target && error.Success()) 709 { 710 debugger.GetTargetList().SetSelectedTarget(target); 711 712 // The darwin always currently uses the GDB remote debugger plug-in 713 // so even when debugging locally we are debugging remotely! 714 process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL); 715 716 if (process_sp) 717 { 718 std::string connect_url = 719 MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port); 720 error = process_sp->ConnectRemote(nullptr, connect_url.c_str()); 721 if (error.Success()) 722 { 723 auto listener = attach_info.GetHijackListener(); 724 if (listener != nullptr) 725 process_sp->HijackProcessEvents(listener.get()); 726 error = process_sp->Attach(attach_info); 727 } 728 729 if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID) 730 { 731 KillSpawnedProcess(debugserver_pid); 732 } 733 } 734 } 735 } 736 } 737 else 738 { 739 error.SetErrorString("not connected to remote gdb server"); 740 } 741 } 742 return process_sp; 743 } 744 745 Error 746 PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec, uint32_t mode) 747 { 748 Error error = m_gdb_client.MakeDirectory(file_spec, mode); 749 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 750 if (log) 751 log->Printf ("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) error = %u (%s)", 752 file_spec.GetCString(), mode, error.GetError(), error.AsCString()); 753 return error; 754 } 755 756 757 Error 758 PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec, 759 uint32_t &file_permissions) 760 { 761 Error error = m_gdb_client.GetFilePermissions(file_spec, file_permissions); 762 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 763 if (log) 764 log->Printf ("PlatformRemoteGDBServer::GetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", 765 file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString()); 766 return error; 767 } 768 769 Error 770 PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec, 771 uint32_t file_permissions) 772 { 773 Error error = m_gdb_client.SetFilePermissions(file_spec, file_permissions); 774 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 775 if (log) 776 log->Printf ("PlatformRemoteGDBServer::SetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", 777 file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString()); 778 return error; 779 } 780 781 782 lldb::user_id_t 783 PlatformRemoteGDBServer::OpenFile (const FileSpec& file_spec, 784 uint32_t flags, 785 uint32_t mode, 786 Error &error) 787 { 788 return m_gdb_client.OpenFile (file_spec, flags, mode, error); 789 } 790 791 bool 792 PlatformRemoteGDBServer::CloseFile (lldb::user_id_t fd, Error &error) 793 { 794 return m_gdb_client.CloseFile (fd, error); 795 } 796 797 lldb::user_id_t 798 PlatformRemoteGDBServer::GetFileSize (const FileSpec& file_spec) 799 { 800 return m_gdb_client.GetFileSize(file_spec); 801 } 802 803 uint64_t 804 PlatformRemoteGDBServer::ReadFile (lldb::user_id_t fd, 805 uint64_t offset, 806 void *dst, 807 uint64_t dst_len, 808 Error &error) 809 { 810 return m_gdb_client.ReadFile (fd, offset, dst, dst_len, error); 811 } 812 813 uint64_t 814 PlatformRemoteGDBServer::WriteFile (lldb::user_id_t fd, 815 uint64_t offset, 816 const void* src, 817 uint64_t src_len, 818 Error &error) 819 { 820 return m_gdb_client.WriteFile (fd, offset, src, src_len, error); 821 } 822 823 Error 824 PlatformRemoteGDBServer::PutFile (const FileSpec& source, 825 const FileSpec& destination, 826 uint32_t uid, 827 uint32_t gid) 828 { 829 return Platform::PutFile(source,destination,uid,gid); 830 } 831 832 Error 833 PlatformRemoteGDBServer::CreateSymlink(const FileSpec &src, // The name of the link is in src 834 const FileSpec &dst) // The symlink points to dst 835 { 836 Error error = m_gdb_client.CreateSymlink(src, dst); 837 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 838 if (log) 839 log->Printf ("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') error = %u (%s)", 840 src.GetCString(), dst.GetCString(), error.GetError(), error.AsCString()); 841 return error; 842 } 843 844 Error 845 PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) 846 { 847 Error error = m_gdb_client.Unlink(file_spec); 848 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 849 if (log) 850 log->Printf ("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)", 851 file_spec.GetCString(), error.GetError(), error.AsCString()); 852 return error; 853 } 854 855 bool 856 PlatformRemoteGDBServer::GetFileExists (const FileSpec& file_spec) 857 { 858 return m_gdb_client.GetFileExists (file_spec); 859 } 860 861 Error 862 PlatformRemoteGDBServer::RunShellCommand(const char *command, // Shouldn't be NULL 863 const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory 864 int *status_ptr, // Pass NULL if you don't want the process exit status 865 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 866 std::string *command_output, // Pass NULL if you don't want the command output 867 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 868 { 869 return m_gdb_client.RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 870 } 871 872 void 873 PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames () 874 { 875 m_trap_handlers.push_back (ConstString ("_sigtramp")); 876 } 877