summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp22
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp76
4 files changed, 72 insertions, 32 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 14fe8773597..d194477b504 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -1091,7 +1091,8 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *url,
Platform *platform,
ProcessLaunchInfo &launch_info,
uint16_t *port,
- const Args& inferior_args)
+ const Args* inferior_args,
+ int pass_comm_fd)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
@@ -1171,6 +1172,16 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *url,
if (url)
debugserver_args.AppendArgument(url);
+ if (pass_comm_fd >= 0)
+ {
+ StreamString fd_arg;
+ fd_arg.Printf("--fd=%i", pass_comm_fd);
+ debugserver_args.AppendArgument(fd_arg.GetData());
+ // Send "pass_comm_fd" down to the inferior so it can use it to
+ // communicate back with this process
+ launch_info.AppendDuplicateFileAction(pass_comm_fd, pass_comm_fd);
+ }
+
// use native registers, not the GDB registers
debugserver_args.AppendArgument("--native-regs");
@@ -1189,7 +1200,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *url,
// 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 (pass_comm_fd == -1 && ((port != nullptr && *port == 0) || port == nullptr))
{
if (url)
{
@@ -1304,10 +1315,10 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *url,
}
} while (has_env_var);
- if (inferior_args.GetArgumentCount() > 0)
+ if (inferior_args && inferior_args->GetArgumentCount() > 0)
{
debugserver_args.AppendArgument ("--");
- debugserver_args.AppendArguments (inferior_args);
+ debugserver_args.AppendArguments (*inferior_args);
}
// Copy the current environment to the gdbserver/debugserver instance
@@ -1337,8 +1348,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *url,
}
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) && pass_comm_fd == -1)
{
if (named_pipe_path.size() > 0)
{
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 13325410e48..623f0d16653 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -162,7 +162,8 @@ public:
Platform *platform, // If non nullptr, then check with the platform for the GDB server binary if it can't be located
ProcessLaunchInfo &launch_info,
uint16_t *port,
- const Args& inferior_args = Args());
+ const Args *inferior_args,
+ int pass_comm_fd); // Communication file descriptor to pass during fork/exec to avoid having to connect/accept
void
DumpHistory(Stream &strm);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index d6900c27293..1cac61277e7 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -149,7 +149,8 @@ GDBRemoteCommunicationServerPlatform::LaunchGDBServer(const lldb_private::Args&
nullptr,
debugserver_launch_info,
port_ptr,
- args);
+ &args,
+ -1);
pid = debugserver_launch_info.GetProcessID();
if (pid != LLDB_INVALID_PROCESS_ID)
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 07ec61f2544..eb82dc1eba3 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -16,6 +16,7 @@
#include <netinet/in.h>
#include <sys/mman.h> // for mmap
#endif
+#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
@@ -64,6 +65,7 @@
#include "lldb/Target/TargetList.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Target/SystemRuntime.h"
+#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/PseudoTerminal.h"
// Project includes
@@ -3602,6 +3604,23 @@ ProcessGDBRemote::EstablishConnectionIfNeeded (const ProcessInfo &process_info)
}
return error;
}
+#if defined (__APPLE__)
+#define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION 1
+#endif
+
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+static bool SetCloexecFlag(int fd)
+{
+#if defined(FD_CLOEXEC)
+ int flags = ::fcntl(fd, F_GETFD);
+ if (flags == -1)
+ return false;
+ return (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0);
+#else
+ return false;
+#endif
+}
+#endif
Error
ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
@@ -3624,30 +3643,34 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
false);
debugserver_launch_info.SetUserID(process_info.GetUserID());
-#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
- // On iOS, still do a local connection using a random port
- const char *hostname = "127.0.0.1";
- uint16_t port = get_random_port ();
-#else
- // 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 = nullptr;
- uint16_t port = 0;
-#endif
- StreamString url_str;
- const char* url = nullptr;
- if (hostname != nullptr)
+ int communication_fd = -1;
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+ // Auto close the sockets we might open up unless everything goes OK. This
+ // helps us not leak file descriptors when things go wrong.
+ lldb_utility::CleanUp <int, int> our_socket(-1, -1, close);
+ lldb_utility::CleanUp <int, int> gdb_socket(-1, -1, close);
+
+ // Use a socketpair on Apple for now until other platforms can verify it
+ // works and is fast enough
{
- url_str.Printf("%s:%u", hostname, port);
- url = url_str.GetData();
+ int sockets[2]; /* the pair of socket descriptors */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1)
+ {
+ error.SetErrorToErrno();
+ return error;
+ }
+
+ our_socket.set(sockets[0]);
+ gdb_socket.set(sockets[1]);
}
- error = m_gdb_comm.StartDebugserverProcess (url,
- GetTarget().GetPlatform().get(),
- debugserver_launch_info,
- &port);
+ // Don't let any child processes inherit our communication socket
+ SetCloexecFlag(our_socket.get());
+ communication_fd = gdb_socket.get();
+#endif
+
+ error = m_gdb_comm.StartDebugserverProcess(nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info, nullptr, nullptr, communication_fd);
if (error.Success ())
m_debugserver_pid = debugserver_launch_info.GetProcessID();
@@ -3655,7 +3678,14 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ {
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+ // Our process spawned correctly, we can now set our connection to use our
+ // end of the socket pair
+ m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket.release(), true));
+#endif
StartAsyncThread ();
+ }
if (error.Fail())
{
@@ -3669,13 +3699,11 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
if (m_gdb_comm.IsConnected())
{
// Finish the connection process by doing the handshake without connecting (send NULL URL)
- ConnectToDebugserver (NULL);
+ ConnectToDebugserver(NULL);
}
else
{
- StreamString connect_url;
- connect_url.Printf("connect://%s:%u", hostname, port);
- error = ConnectToDebugserver (connect_url.GetString().c_str());
+ error.SetErrorString("connection failed");
}
}
OpenPOWER on IntegriCloud