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