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