10 #include "lldb/Host/Config.h"
45 Platform::Initialize();
49 PluginManager::RegisterPlugin(
50 PlatformRemoteGDBServer::GetPluginNameStatic(),
51 PlatformRemoteGDBServer::GetDescriptionStatic(),
52 PlatformRemoteGDBServer::CreateInstance);
56 void PlatformRemoteGDBServer::Terminate() {
59 PluginManager::UnregisterPlugin(PlatformRemoteGDBServer::CreateInstance);
62 Platform::Terminate();
65 PlatformSP PlatformRemoteGDBServer::CreateInstance(
bool force,
76 llvm::StringRef PlatformRemoteGDBServer::GetDescriptionStatic() {
77 return "A platform that uses the GDB remote protocol as the communication "
81 llvm::StringRef PlatformRemoteGDBServer::GetDescription() {
82 if (m_platform_description.empty()) {
88 if (!m_platform_description.empty())
89 return m_platform_description.c_str();
90 return GetDescriptionStatic();
93 bool PlatformRemoteGDBServer::GetModuleSpec(
const FileSpec &module_file_spec,
98 const auto module_path = module_file_spec.
GetPath(
false);
100 if (!m_gdb_client_up ||
101 !m_gdb_client_up->GetModuleInfo(module_file_spec, arch, module_spec)) {
104 "PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
105 __FUNCTION__, module_path.c_str(),
112 module_spec.
Dump(stream);
114 "PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
115 __FUNCTION__, module_path.c_str(),
123 const UUID *uuid_ptr,
126 local_file = platform_file;
131 PlatformRemoteGDBServer::PlatformRemoteGDBServer()
159 llvm::Optional<std::string>
179 "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
193 LLDB_LOGF(log,
"PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
211 error.SetErrorStringWithFormat(
"the platform is already connected to '%s', "
212 "execute 'platform disconnect' to close the "
213 "current connection",
219 error.SetErrorString(
220 "\"platform connect\" takes a single argument: <connect-url>");
226 return Status(
"URL is null.");
228 llvm::Optional<URI> parsed_url =
URI::Parse(url);
230 return Status(
"Invalid URL: %s", url);
237 std::make_unique<process_gdb_remote::GDBRemoteCommunicationClient>();
238 client_up->SetPacketTimeout(
240 client_up->SetConnection(std::make_unique<ConnectionFileDescriptor>());
246 client_up->Connect(url, &
error);
251 if (client_up->HandshakeWithServer(&
error)) {
263 if (remote_arch.
GetTriple().isArch64Bit())
268 client_up->Disconnect();
270 error.SetErrorString(
"handshake failed");
290 llvm::Optional<std::string>
294 return std::move(name);
298 llvm::Optional<std::string>
302 return std::move(name);
325 LLDB_LOGF(log,
"PlatformRemoteGDBServer::%s() called", __FUNCTION__);
328 return Status(
"Not connected.");
330 for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) {
334 switch (file_action->GetFD()) {
361 const char *arch_triple = arch_spec.
GetTriple().str().c_str();
366 "PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'",
367 __FUNCTION__, arch_triple ? arch_triple :
"<NULL>");
377 if (arg_packet_err == 0) {
384 "PlatformRemoteGDBServer::%s() pid %" PRIu64
385 " launched successfully",
389 "PlatformRemoteGDBServer::%s() launch succeeded but we "
390 "didn't get a valid process id back!",
392 error.SetErrorString(
"failed to get PID");
395 error.SetErrorString(error_str.c_str());
396 LLDB_LOGF(log,
"PlatformRemoteGDBServer::%s() launch failed: %s",
397 __FUNCTION__,
error.AsCString());
400 error.SetErrorStringWithFormat(
"'A' packet returned an error: %i",
408 return Status(
"failed to kill remote spawned process");
416 lldb::ProcessSP process_sp;
422 error.SetErrorStringWithFormat(
"unable to launch a GDB server on '%s'",
428 "gdb-remote",
nullptr,
true);
433 error = process_sp->ConnectRemote(connect_url.c_str());
436 error = process_sp->ConnectRemote(connect_url.c_str());
438 error = process_sp->Launch(launch_info);
440 printf(
"error: connect remote failed (%s)\n",
error.AsCString());
446 error.SetErrorString(
"not connected to remote gdb server");
457 llvm::Triple &remote_triple = remote_arch.
GetTriple();
461 bool launch_result =
false;
462 if (remote_triple.getVendor() == llvm::Triple::Apple &&
463 remote_triple.getOS() == llvm::Triple::IOS) {
480 (socket_name.empty()) ?
nullptr : socket_name.c_str());
494 lldb::ProcessSP process_sp;
500 error.SetErrorStringWithFormat(
"unable to launch a GDB server on '%s'",
503 if (target ==
nullptr) {
504 TargetSP new_target_sp;
508 target = new_target_sp.get();
512 if (target &&
error.Success()) {
517 "gdb-remote",
nullptr,
true);
519 error = process_sp->ConnectRemote(connect_url.c_str());
520 if (
error.Success()) {
523 process_sp->HijackProcessEvents(listener_sp);
524 error = process_sp->Attach(attach_info);
534 error.SetErrorString(
"not connected to remote gdb server");
543 return Status(
"Not connected.");
547 "PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
556 return Status(
"Not connected.");
561 "PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
562 "file_permissions=%o) error = %u (%s)",
571 return Status(
"Not connected.");
576 "PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
577 "file_permissions=%o) error = %u (%s)",
613 void *dst, uint64_t dst_len,
622 const void *src, uint64_t src_len,
641 return Status(
"Not connected.");
645 "PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
654 return Status(
"Not connected.");
657 LLDB_LOGF(log,
"PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
669 llvm::StringRef shell, llvm::StringRef command,
679 return Status(
"Not connected.");
680 return m_gdb_client_up->RunShellCommand(command, working_dir, status_ptr,
681 signo_ptr, command_output, timeout);
701 m_gdb_client_up->SendPacketAndWaitForResponse(
"jSignalsInfo", response);
703 if (result != decltype(result)::
Success ||
709 if (!object_sp || !object_sp->IsValid())
712 auto array_sp = object_sp->GetAsArray();
713 if (!array_sp || !array_sp->IsValid())
716 auto remote_signals_sp = std::make_shared<lldb_private::GDBRemoteSignals>();
718 bool done = array_sp->ForEach(
720 if (!
object || !
object->IsValid())
723 auto dict =
object->GetAsDictionary();
724 if (!dict || !dict->IsValid())
729 if (!dict->GetValueForKeyAsInteger(
"signo", signo))
732 llvm::StringRef name;
733 if (!dict->GetValueForKeyAsString(
"name", name))
737 bool suppress{false};
738 auto object_sp = dict->GetValueForKey(
"suppress");
739 if (object_sp && object_sp->IsValid())
740 suppress = object_sp->GetBooleanValue();
743 object_sp = dict->GetValueForKey(
"stop");
744 if (object_sp && object_sp->IsValid())
745 stop = object_sp->GetBooleanValue();
748 object_sp = dict->GetValueForKey(
"notify");
749 if (object_sp && object_sp->IsValid())
750 notify = object_sp->GetBooleanValue();
753 object_sp = dict->GetValueForKey(
"description");
754 if (object_sp && object_sp->IsValid())
755 description =
std::string(object_sp->GetStringValue());
757 remote_signals_sp->AddSignal(signo, name.str().c_str(), suppress, stop,
758 notify, description.c_str());
770 uint16_t port,
const char *socket_name) {
771 const char *override_scheme =
772 getenv(
"LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME");
773 const char *override_hostname =
774 getenv(
"LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
775 const char *port_offset_c_str =
776 getenv(
"LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
777 int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
779 return MakeUrl(override_scheme ? override_scheme : platform_scheme.c_str(),
780 override_hostname ? override_hostname
781 : platform_hostname.c_str(),
782 port + port_offset, socket_name);
786 const char *hostname,
789 result.
Printf(
"%s://[%s]", scheme, hostname);
791 result.
Printf(
":%u", port);
793 result.
Write(path, strlen(path));
799 std::vector<std::string> connection_urls;
802 for (
size_t i = 0; i < connection_urls.size(); ++i) {
807 return connection_urls.size();
811 std::vector<std::string> &connection_urls) {
812 std::vector<std::pair<uint16_t, std::string>> remote_servers;
816 for (
const auto &gdbserver : remote_servers) {
817 const char *socket_name_cstr =
818 gdbserver.second.empty() ? nullptr : gdbserver.second.c_str();
819 connection_urls.emplace_back(
821 gdbserver.first, socket_name_cstr));
823 return connection_urls.size();