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 #include "Plugins/Process/Utility/GDBRemoteSignals.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 module_spec.GetUUID().IsValid()) 146 { 147 if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) 148 { 149 error = ModuleList::GetSharedModule (resolved_module_spec, 150 exe_module_sp, 151 module_search_paths_ptr, 152 NULL, 153 NULL); 154 155 if (exe_module_sp && exe_module_sp->GetObjectFile()) 156 return error; 157 exe_module_sp.reset(); 158 } 159 // No valid architecture was specified or the exact arch wasn't 160 // found so ask the platform for the architectures that we should be 161 // using (in the correct order) and see if we can find a match that way 162 StreamString arch_names; 163 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) 164 { 165 error = ModuleList::GetSharedModule (resolved_module_spec, 166 exe_module_sp, 167 module_search_paths_ptr, 168 NULL, 169 NULL); 170 // Did we find an executable using one of the 171 if (error.Success()) 172 { 173 if (exe_module_sp && exe_module_sp->GetObjectFile()) 174 break; 175 else 176 error.SetErrorToGenericError(); 177 } 178 179 if (idx > 0) 180 arch_names.PutCString (", "); 181 arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); 182 } 183 184 if (error.Fail() || !exe_module_sp) 185 { 186 if (resolved_module_spec.GetFileSpec().Readable()) 187 { 188 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", 189 resolved_module_spec.GetFileSpec().GetPath().c_str(), 190 GetPluginName().GetCString(), 191 arch_names.GetString().c_str()); 192 } 193 else 194 { 195 error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); 196 } 197 } 198 } 199 else 200 { 201 error.SetErrorStringWithFormat ("'%s' does not exist", 202 resolved_module_spec.GetFileSpec().GetPath().c_str()); 203 } 204 205 return error; 206 } 207 208 bool 209 PlatformRemoteGDBServer::GetModuleSpec (const FileSpec& module_file_spec, 210 const ArchSpec& arch, 211 ModuleSpec &module_spec) 212 { 213 Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM); 214 215 const auto module_path = module_file_spec.GetPath (false); 216 217 if (!m_gdb_client.GetModuleInfo (module_file_spec, arch, module_spec)) 218 { 219 if (log) 220 log->Printf ("PlatformRemoteGDBServer::%s - failed to get module info for %s:%s", 221 __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str ()); 222 return false; 223 } 224 225 if (log) 226 { 227 StreamString stream; 228 module_spec.Dump (stream); 229 log->Printf ("PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s", 230 __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str (), stream.GetString ().c_str ()); 231 } 232 233 return true; 234 } 235 236 Error 237 PlatformRemoteGDBServer::GetFileWithUUID (const FileSpec &platform_file, 238 const UUID *uuid_ptr, 239 FileSpec &local_file) 240 { 241 // Default to the local case 242 local_file = platform_file; 243 return Error(); 244 } 245 246 //------------------------------------------------------------------ 247 /// Default Constructor 248 //------------------------------------------------------------------ 249 PlatformRemoteGDBServer::PlatformRemoteGDBServer () : 250 Platform (false), // This is a remote platform 251 m_gdb_client () 252 { 253 } 254 255 //------------------------------------------------------------------ 256 /// Destructor. 257 /// 258 /// The destructor is virtual since this class is designed to be 259 /// inherited from by the plug-in instance. 260 //------------------------------------------------------------------ 261 PlatformRemoteGDBServer::~PlatformRemoteGDBServer() 262 { 263 } 264 265 bool 266 PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 267 { 268 ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture(); 269 270 if (idx == 0) 271 { 272 arch = remote_arch; 273 return arch.IsValid(); 274 } 275 else if (idx == 1 && remote_arch.IsValid() && remote_arch.GetTriple().isArch64Bit()) 276 { 277 arch.SetTriple(remote_arch.GetTriple().get32BitArchVariant()); 278 return arch.IsValid(); 279 } 280 return false; 281 } 282 283 size_t 284 PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) 285 { 286 // This isn't needed if the z/Z packets are supported in the GDB remote 287 // server. But we might need a packet to detect this. 288 return 0; 289 } 290 291 bool 292 PlatformRemoteGDBServer::GetRemoteOSVersion () 293 { 294 uint32_t major, minor, update; 295 if (m_gdb_client.GetOSVersion (major, minor, update)) 296 { 297 m_major_os_version = major; 298 m_minor_os_version = minor; 299 m_update_os_version = update; 300 return true; 301 } 302 return false; 303 } 304 305 bool 306 PlatformRemoteGDBServer::GetRemoteOSBuildString (std::string &s) 307 { 308 return m_gdb_client.GetOSBuildString (s); 309 } 310 311 bool 312 PlatformRemoteGDBServer::GetRemoteOSKernelDescription (std::string &s) 313 { 314 return m_gdb_client.GetOSKernelDescription (s); 315 } 316 317 // Remote Platform subclasses need to override this function 318 ArchSpec 319 PlatformRemoteGDBServer::GetRemoteSystemArchitecture () 320 { 321 return m_gdb_client.GetSystemArchitecture(); 322 } 323 324 FileSpec 325 PlatformRemoteGDBServer::GetRemoteWorkingDirectory() 326 { 327 if (IsConnected()) 328 { 329 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 330 FileSpec working_dir; 331 if (m_gdb_client.GetWorkingDir(working_dir) && log) 332 log->Printf("PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'", 333 working_dir.GetCString()); 334 return working_dir; 335 } 336 else 337 { 338 return Platform::GetRemoteWorkingDirectory(); 339 } 340 } 341 342 bool 343 PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const FileSpec &working_dir) 344 { 345 if (IsConnected()) 346 { 347 // Clear the working directory it case it doesn't get set correctly. This will 348 // for use to re-read it 349 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 350 if (log) 351 log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')", 352 working_dir.GetCString()); 353 return m_gdb_client.SetWorkingDir(working_dir) == 0; 354 } 355 else 356 return Platform::SetRemoteWorkingDirectory(working_dir); 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 m_gdb_client.SetConnection(new ConnectionFileDescriptor()); 379 // we're going to reuse the hostname when we connect to the debugserver 380 int port; 381 std::string path; 382 const char *url = args.GetArgumentAtIndex(0); 383 if (!url) 384 return Error("URL is null."); 385 if (!UriParser::Parse(url, m_platform_scheme, m_platform_hostname, port, path)) 386 return Error("Invalid URL: %s", url); 387 388 const ConnectionStatus status = m_gdb_client.Connect(url, &error); 389 if (status == eConnectionStatusSuccess) 390 { 391 if (m_gdb_client.HandshakeWithServer(&error)) 392 { 393 m_gdb_client.GetHostInfo(); 394 // If a working directory was set prior to connecting, send it down now 395 if (m_working_dir) 396 m_gdb_client.SetWorkingDir(m_working_dir); 397 } 398 else 399 { 400 m_gdb_client.Disconnect(); 401 if (error.Success()) 402 error.SetErrorString("handshake failed"); 403 } 404 } 405 } 406 else 407 { 408 error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>"); 409 } 410 } 411 return error; 412 } 413 414 Error 415 PlatformRemoteGDBServer::DisconnectRemote () 416 { 417 Error error; 418 m_gdb_client.Disconnect(&error); 419 m_remote_signals_sp.reset(); 420 return error; 421 } 422 423 const char * 424 PlatformRemoteGDBServer::GetHostname () 425 { 426 m_gdb_client.GetHostname (m_name); 427 if (m_name.empty()) 428 return NULL; 429 return m_name.c_str(); 430 } 431 432 const char * 433 PlatformRemoteGDBServer::GetUserName (uint32_t uid) 434 { 435 // Try and get a cache user name first 436 const char *cached_user_name = Platform::GetUserName(uid); 437 if (cached_user_name) 438 return cached_user_name; 439 std::string name; 440 if (m_gdb_client.GetUserName(uid, name)) 441 return SetCachedUserName(uid, name.c_str(), name.size()); 442 443 SetUserNameNotFound(uid); // Negative cache so we don't keep sending packets 444 return NULL; 445 } 446 447 const char * 448 PlatformRemoteGDBServer::GetGroupName (uint32_t gid) 449 { 450 const char *cached_group_name = Platform::GetGroupName(gid); 451 if (cached_group_name) 452 return cached_group_name; 453 std::string name; 454 if (m_gdb_client.GetGroupName(gid, name)) 455 return SetCachedGroupName(gid, name.c_str(), name.size()); 456 457 SetGroupNameNotFound(gid); // Negative cache so we don't keep sending packets 458 return NULL; 459 } 460 461 uint32_t 462 PlatformRemoteGDBServer::FindProcesses (const ProcessInstanceInfoMatch &match_info, 463 ProcessInstanceInfoList &process_infos) 464 { 465 return m_gdb_client.FindProcesses (match_info, process_infos); 466 } 467 468 bool 469 PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 470 { 471 return m_gdb_client.GetProcessInfo (pid, process_info); 472 } 473 474 475 Error 476 PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) 477 { 478 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); 479 Error error; 480 481 if (log) 482 log->Printf ("PlatformRemoteGDBServer::%s() called", __FUNCTION__); 483 484 auto num_file_actions = launch_info.GetNumFileActions (); 485 for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) 486 { 487 const auto file_action = launch_info.GetFileActionAtIndex (i); 488 if (file_action->GetAction () != FileAction::eFileActionOpen) 489 continue; 490 switch(file_action->GetFD()) 491 { 492 case STDIN_FILENO: 493 m_gdb_client.SetSTDIN(file_action->GetFileSpec()); 494 break; 495 case STDOUT_FILENO: 496 m_gdb_client.SetSTDOUT(file_action->GetFileSpec()); 497 break; 498 case STDERR_FILENO: 499 m_gdb_client.SetSTDERR(file_action->GetFileSpec()); 500 break; 501 } 502 } 503 504 m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)); 505 m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError)); 506 507 FileSpec working_dir = launch_info.GetWorkingDirectory(); 508 if (working_dir) 509 { 510 m_gdb_client.SetWorkingDir(working_dir); 511 } 512 513 // Send the environment and the program + arguments after we connect 514 const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 515 516 if (envp) 517 { 518 const char *env_entry; 519 for (int i=0; (env_entry = envp[i]); ++i) 520 { 521 if (m_gdb_client.SendEnvironmentPacket(env_entry) != 0) 522 break; 523 } 524 } 525 526 ArchSpec arch_spec = launch_info.GetArchitecture(); 527 const char *arch_triple = arch_spec.GetTriple().str().c_str(); 528 529 m_gdb_client.SendLaunchArchPacket(arch_triple); 530 if (log) 531 log->Printf ("PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'", __FUNCTION__, arch_triple ? arch_triple : "<NULL>"); 532 533 int arg_packet_err; 534 { 535 // Scope for the scoped timeout object 536 process_gdb_remote::GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_client, 5); 537 arg_packet_err = m_gdb_client.SendArgumentsPacket (launch_info); 538 } 539 540 if (arg_packet_err == 0) 541 { 542 std::string error_str; 543 if (m_gdb_client.GetLaunchSuccess (error_str)) 544 { 545 const auto pid = m_gdb_client.GetCurrentProcessID (false); 546 if (pid != LLDB_INVALID_PROCESS_ID) 547 { 548 launch_info.SetProcessID (pid); 549 if (log) 550 log->Printf ("PlatformRemoteGDBServer::%s() pid %" PRIu64 " launched successfully", __FUNCTION__, pid); 551 } 552 else 553 { 554 if (log) 555 log->Printf ("PlatformRemoteGDBServer::%s() launch succeeded but we didn't get a valid process id back!", __FUNCTION__); 556 error.SetErrorString ("failed to get PID"); 557 } 558 } 559 else 560 { 561 error.SetErrorString (error_str.c_str()); 562 if (log) 563 log->Printf ("PlatformRemoteGDBServer::%s() launch failed: %s", __FUNCTION__, error.AsCString ()); 564 } 565 } 566 else 567 { 568 error.SetErrorStringWithFormat("'A' packet returned an error: %i", arg_packet_err); 569 } 570 return error; 571 } 572 573 Error 574 PlatformRemoteGDBServer::KillProcess (const lldb::pid_t pid) 575 { 576 if (!KillSpawnedProcess(pid)) 577 return Error("failed to kill remote spawned process"); 578 return Error(); 579 } 580 581 lldb::ProcessSP 582 PlatformRemoteGDBServer::DebugProcess (ProcessLaunchInfo &launch_info, 583 Debugger &debugger, 584 Target *target, // Can be NULL, if NULL create a new target, else use existing one 585 Error &error) 586 { 587 lldb::ProcessSP process_sp; 588 if (IsRemote()) 589 { 590 if (IsConnected()) 591 { 592 lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID; 593 uint16_t port = LaunchGDBserverAndGetPort(debugserver_pid); 594 595 if (port == 0) 596 { 597 error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ()); 598 } 599 else 600 { 601 if (target == NULL) 602 { 603 TargetSP new_target_sp; 604 605 error = debugger.GetTargetList().CreateTarget (debugger, 606 NULL, 607 NULL, 608 false, 609 NULL, 610 new_target_sp); 611 target = new_target_sp.get(); 612 } 613 else 614 error.Clear(); 615 616 if (target && error.Success()) 617 { 618 debugger.GetTargetList().SetSelectedTarget(target); 619 620 // The darwin always currently uses the GDB remote debugger plug-in 621 // so even when debugging locally we are debugging remotely! 622 process_sp = target->CreateProcess (launch_info.GetListenerForProcess(debugger), "gdb-remote", NULL); 623 624 if (process_sp) 625 { 626 std::string connect_url = 627 MakeGdbServerUrl(m_platform_scheme, 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 = 723 MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port); 724 error = process_sp->ConnectRemote(nullptr, connect_url.c_str()); 725 if (error.Success()) 726 { 727 auto listener = attach_info.GetHijackListener(); 728 if (listener != nullptr) 729 process_sp->HijackProcessEvents(listener.get()); 730 error = process_sp->Attach(attach_info); 731 } 732 733 if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID) 734 { 735 KillSpawnedProcess(debugserver_pid); 736 } 737 } 738 } 739 } 740 } 741 else 742 { 743 error.SetErrorString("not connected to remote gdb server"); 744 } 745 } 746 return process_sp; 747 } 748 749 Error 750 PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec, uint32_t mode) 751 { 752 Error error = m_gdb_client.MakeDirectory(file_spec, mode); 753 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 754 if (log) 755 log->Printf ("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) error = %u (%s)", 756 file_spec.GetCString(), mode, error.GetError(), error.AsCString()); 757 return error; 758 } 759 760 761 Error 762 PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec, 763 uint32_t &file_permissions) 764 { 765 Error error = m_gdb_client.GetFilePermissions(file_spec, file_permissions); 766 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 767 if (log) 768 log->Printf ("PlatformRemoteGDBServer::GetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", 769 file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString()); 770 return error; 771 } 772 773 Error 774 PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec, 775 uint32_t file_permissions) 776 { 777 Error error = m_gdb_client.SetFilePermissions(file_spec, 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)", 781 file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString()); 782 return error; 783 } 784 785 786 lldb::user_id_t 787 PlatformRemoteGDBServer::OpenFile (const FileSpec& file_spec, 788 uint32_t flags, 789 uint32_t mode, 790 Error &error) 791 { 792 return m_gdb_client.OpenFile (file_spec, flags, mode, error); 793 } 794 795 bool 796 PlatformRemoteGDBServer::CloseFile (lldb::user_id_t fd, Error &error) 797 { 798 return m_gdb_client.CloseFile (fd, error); 799 } 800 801 lldb::user_id_t 802 PlatformRemoteGDBServer::GetFileSize (const FileSpec& file_spec) 803 { 804 return m_gdb_client.GetFileSize(file_spec); 805 } 806 807 uint64_t 808 PlatformRemoteGDBServer::ReadFile (lldb::user_id_t fd, 809 uint64_t offset, 810 void *dst, 811 uint64_t dst_len, 812 Error &error) 813 { 814 return m_gdb_client.ReadFile (fd, offset, dst, dst_len, error); 815 } 816 817 uint64_t 818 PlatformRemoteGDBServer::WriteFile (lldb::user_id_t fd, 819 uint64_t offset, 820 const void* src, 821 uint64_t src_len, 822 Error &error) 823 { 824 return m_gdb_client.WriteFile (fd, offset, src, src_len, error); 825 } 826 827 Error 828 PlatformRemoteGDBServer::PutFile (const FileSpec& source, 829 const FileSpec& destination, 830 uint32_t uid, 831 uint32_t gid) 832 { 833 return Platform::PutFile(source,destination,uid,gid); 834 } 835 836 Error 837 PlatformRemoteGDBServer::CreateSymlink(const FileSpec &src, // The name of the link is in src 838 const FileSpec &dst) // The symlink points to dst 839 { 840 Error error = m_gdb_client.CreateSymlink(src, dst); 841 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 842 if (log) 843 log->Printf ("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') error = %u (%s)", 844 src.GetCString(), dst.GetCString(), error.GetError(), error.AsCString()); 845 return error; 846 } 847 848 Error 849 PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) 850 { 851 Error error = m_gdb_client.Unlink(file_spec); 852 Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); 853 if (log) 854 log->Printf ("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)", 855 file_spec.GetCString(), error.GetError(), error.AsCString()); 856 return error; 857 } 858 859 bool 860 PlatformRemoteGDBServer::GetFileExists (const FileSpec& file_spec) 861 { 862 return m_gdb_client.GetFileExists (file_spec); 863 } 864 865 Error 866 PlatformRemoteGDBServer::RunShellCommand(const char *command, // Shouldn't be NULL 867 const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory 868 int *status_ptr, // Pass NULL if you don't want the process exit status 869 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 870 std::string *command_output, // Pass NULL if you don't want the command output 871 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 872 { 873 return m_gdb_client.RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 874 } 875 876 void 877 PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames () 878 { 879 m_trap_handlers.push_back (ConstString ("_sigtramp")); 880 } 881 882 const UnixSignalsSP & 883 PlatformRemoteGDBServer::GetRemoteUnixSignals() 884 { 885 if (!IsConnected()) 886 return Platform::GetRemoteUnixSignals(); 887 888 if (m_remote_signals_sp) 889 return m_remote_signals_sp; 890 891 // If packet not implemented or JSON failed to parse, 892 // we'll guess the signal set based on the remote architecture. 893 m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture()); 894 895 const char packet[] = "jSignalsInfo"; 896 StringExtractorGDBRemote response; 897 auto result = m_gdb_client.SendPacketAndWaitForResponse( 898 packet, strlen(packet), response, false); 899 900 if (result != decltype(result)::Success || 901 response.GetResponseType() != response.eResponse) 902 return m_remote_signals_sp; 903 904 auto object_sp = StructuredData::ParseJSON(response.GetStringRef()); 905 if (!object_sp || !object_sp->IsValid()) 906 return m_remote_signals_sp; 907 908 auto array_sp = object_sp->GetAsArray(); 909 if (!array_sp || !array_sp->IsValid()) 910 return m_remote_signals_sp; 911 912 auto remote_signals_sp = std::make_shared<lldb_private::GDBRemoteSignals>(); 913 914 bool done = array_sp->ForEach( 915 [&remote_signals_sp](StructuredData::Object *object) -> bool 916 { 917 if (!object || !object->IsValid()) 918 return false; 919 920 auto dict = object->GetAsDictionary(); 921 if (!dict || !dict->IsValid()) 922 return false; 923 924 // Signal number and signal name are required. 925 int signo; 926 if (!dict->GetValueForKeyAsInteger("signo", signo)) 927 return false; 928 929 std::string name; 930 if (!dict->GetValueForKeyAsString("name", name)) 931 return false; 932 933 // We can live without short_name, description, etc. 934 std::string short_name{""}; 935 auto object_sp = dict->GetValueForKey("short_name"); 936 if (object_sp && object_sp->IsValid()) 937 short_name = object_sp->GetStringValue(); 938 939 bool suppress{false}; 940 object_sp = dict->GetValueForKey("suppress"); 941 if (object_sp && object_sp->IsValid()) 942 suppress = object_sp->GetBooleanValue(); 943 944 bool stop{false}; 945 object_sp = dict->GetValueForKey("stop"); 946 if (object_sp && object_sp->IsValid()) 947 stop = object_sp->GetBooleanValue(); 948 949 bool notify{false}; 950 object_sp = dict->GetValueForKey("notify"); 951 if (object_sp && object_sp->IsValid()) 952 notify = object_sp->GetBooleanValue(); 953 954 std::string description{""}; 955 object_sp = dict->GetValueForKey("description"); 956 if (object_sp && object_sp->IsValid()) 957 description = object_sp->GetStringValue(); 958 959 remote_signals_sp->AddSignal(signo, 960 name.c_str(), 961 short_name.c_str(), 962 suppress, stop, notify, 963 description.c_str()); 964 return true; 965 }); 966 967 if (done) 968 m_remote_signals_sp = std::move(remote_signals_sp); 969 970 return m_remote_signals_sp; 971 } 972