diff options
Diffstat (limited to 'tools/lldb-server/lldb-gdbserver.cpp')
-rw-r--r-- | tools/lldb-server/lldb-gdbserver.cpp | 158 |
1 files changed, 39 insertions, 119 deletions
diff --git a/tools/lldb-server/lldb-gdbserver.cpp b/tools/lldb-server/lldb-gdbserver.cpp index 30bb2d6867701..df8cb6e68554f 100644 --- a/tools/lldb-server/lldb-gdbserver.cpp +++ b/tools/lldb-server/lldb-gdbserver.cpp @@ -9,7 +9,6 @@ // C Includes #include <errno.h> -#include <getopt.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -25,17 +24,16 @@ // Other libraries and framework includes #include "llvm/ADT/StringRef.h" -#include "lldb/Core/ConnectionMachPort.h" #include "lldb/Core/Error.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/ConnectionFileDescriptor.h" -#include "lldb/Host/HostThread.h" +#include "lldb/Host/HostGetOpt.h" #include "lldb/Host/OptionParser.h" #include "lldb/Host/Pipe.h" #include "lldb/Host/Socket.h" #include "lldb/Host/StringConvert.h" -#include "lldb/Host/ThreadLauncher.h" #include "lldb/Target/Platform.h" +#include "Acceptor.h" #include "LLDBServerUtilities.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" @@ -54,15 +52,6 @@ using namespace lldb_private; using namespace lldb_private::lldb_server; using namespace lldb_private::process_gdb_remote; -// lldb-gdbserver state - -namespace -{ -HostThread s_listen_thread; - std::unique_ptr<ConnectionFileDescriptor> s_listen_connection_up; - std::string s_listen_url; -} - //---------------------------------------------------------------------- // option descriptors for getopt_long_only() //---------------------------------------------------------------------- @@ -263,64 +252,16 @@ handle_launch (GDBRemoteCommunicationServerLLGS &gdb_server, int argc, const cha } } -static lldb::thread_result_t -ListenThread (lldb::thread_arg_t /* arg */) -{ - Error error; - - if (s_listen_connection_up) - { - // Do the listen on another thread so we can continue on... - if (s_listen_connection_up->Connect(s_listen_url.c_str(), &error) != eConnectionStatusSuccess) - s_listen_connection_up.reset(); - } - return nullptr; -} - -static Error -StartListenThread (const char *hostname, uint16_t port) -{ - Error error; - if (s_listen_thread.IsJoinable()) - { - error.SetErrorString("listen thread already running"); - } - else - { - char listen_url[512]; - if (hostname && hostname[0]) - snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port); - else - snprintf(listen_url, sizeof(listen_url), "listen://%i", port); - - s_listen_url = listen_url; - s_listen_connection_up.reset (new ConnectionFileDescriptor ()); - s_listen_thread = ThreadLauncher::LaunchThread(listen_url, ListenThread, nullptr, &error); - } - return error; -} - -static bool -JoinListenThread () -{ - if (s_listen_thread.IsJoinable()) - s_listen_thread.Join(nullptr); - return true; -} - Error -WritePortToPipe(Pipe &port_pipe, const uint16_t port) +writeSocketIdToPipe(Pipe &port_pipe, const std::string &socket_id) { - char port_str[64]; - const auto port_str_len = ::snprintf(port_str, sizeof(port_str), "%u", port); - size_t bytes_written = 0; // Write the port number as a C string with the NULL terminator. - return port_pipe.Write(port_str, port_str_len + 1, bytes_written); + return port_pipe.Write(socket_id.c_str(), socket_id.size() + 1, bytes_written); } Error -writePortToPipe(const char *const named_pipe_path, const uint16_t port) +writeSocketIdToPipe(const char *const named_pipe_path, const std::string &socket_id) { Pipe port_name_pipe; // Wait for 10 seconds for pipe to be opened. @@ -328,17 +269,17 @@ writePortToPipe(const char *const named_pipe_path, const uint16_t port) std::chrono::seconds{10}); if (error.Fail()) return error; - return WritePortToPipe(port_name_pipe, port); + return writeSocketIdToPipe(port_name_pipe, socket_id); } Error -writePortToPipe(int unnamed_pipe_fd, const uint16_t port) +writeSocketIdToPipe(int unnamed_pipe_fd, const std::string &socket_id) { #if defined(_WIN32) return Error("Unnamed pipes are not supported on Windows."); #else Pipe port_pipe{Pipe::kInvalidDescriptor, unnamed_pipe_fd}; - return WritePortToPipe(port_pipe, port); + return writeSocketIdToPipe(port_pipe, socket_id); #endif } @@ -370,14 +311,8 @@ ConnectToRemote(MainLoop &mainloop, GDBRemoteCommunicationServerLLGS &gdb_server connection_port = final_host_and_port.substr (colon_pos + 1); connection_portno = StringConvert::ToUInt32 (connection_port.c_str (), 0); } - else - { - fprintf (stderr, "failed to parse host and port from connection string '%s'\n", final_host_and_port.c_str ()); - display_usage (progname, subcommand); - exit (1); - } - std::unique_ptr<ConnectionFileDescriptor> connection_up; + std::unique_ptr<Connection> connection_up; if (reverse_connect) { @@ -410,66 +345,51 @@ ConnectToRemote(MainLoop &mainloop, GDBRemoteCommunicationServerLLGS &gdb_server } else { - // llgs will listen for connections on the given port from the given address. - // Start the listener on a new thread. We need to do this so we can resolve the - // bound listener port. - StartListenThread(connection_host.c_str (), static_cast<uint16_t> (connection_portno)); - printf ("Listening to port %s for a connection from %s...\n", connection_port.c_str (), connection_host.c_str ()); - - // If we have a named pipe to write the port number back to, do that now. - if (named_pipe_path && named_pipe_path[0] && connection_portno == 0) + std::unique_ptr<Acceptor> acceptor_up(Acceptor::Create(final_host_and_port, false, error)); + if (error.Fail()) + { + fprintf(stderr, "failed to create acceptor: %s", error.AsCString()); + exit(1); + } + error = acceptor_up->Listen(1); + if (error.Fail()) { - const uint16_t bound_port = s_listen_connection_up->GetListeningPort (10); - if (bound_port > 0) + fprintf(stderr, "failed to listen: %s\n", error.AsCString()); + exit(1); + } + const std::string socket_id = acceptor_up->GetLocalSocketId(); + if (!socket_id.empty()) + { + // If we have a named pipe to write the socket id back to, do that now. + if (named_pipe_path && named_pipe_path[0]) { - error = writePortToPipe (named_pipe_path, bound_port); + error = writeSocketIdToPipe (named_pipe_path, socket_id); if (error.Fail ()) - { - fprintf (stderr, "failed to write to the named pipe \'%s\': %s", named_pipe_path, error.AsCString()); - } + fprintf (stderr, "failed to write to the named pipe \'%s\': %s", + named_pipe_path, error.AsCString()); } - else + // If we have an unnamed pipe to write the socket id back to, do that now. + else if (unnamed_pipe_fd >= 0) { - fprintf (stderr, "unable to get the bound port for the listening connection\n"); - } - } - - // If we have an unnamed pipe to write the port number back to, do that now. - if (unnamed_pipe_fd >= 0 && connection_portno == 0) - { - const uint16_t bound_port = s_listen_connection_up->GetListeningPort(10); - if (bound_port > 0) - { - error = writePortToPipe(unnamed_pipe_fd, bound_port); + error = writeSocketIdToPipe(unnamed_pipe_fd, socket_id); if (error.Fail()) - { fprintf(stderr, "failed to write to the unnamed pipe: %s", error.AsCString()); - } - } - else - { - fprintf(stderr, "unable to get the bound port for the listening connection\n"); } } - - // Join the listener thread. - if (!JoinListenThread ()) + else { - fprintf (stderr, "failed to join the listener thread\n"); - display_usage (progname, subcommand); - exit (1); + fprintf (stderr, "unable to get the socket id for the listening connection\n"); } - // Ensure we connected. - if (s_listen_connection_up) - connection_up = std::move(s_listen_connection_up); - else + Connection* conn = nullptr; + error = acceptor_up->Accept(false, conn); + if (error.Fail()) { - fprintf (stderr, "failed to connect to '%s': %s\n", final_host_and_port.c_str (), error.AsCString ()); - display_usage (progname, subcommand); - exit (1); + printf ("failed to accept new connection: %s\n", error.AsCString()); + exit(1); } + connection_up.reset(conn); } error = gdb_server.InitializeConnection (std::move(connection_up)); if (error.Fail()) |