diff options
Diffstat (limited to 'tools/lldb-server/lldb-platform.cpp')
-rw-r--r-- | tools/lldb-server/lldb-platform.cpp | 95 |
1 files changed, 61 insertions, 34 deletions
diff --git a/tools/lldb-server/lldb-platform.cpp b/tools/lldb-server/lldb-platform.cpp index 4dfa7d2..3292080 100644 --- a/tools/lldb-server/lldb-platform.cpp +++ b/tools/lldb-server/lldb-platform.cpp @@ -23,15 +23,17 @@ #include <fstream> // Other libraries and framework includes +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" + #include "lldb/Core/Error.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostGetOpt.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/Socket.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/FileUtilities.h" +#include "lldb/Host/common/TCPSocket.h" +#include "Acceptor.h" #include "LLDBServerUtilities.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" @@ -61,7 +63,7 @@ static struct option g_long_options[] = { "gdbserver-port", required_argument, NULL, 'P' }, { "min-gdbserver-port", required_argument, NULL, 'm' }, { "max-gdbserver-port", required_argument, NULL, 'M' }, - { "port-file", required_argument, NULL, 'f' }, + { "socket-file", required_argument, NULL, 'f' }, { "server", no_argument, &g_server, 1 }, { NULL, 0, NULL, 0 } }; @@ -100,9 +102,9 @@ display_usage (const char *progname, const char *subcommand) } static Error -save_port_to_file(const uint16_t port, const FileSpec &port_file_spec) +save_socket_id_to_file(const std::string &socket_id, const FileSpec &file_spec) { - FileSpec temp_file_spec(port_file_spec.GetDirectory().AsCString(), false); + FileSpec temp_file_spec(file_spec.GetDirectory().AsCString(), false); auto error = FileSystem::MakeDirectory(temp_file_spec, eFilePermissionsDirectoryDefault); if (error.Fail()) return Error("Failed to create directory %s: %s", temp_file_spec.GetCString(), error.AsCString()); @@ -119,13 +121,13 @@ save_port_to_file(const uint16_t port, const FileSpec &port_file_spec) std::ofstream temp_file(temp_file_path.c_str(), std::ios::out); if (!temp_file.is_open()) return Error("Failed to open temp file %s", temp_file_path.c_str()); - temp_file << port; + temp_file << socket_id; } - err_code = llvm::sys::fs::rename(temp_file_path.c_str(), port_file_spec.GetPath().c_str()); + err_code = llvm::sys::fs::rename(temp_file_path.c_str(), file_spec.GetPath().c_str()); if (err_code) return Error("Failed to rename file %s to %s: %s", - temp_file_path.c_str(), port_file_spec.GetPath().c_str(), err_code.message().c_str()); + temp_file_path.c_str(), file_spec.GetPath().c_str(), err_code.message().c_str()); tmp_file_remover.releaseFile(); return Error(); @@ -156,7 +158,7 @@ main_platform (int argc, char *argv[]) int max_gdbserver_port = 0; uint16_t port_offset = 0; - FileSpec port_file; + FileSpec socket_file; bool show_usage = false; int option_error = 0; int socket_error = -1; @@ -191,9 +193,9 @@ main_platform (int argc, char *argv[]) log_channels = StringRef(optarg); break; - case 'f': // Port file + case 'f': // Socket file if (optarg && optarg[0]) - port_file.SetFile(optarg, false); + socket_file.SetFile(optarg, false); break; case 'p': @@ -282,36 +284,46 @@ main_platform (int argc, char *argv[]) display_usage(progname, subcommand); exit(option_error); } - - std::unique_ptr<Socket> listening_socket_up; - Socket *socket = nullptr; - const bool children_inherit_listen_socket = false; + // Skip any options we consumed with getopt_long_only. + argc -= optind; + argv += optind; + lldb_private::Args inferior_arguments; + inferior_arguments.SetArguments(argc, const_cast<const char**>(argv)); + + const bool children_inherit_listen_socket = false; // the test suite makes many connections in parallel, let's not miss any. - // The highest this should get reasonably is a function of the number - // of target CPUs. For now, let's just use 100 + // The highest this should get reasonably is a function of the number + // of target CPUs. For now, let's just use 100. const int backlog = 100; - error = Socket::TcpListen(listen_host_port.c_str(), children_inherit_listen_socket, socket, NULL, backlog); + + std::unique_ptr<Acceptor> acceptor_up(Acceptor::Create(listen_host_port, children_inherit_listen_socket, error)); if (error.Fail()) { - printf("error: %s\n", error.AsCString()); + fprintf(stderr, "failed to create acceptor: %s", error.AsCString()); exit(socket_error); } - listening_socket_up.reset(socket); - printf ("Listening for a connection from %u...\n", listening_socket_up->GetLocalPortNumber()); - if (port_file) + + error = acceptor_up->Listen(backlog); + if (error.Fail()) + { + printf("failed to listen: %s\n", error.AsCString()); + exit(socket_error); + } + if (socket_file) { - error = save_port_to_file(listening_socket_up->GetLocalPortNumber(), port_file); + error = save_socket_id_to_file(acceptor_up->GetLocalSocketId(), socket_file); if (error.Fail()) { - fprintf(stderr, "failed to write port to %s: %s", port_file.GetPath().c_str(), error.AsCString()); + fprintf(stderr, "failed to write socket id to %s: %s\n", socket_file.GetPath().c_str(), error.AsCString()); return 1; } } do { - GDBRemoteCommunicationServerPlatform platform; - + GDBRemoteCommunicationServerPlatform platform(acceptor_up->GetSocketProtocol(), + acceptor_up->GetSocketScheme()); + if (port_offset > 0) platform.SetPortOffset(port_offset); @@ -321,8 +333,8 @@ main_platform (int argc, char *argv[]) } const bool children_inherit_accept_socket = true; - socket = nullptr; - error = listening_socket_up->BlockingAccept(listen_host_port.c_str(), children_inherit_accept_socket, socket); + Connection* conn = nullptr; + error = acceptor_up->Accept(children_inherit_accept_socket, conn); if (error.Fail()) { printf ("error: %s\n", error.AsCString()); @@ -336,8 +348,7 @@ main_platform (int argc, char *argv[]) if (fork()) { // Parent doesn't need a connection to the lldb client - delete socket; - socket = nullptr; + delete conn; // Parent will continue to listen for new connections. continue; @@ -347,19 +358,35 @@ main_platform (int argc, char *argv[]) // Child process will handle the connection and exit. g_server = 0; // Listening socket is owned by parent process. - listening_socket_up.release(); + acceptor_up.release(); } } else { // If not running as a server, this process will not accept // connections while a connection is active. - listening_socket_up.reset(); + acceptor_up.reset(); } - platform.SetConnection (new ConnectionFileDescriptor(socket)); + platform.SetConnection (conn); if (platform.IsConnected()) { + if (inferior_arguments.GetArgumentCount() > 0) + { + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + uint16_t port = 0; + std::string socket_name; + Error error = platform.LaunchGDBServer(inferior_arguments, + "", // hostname + pid, + port, + socket_name); + if (error.Success()) + platform.SetPendingGdbServer(pid, port, socket_name); + else + fprintf(stderr, "failed to start gdbserver: %s\n", error.AsCString()); + } + // After we connected, we need to get an initial ack from... if (platform.HandshakeWithClient()) { |