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