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