diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
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"); } } |