summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp21
-rw-r--r--lldb/source/Plugins/Platform/Android/AdbClient.cpp13
-rw-r--r--lldb/source/Plugins/Platform/Android/AdbClient.h3
-rw-r--r--lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp3
-rw-r--r--lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp88
-rw-r--r--lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h15
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp51
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h14
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp78
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h5
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp26
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h7
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp71
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h11
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp15
15 files changed, 263 insertions, 158 deletions
diff --git a/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index cb69b6b2850..54cb7c22330 100644
--- a/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -50,8 +50,6 @@
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Interpreter/Args.h"
-#include "Utility/UriParser.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -171,20 +169,6 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
// unix://SOCKNAME
return NamedSocketAccept(s + strlen("unix-accept://"), error_ptr);
}
- else if (strstr(s, "adb://") == s)
- {
- int port = -1;
- std::string scheme, host, path;
- if (!UriParser::Parse(s, scheme, host, port, path))
- {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("Failed to parse URL '%s'", s);
- return eConnectionStatusError;
- }
- std::ostringstream host_and_port;
- host_and_port << "localhost:" << port;
- return ConnectTCP(host_and_port.str().c_str(), error_ptr);
- }
else if (strstr(s, "connect://") == s)
{
return ConnectTCP(s + strlen("connect://"), error_ptr);
@@ -197,6 +181,11 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
{
return ConnectUDP(s + strlen("udp://"), error_ptr);
}
+ else if (strstr(s, "unix-connect://") == s)
+ {
+ // unix-connect://SOCKNAME
+ return NamedSocketConnect(s + strlen("unix-connect://"), error_ptr);
+ }
#ifndef LLDB_DISABLE_POSIX
else if (strstr(s, "fd://") == s)
{
diff --git a/lldb/source/Plugins/Platform/Android/AdbClient.cpp b/lldb/source/Plugins/Platform/Android/AdbClient.cpp
index 17fccb38937..f57e8c3faf2 100644
--- a/lldb/source/Plugins/Platform/Android/AdbClient.cpp
+++ b/lldb/source/Plugins/Platform/Android/AdbClient.cpp
@@ -145,6 +145,19 @@ AdbClient::SetPortForwarding (const uint16_t local_port, const uint16_t remote_p
}
Error
+AdbClient::SetPortForwarding (const uint16_t local_port, const char* remote_socket_name)
+{
+ char message[PATH_MAX];
+ snprintf (message, sizeof (message), "forward:tcp:%d;localfilesystem:%s", local_port, remote_socket_name);
+
+ const auto error = SendDeviceMessage (message);
+ if (error.Fail ())
+ return error;
+
+ return ReadResponseStatus ();
+}
+
+Error
AdbClient::DeletePortForwarding (const uint16_t local_port)
{
char message[32];
diff --git a/lldb/source/Plugins/Platform/Android/AdbClient.h b/lldb/source/Plugins/Platform/Android/AdbClient.h
index 25a72640c6c..43aa1db678f 100644
--- a/lldb/source/Plugins/Platform/Android/AdbClient.h
+++ b/lldb/source/Plugins/Platform/Android/AdbClient.h
@@ -51,6 +51,9 @@ public:
SetPortForwarding (const uint16_t local_port, const uint16_t remote_port);
Error
+ SetPortForwarding (const uint16_t local_port, const char* remote_socket_name);
+
+ Error
DeletePortForwarding (const uint16_t local_port);
Error
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
index 403e641952c..0706c9bafa8 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -196,8 +196,7 @@ PlatformAndroid::ConnectRemote(Args& args)
return Error("URL is null.");
if (!UriParser::Parse(url, scheme, host, port, path))
return Error("Invalid URL: %s", url);
- if (scheme == "adb")
- m_device_id = host;
+ m_device_id = host;
auto error = PlatformLinux::ConnectRemote(args);
if (error.Success())
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
index 3e07442994b..1abc708cb83 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -24,7 +24,10 @@ using namespace platform_android;
static const lldb::pid_t g_remote_platform_pid = 0; // Alias for the process id of lldb-platform
static Error
-ForwardPortWithAdb (const uint16_t local_port, const uint16_t remote_port, std::string& device_id)
+ForwardPortWithAdb (const uint16_t local_port,
+ const uint16_t remote_port,
+ const char* remote_socket_name,
+ std::string& device_id)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
@@ -37,7 +40,16 @@ ForwardPortWithAdb (const uint16_t local_port, const uint16_t remote_port, std::
if (log)
log->Printf("Connected to Android device \"%s\"", device_id.c_str ());
- return adb.SetPortForwarding(local_port, remote_port);
+ if (remote_port != 0)
+ {
+ if (log)
+ log->Printf("Forwarding remote TCP port %d to local TCP port %d", remote_port, local_port);
+ return adb.SetPortForwarding(local_port, remote_port);
+ }
+
+ if (log)
+ log->Printf("Forwarding remote socket \"%s\" to local TCP port %d", remote_socket_name, local_port);
+ return adb.SetPortForwarding(local_port, remote_socket_name);
}
static Error
@@ -72,16 +84,24 @@ PlatformAndroidRemoteGDBServer::~PlatformAndroidRemoteGDBServer ()
DeleteForwardPortWithAdb(it.second, m_device_id);
}
-uint16_t
-PlatformAndroidRemoteGDBServer::LaunchGDBserverAndGetPort (lldb::pid_t &pid)
+bool
+PlatformAndroidRemoteGDBServer::LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url)
{
- uint16_t remote_port = m_gdb_client.LaunchGDBserverAndGetPort (pid, "127.0.0.1");
- if (remote_port == 0)
- return remote_port;
+ uint16_t remote_port = 0;
+ std::string socket_name;
+ if (!m_gdb_client.LaunchGDBServer ("127.0.0.1", pid, remote_port, socket_name))
+ return false;
- uint16_t local_port = 0;
- auto error = SetPortForwarding (pid, remote_port, local_port);
- return error.Success() ? local_port : 0;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+
+ auto error = MakeConnectURL (pid,
+ remote_port,
+ socket_name.c_str (),
+ connect_url);
+ if (error.Success() && log)
+ log->Printf("gdbserver connect URL: %s", connect_url.c_str());
+
+ return error.Success();
}
bool
@@ -106,21 +126,22 @@ PlatformAndroidRemoteGDBServer::ConnectRemote (Args& args)
return Error("URL is null.");
if (!UriParser::Parse (url, scheme, host, remote_port, path))
return Error("Invalid URL: %s", url);
- if (scheme == "adb")
- m_device_id = host;
+ m_device_id = host;
+
+ std::string connect_url;
+ auto error = MakeConnectURL (g_remote_platform_pid,
+ (remote_port < 0) ? 0 : remote_port,
+ path.c_str (),
+ connect_url);
- uint16_t local_port = 0;
- auto error = SetPortForwarding (g_remote_platform_pid, remote_port, local_port);
if (error.Fail ())
return error;
- const std::string new_url = MakeUrl(
- scheme.c_str(), host.c_str(), local_port, path.c_str());
- args.ReplaceArgumentAtIndex (0, new_url.c_str ());
+ args.ReplaceArgumentAtIndex (0, connect_url.c_str ());
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
if (log)
- log->Printf("Rewritten URL: %s", new_url.c_str());
+ log->Printf("Rewritten platform connect URL: %s", connect_url.c_str());
error = PlatformRemoteGDBServer::ConnectRemote(args);
if (error.Fail ())
@@ -156,9 +177,10 @@ PlatformAndroidRemoteGDBServer::DeleteForwardPort (lldb::pid_t pid)
}
Error
-PlatformAndroidRemoteGDBServer::SetPortForwarding(const lldb::pid_t pid,
- const uint16_t remote_port,
- uint16_t &local_port)
+PlatformAndroidRemoteGDBServer::MakeConnectURL(const lldb::pid_t pid,
+ const uint16_t remote_port,
+ const char* remote_socket_name,
+ std::string& connect_url)
{
static const int kAttempsNum = 5;
@@ -168,35 +190,21 @@ PlatformAndroidRemoteGDBServer::SetPortForwarding(const lldb::pid_t pid,
// adding the loop to mitigate such problem.
for (auto i = 0; i < kAttempsNum; ++i)
{
+ uint16_t local_port = 0;
error = FindUnusedPort(local_port);
if (error.Fail())
return error;
- error = ForwardPortWithAdb(local_port, remote_port, m_device_id);
+ error = ForwardPortWithAdb(local_port, remote_port, remote_socket_name, m_device_id);
if (error.Success())
{
m_port_forwards[pid] = local_port;
+ std::ostringstream url_str;
+ url_str << "connect://localhost:" << local_port;
+ connect_url = url_str.str();
break;
}
}
return error;
}
-
-std::string
-PlatformAndroidRemoteGDBServer::MakeUrl(const char* scheme,
- const char* hostname,
- uint16_t port,
- const char* path)
-{
- std::ostringstream hostname_str;
- if (!strcmp(scheme, "adb"))
- hostname_str << "[" << hostname << "]";
- else
- hostname_str << hostname;
-
- return PlatformRemoteGDBServer::MakeUrl(scheme,
- hostname_str.str().c_str(),
- port,
- path);
-}
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
index a6dccb8cfcd..9555c73a29a 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
@@ -40,8 +40,8 @@ protected:
std::string m_device_id;
std::map<lldb::pid_t, uint16_t> m_port_forwards;
- uint16_t
- LaunchGDBserverAndGetPort (lldb::pid_t &pid) override;
+ bool
+ LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url) override;
bool
KillSpawnedProcess (lldb::pid_t pid) override;
@@ -49,14 +49,11 @@ protected:
void
DeleteForwardPort (lldb::pid_t pid);
- std::string
- MakeUrl(const char* scheme,
- const char* hostname,
- uint16_t port,
- const char* path) override;
-
Error
- SetPortForwarding(const lldb::pid_t pid, const uint16_t remote_port, uint16_t &local_port);
+ MakeConnectURL(const lldb::pid_t pid,
+ const uint16_t remote_port,
+ const char* remote_socket_name,
+ std::string& connect_url);
private:
DISALLOW_COPY_AND_ASSIGN (PlatformAndroidRemoteGDBServer);
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index bf5c328f866..ea83027bfe5 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -573,9 +573,8 @@ PlatformRemoteGDBServer::DebugProcess (ProcessLaunchInfo &launch_info,
if (IsConnected())
{
lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
- uint16_t port = LaunchGDBserverAndGetPort(debugserver_pid);
-
- if (port == 0)
+ std::string connect_url;
+ if (!LaunchGDBServer(debugserver_pid, connect_url))
{
error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
}
@@ -606,8 +605,6 @@ PlatformRemoteGDBServer::DebugProcess (ProcessLaunchInfo &launch_info,
if (process_sp)
{
- std::string connect_url =
- MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port);
error = process_sp->ConnectRemote (nullptr, connect_url.c_str());
// Retry the connect remote one time...
if (error.Fail())
@@ -632,23 +629,36 @@ PlatformRemoteGDBServer::DebugProcess (ProcessLaunchInfo &launch_info,
}
-uint16_t
-PlatformRemoteGDBServer::LaunchGDBserverAndGetPort (lldb::pid_t &pid)
+bool
+PlatformRemoteGDBServer::LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url)
{
ArchSpec remote_arch = GetRemoteSystemArchitecture ();
llvm::Triple &remote_triple = remote_arch.GetTriple ();
+
+ uint16_t port = 0;
+ std::string socket_name;
+ bool launch_result = false;
if (remote_triple.getVendor () == llvm::Triple::Apple && remote_triple.getOS () == llvm::Triple::IOS)
{
// When remote debugging to iOS, we use a USB mux that always talks
// to localhost, so we will need the remote debugserver to accept connections
// only from localhost, no matter what our current hostname is
- return m_gdb_client.LaunchGDBserverAndGetPort (pid, "127.0.0.1");
+ launch_result = m_gdb_client.LaunchGDBServer ("127.0.0.1", pid, port, socket_name);
}
else
{
// All other hosts should use their actual hostname
- return m_gdb_client.LaunchGDBserverAndGetPort (pid, NULL);
+ launch_result = m_gdb_client.LaunchGDBServer (nullptr, pid, port, socket_name);
}
+
+ if (!launch_result)
+ return false;
+
+ connect_url = MakeGdbServerUrl(m_platform_scheme,
+ m_platform_hostname,
+ port,
+ (socket_name.empty()) ? nullptr : socket_name.c_str());
+ return true;
}
bool
@@ -669,9 +679,8 @@ PlatformRemoteGDBServer::Attach (ProcessAttachInfo &attach_info,
if (IsConnected())
{
lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
- uint16_t port = LaunchGDBserverAndGetPort(debugserver_pid);
-
- if (port == 0)
+ std::string connect_url;
+ if (!LaunchGDBServer(debugserver_pid, connect_url))
{
error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
}
@@ -699,11 +708,8 @@ PlatformRemoteGDBServer::Attach (ProcessAttachInfo &attach_info,
// The darwin always currently uses the GDB remote debugger plug-in
// so even when debugging locally we are debugging remotely!
process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
-
if (process_sp)
{
- std::string connect_url =
- MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port);
error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
if (error.Success())
{
@@ -950,7 +956,8 @@ PlatformRemoteGDBServer::GetRemoteUnixSignals()
std::string
PlatformRemoteGDBServer::MakeGdbServerUrl(const std::string &platform_scheme,
const std::string &platform_hostname,
- uint16_t port)
+ uint16_t port,
+ const char* socket_name)
{
const char *override_scheme = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME");
const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
@@ -960,17 +967,19 @@ PlatformRemoteGDBServer::MakeGdbServerUrl(const std::string &platform_scheme,
return MakeUrl(override_scheme ? override_scheme : platform_scheme.c_str(),
override_hostname ? override_hostname : platform_hostname.c_str(),
port + port_offset,
- nullptr);
+ socket_name);
}
std::string
PlatformRemoteGDBServer::MakeUrl(const char* scheme,
- const char* hostname,
- uint16_t port,
- const char* path)
+ const char* hostname,
+ uint16_t port,
+ const char* path)
{
StreamString result;
- result.Printf("%s://%s:%u", scheme, hostname, port);
+ result.Printf("%s://%s", scheme, hostname);
+ if (port != 0)
+ result.Printf(":%u", port);
if (path)
result.Write(path, strlen(path));
return result.GetString();
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 7b997e8c561..ffba509bbfb 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -225,11 +225,12 @@ protected:
lldb::UnixSignalsSP m_remote_signals_sp;
- // Launch the lldb-gdbserver on the remote host and return the port it is listening on or 0 on
- // failure. Subclasses should override this method if they want to do extra actions before or
- // after launching the lldb-gdbserver.
- virtual uint16_t
- LaunchGDBserverAndGetPort (lldb::pid_t &pid);
+ // Launch the debug server on the remote host - caller connects to launched
+ // debug server using connect_url.
+ // Subclasses should override this method if they want to do extra actions before or
+ // after launching the debug server.
+ virtual bool
+ LaunchGDBServer (lldb::pid_t &pid, std::string &connect_url);
virtual bool
KillSpawnedProcess (lldb::pid_t pid);
@@ -244,7 +245,8 @@ private:
std::string
MakeGdbServerUrl(const std::string &platform_scheme,
const std::string &platform_hostname,
- uint16_t port);
+ uint16_t port,
+ const char* socket_name);
DISALLOW_COPY_AND_ASSIGN (PlatformRemoteGDBServer);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 0bbee854dc4..ea95298dd5c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -1112,17 +1112,15 @@ GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
}
Error
-GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
- uint16_t in_port,
+GDBRemoteCommunication::StartDebugserverProcess (const char *url,
Platform *platform,
ProcessLaunchInfo &launch_info,
- uint16_t &out_port)
+ uint16_t *port)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
- log->Printf ("GDBRemoteCommunication::%s(hostname=%s, in_port=%" PRIu16 ", out_port=%" PRIu16, __FUNCTION__, hostname ? hostname : "<empty>", in_port, out_port);
+ log->Printf ("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16, __FUNCTION__, url ? url : "<empty>", port ? *port : uint16_t(0));
- out_port = in_port;
Error error;
// If we locate debugserver, keep that located version around
static FileSpec g_debugserver_file_spec;
@@ -1193,17 +1191,9 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
debugserver_args.AppendArgument("gdbserver");
#endif
- // If a host and port is supplied then use it
- char host_and_port[128];
- if (hostname)
- {
- snprintf (host_and_port, sizeof(host_and_port), "%s:%u", hostname, in_port);
- debugserver_args.AppendArgument(host_and_port);
- }
- else
- {
- host_and_port[0] = '\0';
- }
+ // If a url is supplied then use it
+ if (url)
+ debugserver_args.AppendArgument(url);
// use native registers, not the GDB registers
debugserver_args.AppendArgument("--native-regs");
@@ -1214,11 +1204,18 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
}
llvm::SmallString<PATH_MAX> named_pipe_path;
- Pipe port_pipe;
-
- if (in_port == 0)
+ // socket_pipe is used by debug server to communicate back either
+ // TCP port or domain socket name which it listens on.
+ // The second purpose of the pipe to serve as a synchronization point -
+ // once data is written to the pipe, debug server is up and running.
+ Pipe socket_pipe;
+
+ // port is null when debug server should listen on domain socket -
+ // we're not interested in port value but rather waiting for debug server
+ // to become available.
+ if ((port != nullptr && *port == 0) || port == nullptr)
{
- if (host_and_port[0])
+ if (url)
{
// Create a temporary file to get the stdout/stderr and redirect the
// output of the command into this file. We will later read this file
@@ -1227,7 +1224,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
#if defined(__APPLE__)
// Binding to port zero, we need to figure out what port it ends up
// using using a named pipe...
- error = port_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path);
+ error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path);
if (error.Fail())
{
if (log)
@@ -1241,7 +1238,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
#else
// Binding to port zero, we need to figure out what port it ends up
// using using an unnamed pipe...
- error = port_pipe.CreateNew(true);
+ error = socket_pipe.CreateNew(true);
if (error.Fail())
{
if (log)
@@ -1250,10 +1247,10 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
__FUNCTION__, error.AsCString());
return error;
}
- int write_fd = port_pipe.GetWriteFileDescriptor();
+ int write_fd = socket_pipe.GetWriteFileDescriptor();
debugserver_args.AppendArgument("--pipe");
debugserver_args.AppendArgument(std::to_string(write_fd).c_str());
- launch_info.AppendCloseFileAction(port_pipe.GetReadFileDescriptor());
+ launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor());
#endif
}
else
@@ -1270,11 +1267,11 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
// Wait for 10 seconds to resolve the bound port
- out_port = connection->GetListeningPort(10);
- if (out_port > 0)
+ *port = connection->GetListeningPort(10);
+ if (*port > 0)
{
char port_cstr[32];
- snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", out_port);
+ snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", *port);
// Send the host and port down that debugserver and specify an option
// so that it connects back to the port we are listening to in this process
debugserver_args.AppendArgument("--reverse-connect");
@@ -1343,11 +1340,12 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
error = Host::LaunchProcess(launch_info);
- if (error.Success() && launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
+ if (error.Success() &&
+ launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
{
if (named_pipe_path.size() > 0)
{
- error = port_pipe.OpenAsReader(named_pipe_path, false);
+ error = socket_pipe.OpenAsReader(named_pipe_path, false);
if (error.Fail())
if (log)
log->Printf("GDBRemoteCommunication::%s() "
@@ -1355,24 +1353,24 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
__FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
- if (port_pipe.CanWrite())
- port_pipe.CloseWriteFileDescriptor();
- if (port_pipe.CanRead())
+ if (socket_pipe.CanWrite())
+ socket_pipe.CloseWriteFileDescriptor();
+ if (socket_pipe.CanRead())
{
- char port_cstr[256];
+ char port_cstr[PATH_MAX] = {0};
port_cstr[0] = '\0';
size_t num_bytes = sizeof(port_cstr);
// Read port from pipe with 10 second timeout.
- error = port_pipe.ReadWithTimeout(port_cstr, num_bytes,
+ error = socket_pipe.ReadWithTimeout(port_cstr, num_bytes,
std::chrono::seconds{10}, num_bytes);
- if (error.Success())
+ if (error.Success() && (port != nullptr))
{
assert(num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
- out_port = StringConvert::ToUInt32(port_cstr, 0);
+ *port = StringConvert::ToUInt32(port_cstr, 0);
if (log)
log->Printf("GDBRemoteCommunication::%s() "
- "debugserver listens %u port",
- __FUNCTION__, out_port);
+ "debugserver listens %u port",
+ __FUNCTION__, *port);
}
else
{
@@ -1382,12 +1380,12 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
__FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
- port_pipe.Close();
+ socket_pipe.Close();
}
if (named_pipe_path.size() > 0)
{
- const auto err = port_pipe.Delete(named_pipe_path);
+ const auto err = socket_pipe.Delete(named_pipe_path);
if (err.Fail())
{
if (log)
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 94ffa512884..dee3528463f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -167,11 +167,10 @@ public:
// supplied connection URL.
//------------------------------------------------------------------
Error
- StartDebugserverProcess (const char *hostname,
- uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
+ StartDebugserverProcess (const char *url,
Platform *platform, // If non NULL, then check with the platform for the GDB server binary if it can't be located
ProcessLaunchInfo &launch_info,
- uint16_t &out_port);
+ uint16_t *port);
void
DumpHistory(Stream &strm);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 42eb0a1d2ac..a6fcd14cba4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -3315,10 +3315,16 @@ GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t
return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success;
}
-uint16_t
-GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname)
+bool
+GDBRemoteCommunicationClient::LaunchGDBServer (const char *remote_accept_hostname,
+ lldb::pid_t &pid,
+ uint16_t &port,
+ std::string &socket_name)
{
pid = LLDB_INVALID_PROCESS_ID;
+ port = 0;
+ socket_name.clear();
+
StringExtractorGDBRemote response;
StreamString stream;
stream.PutCString("qLaunchGDBServer;");
@@ -3343,22 +3349,30 @@ GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const
// give the process a few seconds to startup
GDBRemoteCommunication::ScopedTimeout timeout (*this, 10);
-
+
if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
std::string name;
std::string value;
- uint16_t port = 0;
+ StringExtractor extractor;
while (response.GetNameColonValue(name, value))
{
if (name.compare("port") == 0)
port = StringConvert::ToUInt32(value.c_str(), 0, 0);
else if (name.compare("pid") == 0)
pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
+ else if (name.compare("socket_name") == 0)
+ {
+ extractor.GetStringRef().swap(value);
+ extractor.SetFilePos(0);
+ extractor.GetHexByteString(value);
+
+ socket_name = value;
+ }
}
- return port;
+ return true;
}
- return 0;
+ return false;
}
bool
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index b08ff064779..4847aad52f2 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -114,8 +114,11 @@ public:
bool
GetLaunchSuccess (std::string &error_str);
- uint16_t
- LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname);
+ bool
+ LaunchGDBServer (const char *remote_accept_hostname,
+ lldb::pid_t &pid,
+ uint16_t &port,
+ std::string &socket_name);
bool
KillSpawnedProcess (lldb::pid_t pid);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 592d7f7f27c..54aad1022f1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -15,14 +15,20 @@
// C++ Includes
#include <cstring>
#include <chrono>
+#include <mutex>
+#include <sstream>
// Other libraries and framework includes
+#include "llvm/Support/FileSystem.h"
+
#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamGDBRemote.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Platform.h"
@@ -40,8 +46,9 @@ using namespace lldb_private::process_gdb_remote;
//----------------------------------------------------------------------
// GDBRemoteCommunicationServerPlatform constructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform() :
+GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol) :
GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"),
+ m_socket_protocol(socket_protocol),
m_spawned_pids_mutex (Mutex::eMutexTypeRecursive),
m_platform_sp (Platform::GetHostPlatform ()),
m_port_map (),
@@ -138,11 +145,24 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGD
bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path);
UNUSED_IF_ASSERT_DISABLED(ok);
assert(ok);
- Error error = StartDebugserverProcess (platform_ip.c_str(),
- port,
+
+ std::string socket_name;
+ std::ostringstream url;
+
+ uint16_t* port_ptr = &port;
+ if (m_socket_protocol == Socket::ProtocolTcp)
+ url << platform_ip << ":" << port;
+ else
+ {
+ socket_name = GetDomainSocketPath("gdbserver").GetPath();
+ url << socket_name;
+ port_ptr = nullptr;
+ }
+
+ Error error = StartDebugserverProcess (url.str().c_str(),
nullptr,
debugserver_launch_info,
- port);
+ port_ptr);
lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
@@ -165,11 +185,16 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGD
if (log)
log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid);
- char response[256];
- const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
- assert (response_len < (int)sizeof(response));
- PacketResult packet_result = SendPacketNoLock (response, response_len);
+ StreamGDBRemote response;
+ response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
+ if (!socket_name.empty())
+ {
+ response.PutCString("socket_name:");
+ response.PutCStringAsRawHex8(socket_name.c_str());
+ response.PutChar(';');
+ }
+ PacketResult packet_result = SendPacketNoLock(response.GetData(), response.GetSize());
if (packet_result != PacketResult::Success)
{
if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
@@ -494,6 +519,36 @@ GDBRemoteCommunicationServerPlatform::FreePortForProcess (lldb::pid_t pid)
return false;
}
+const FileSpec&
+GDBRemoteCommunicationServerPlatform::GetDomainSocketDir()
+{
+ static FileSpec g_domainsocket_dir;
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ const char* domainsocket_dir_env = ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
+ if (domainsocket_dir_env != nullptr)
+ g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
+ else
+ HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir);
+ });
+
+ return g_domainsocket_dir;
+}
+
+FileSpec
+GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char* prefix)
+{
+ llvm::SmallString<PATH_MAX> socket_path;
+ llvm::SmallString<PATH_MAX> socket_name((llvm::StringRef(prefix) + ".%%%%%%").str());
+
+ FileSpec socket_path_spec(GetDomainSocketDir());
+ socket_path_spec.AppendPathComponent(socket_name.c_str());
+
+ llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
+ return FileSpec(socket_path.c_str(), false);
+}
+
void
GDBRemoteCommunicationServerPlatform::SetPortOffset (uint16_t port_offset)
{
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index f507a085cdb..e34189f9ec1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -12,6 +12,8 @@
#include "GDBRemoteCommunicationServerCommon.h"
+#include "lldb/Host/Socket.h"
+
#include <set>
namespace lldb_private {
@@ -23,7 +25,7 @@ class GDBRemoteCommunicationServerPlatform :
public:
typedef std::map<uint16_t, lldb::pid_t> PortMap;
- GDBRemoteCommunicationServerPlatform();
+ GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol);
virtual
~GDBRemoteCommunicationServerPlatform();
@@ -61,6 +63,7 @@ public:
SetPortOffset (uint16_t port_offset);
protected:
+ const Socket::SocketProtocol m_socket_protocol;
Mutex m_spawned_pids_mutex;
std::set<lldb::pid_t> m_spawned_pids;
lldb::PlatformSP m_platform_sp;
@@ -103,6 +106,12 @@ private:
int signal,
int status);
+ static const FileSpec&
+ GetDomainSocketDir();
+
+ static FileSpec
+ GetDomainSocketPath(const char* prefix);
+
//------------------------------------------------------------------
// For GDBRemoteCommunicationServerPlatform only
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 5b6f9794f5a..8ed7e45f1a2 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -3562,15 +3562,22 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
// Set hostname being NULL to do the reverse connect where debugserver
// will bind to port zero and it will communicate back to us the port
// that we will connect to
- const char *hostname = NULL;
+ const char *hostname = nullptr;
uint16_t port = 0;
#endif
- error = m_gdb_comm.StartDebugserverProcess (hostname,
- port,
+ StreamString url_str;
+ const char* url = nullptr;
+ if (hostname != nullptr)
+ {
+ url_str.Printf("%s:%u", hostname, port);
+ url = url_str.GetData();
+ }
+
+ error = m_gdb_comm.StartDebugserverProcess (url,
GetTarget().GetPlatform().get(),
debugserver_launch_info,
- port);
+ &port);
if (error.Success ())
m_debugserver_pid = debugserver_launch_info.GetProcessID();
OpenPOWER on IntegriCloud