Index: lldb.xcodeproj/project.pbxproj =================================================================== --- lldb.xcodeproj/project.pbxproj +++ lldb.xcodeproj/project.pbxproj @@ -103,6 +103,8 @@ 2579065C1BD0488100178368 /* TCPSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2579065A1BD0488100178368 /* TCPSocket.cpp */; }; 2579065D1BD0488100178368 /* UDPSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2579065B1BD0488100178368 /* UDPSocket.cpp */; }; 2579065F1BD0488D00178368 /* DomainSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2579065E1BD0488D00178368 /* DomainSocket.cpp */; }; + 257906641BD5AFD000178368 /* Acceptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 257906621BD5AFD000178368 /* Acceptor.cpp */; }; + 257906651BD5AFD000178368 /* Acceptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 257906631BD5AFD000178368 /* Acceptor.h */; }; 257E47171AA56C2000A62F81 /* ModuleCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 257E47151AA56C2000A62F81 /* ModuleCache.cpp */; }; 25EF23781AC09B3700908DF0 /* AdbClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25EF23751AC09AD800908DF0 /* AdbClient.cpp */; }; 260157C61885F51C00F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; }; @@ -1205,6 +1207,8 @@ 2579065A1BD0488100178368 /* TCPSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TCPSocket.cpp; sourceTree = ""; }; 2579065B1BD0488100178368 /* UDPSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UDPSocket.cpp; sourceTree = ""; }; 2579065E1BD0488D00178368 /* DomainSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DomainSocket.cpp; sourceTree = ""; }; + 257906621BD5AFD000178368 /* Acceptor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Acceptor.cpp; path = "tools/lldb-server/Acceptor.cpp"; sourceTree = ""; }; + 257906631BD5AFD000178368 /* Acceptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Acceptor.h; path = "tools/lldb-server/Acceptor.h"; sourceTree = ""; }; 257E47151AA56C2000A62F81 /* ModuleCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleCache.cpp; path = source/Utility/ModuleCache.cpp; sourceTree = ""; }; 257E47161AA56C2000A62F81 /* ModuleCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModuleCache.h; path = source/Utility/ModuleCache.h; sourceTree = ""; }; 25EF23751AC09AD800908DF0 /* AdbClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdbClient.cpp; sourceTree = ""; }; @@ -5578,6 +5582,8 @@ E769331B1A94D10E00C73337 /* lldb-server */ = { isa = PBXGroup; children = ( + 257906621BD5AFD000178368 /* Acceptor.cpp */, + 257906631BD5AFD000178368 /* Acceptor.h */, 6D762BEC1B1605CD006C929D /* LLDBServerUtilities.cpp */, 6D762BED1B1605CD006C929D /* LLDBServerUtilities.h */, E769331D1A94D18100C73337 /* lldb-server.cpp */, @@ -5693,6 +5699,7 @@ buildActionMask = 2147483647; files = ( 4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */, + 257906651BD5AFD000178368 /* Acceptor.h in Headers */, 260A63171861008E00FECF8E /* IOHandler.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -6528,6 +6535,7 @@ 268900E513353E6F00698AC0 /* UnwindTable.cpp in Sources */, 268900E613353E6F00698AC0 /* Variable.cpp in Sources */, 268900E713353E6F00698AC0 /* VariableList.cpp in Sources */, + 257906641BD5AFD000178368 /* Acceptor.cpp in Sources */, 268900E813353E6F00698AC0 /* ABI.cpp in Sources */, 4C56543119D1EFAA002E9C44 /* ThreadPlanPython.cpp in Sources */, 26AB92121819D74600E63F3E /* DWARFDataExtractor.cpp in Sources */, Index: source/Host/posix/ConnectionFileDescriptorPosix.cpp =================================================================== --- source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ 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 @@ // 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 @@ { 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) { Index: source/Plugins/Platform/Android/AdbClient.h =================================================================== --- source/Plugins/Platform/Android/AdbClient.h +++ source/Plugins/Platform/Android/AdbClient.h @@ -51,6 +51,9 @@ 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 Index: source/Plugins/Platform/Android/AdbClient.cpp =================================================================== --- source/Plugins/Platform/Android/AdbClient.cpp +++ source/Plugins/Platform/Android/AdbClient.cpp @@ -145,6 +145,19 @@ } 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]; Index: source/Plugins/Platform/Android/PlatformAndroid.cpp =================================================================== --- source/Plugins/Platform/Android/PlatformAndroid.cpp +++ source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -195,8 +195,7 @@ 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()) Index: source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h =================================================================== --- source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h +++ source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h @@ -40,8 +40,8 @@ std::string m_device_id; std::map m_port_forwards; - uint16_t - LaunchGDBserverAndGetPort (lldb::pid_t &pid) override; + bool + LaunchGDBserverAndGetPort (lldb::pid_t &pid, std::string &connect_url) override; bool KillSpawnedProcess (lldb::pid_t pid) override; @@ -49,14 +49,11 @@ 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); Index: source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp =================================================================== --- source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp +++ source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp @@ -24,7 +24,10 @@ 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 @@ 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 @@ DeleteForwardPortWithAdb(it.second, m_device_id); } -uint16_t -PlatformAndroidRemoteGDBServer::LaunchGDBserverAndGetPort (lldb::pid_t &pid) +bool +PlatformAndroidRemoteGDBServer::LaunchGDBserverAndGetPort (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.LaunchGDBserverAndGetPort ("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 @@ 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 @@ } 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 @@ // 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); -} Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h =================================================================== --- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -225,11 +225,11 @@ 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 + // Launch the lldb-gdbserver on the remote host and return true it is listening on + // 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); + virtual bool + LaunchGDBserverAndGetPort (lldb::pid_t &pid, std::string &connect_url); virtual bool KillSpawnedProcess (lldb::pid_t pid); @@ -244,7 +244,8 @@ 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); Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp =================================================================== --- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -34,12 +34,36 @@ #include "Plugins/Process/Utility/GDBRemoteSignals.h" +#include +#include +#include + using namespace lldb; using namespace lldb_private; using namespace lldb_private::platform_gdb_server; static bool g_initialized = false; +namespace { + +const int kNumRetries = 10; +const auto kWaitTimeout = std::chrono::milliseconds(500); + +Error +ConnectWithRetries(const std::function &connect_func) { + Error error; + for (int i = 0; i < kNumRetries; ++i) + { + error = connect_func(); + if (error.Success()) + break; + std::this_thread::sleep_for(kWaitTimeout); + } + return error; +} + +} + void PlatformRemoteGDBServer::Initialize () { @@ -368,8 +392,14 @@ if (!UriParser::Parse(url, m_platform_scheme, m_platform_hostname, port, path)) return Error("Invalid URL: %s", url); - const ConnectionStatus status = m_gdb_client.Connect(url, &error); - if (status == eConnectionStatusSuccess) + error = ConnectWithRetries([&](){ + Error e; + const ConnectionStatus status = m_gdb_client.Connect(url, &e); + if (status != eConnectionStatusSuccess) + e.SetErrorStringWithFormat("Received invalid connection status: %d", status); + return e; + }); + if (error.Success()) { if (m_gdb_client.HandshakeWithServer(&error)) { @@ -573,9 +603,8 @@ 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 (!LaunchGDBserverAndGetPort(debugserver_pid, connect_url)) { error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ()); } @@ -606,12 +635,9 @@ 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()) - error = process_sp->ConnectRemote (nullptr, connect_url.c_str()); + error = ConnectWithRetries([&](){ + return process_sp->ConnectRemote (nullptr, connect_url.c_str()); + }); if (error.Success()) error = process_sp->Launch(launch_info); else if (debugserver_pid != LLDB_INVALID_PROCESS_ID) @@ -632,23 +658,36 @@ } -uint16_t -PlatformRemoteGDBServer::LaunchGDBserverAndGetPort (lldb::pid_t &pid) +bool +PlatformRemoteGDBServer::LaunchGDBserverAndGetPort (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.LaunchGDBserverAndGetPort ("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.LaunchGDBserverAndGetPort (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 +708,8 @@ 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 (!LaunchGDBserverAndGetPort(debugserver_pid, connect_url)) { error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ()); } @@ -702,9 +740,9 @@ if (process_sp) { - std::string connect_url = - MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port); - error = process_sp->ConnectRemote(nullptr, connect_url.c_str()); + error = ConnectWithRetries([&](){ + return process_sp->ConnectRemote (nullptr, connect_url.c_str()); + }); if (error.Success()) { auto listener = attach_info.GetHijackListener(); @@ -956,7 +994,8 @@ 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"); @@ -966,17 +1005,19 @@ 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(); Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -167,11 +167,10 @@ // 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); Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -1112,17 +1112,15 @@ } 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 : "", in_port, out_port); + log->Printf ("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16, __FUNCTION__, url ? url : "", 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 @@ 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"); @@ -1216,9 +1206,9 @@ llvm::SmallString named_pipe_path; Pipe port_pipe; - if (in_port == 0) + if (port != nullptr && *port == 0) { - 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 @@ -1270,11 +1260,11 @@ 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,7 +1333,9 @@ 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 && + port != nullptr) { if (named_pipe_path.size() > 0) { @@ -1368,11 +1360,11 @@ if (error.Success()) { 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); + __FUNCTION__, *port); } else { Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -114,8 +114,11 @@ bool GetLaunchSuccess (std::string &error_str); - uint16_t - LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname); + bool + LaunchGDBserverAndGetPort (const char *remote_accept_hostname, + lldb::pid_t &pid, + uint16_t &port, + std::string &socket_name); bool KillSpawnedProcess (lldb::pid_t pid); Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -3315,10 +3315,16 @@ 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::LaunchGDBserverAndGetPort (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 @@ // 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 Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -12,6 +12,8 @@ #include "GDBRemoteCommunicationServerCommon.h" +#include "lldb/Host/Socket.h" + #include namespace lldb_private { @@ -23,7 +25,7 @@ public: typedef std::map PortMap; - GDBRemoteCommunicationServerPlatform(); + GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol); virtual ~GDBRemoteCommunicationServerPlatform(); @@ -61,6 +63,7 @@ SetPortOffset (uint16_t port_offset); protected: + const Socket::SocketProtocol m_socket_protocol; Mutex m_spawned_pids_mutex; std::set m_spawned_pids; lldb::PlatformSP m_platform_sp; @@ -103,6 +106,12 @@ int signal, int status); + static const FileSpec& + GetDomainSocketDir(); + + static FileSpec + GetDomainSocketPath(const char* prefix); + //------------------------------------------------------------------ // For GDBRemoteCommunicationServerPlatform only //------------------------------------------------------------------ Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -15,20 +15,26 @@ // C++ Includes #include #include +#include +#include // Other libraries and framework includes #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" #include "lldb/Target/Process.h" #include "lldb/Target/UnixSignals.h" +#include "llvm/Support/FileSystem.h" + // Project includes #include "Utility/StringExtractorGDBRemote.h" #include "Utility/UriParser.h" @@ -40,8 +46,9 @@ //---------------------------------------------------------------------- // 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 @@ 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 @@ 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 @@ 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 socket_path; + llvm::SmallString 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) { Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -3562,15 +3562,22 @@ // 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(); Index: tools/lldb-server/Acceptor.h =================================================================== --- /dev/null +++ tools/lldb-server/Acceptor.h @@ -0,0 +1,57 @@ +//===-- Acceptor.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef lldb_server_Acceptor_h_ +#define lldb_server_Acceptor_h_ + +#include "lldb/Core/Connection.h" +#include "lldb/Core/Error.h" +#include "lldb/Host/Socket.h" + +#include +#include + +namespace llvm +{ + class StringRef; +} + +namespace lldb_private { +namespace lldb_server { + +class Acceptor +{ +public: + virtual ~Acceptor() = default; + + Error + Listen(int backlog); + + Error + Accept(const bool child_processes_inherit, Connection *&conn); + + static std::unique_ptr + Create(llvm::StringRef name, const bool child_processes_inherit, Error &error); + + Socket::SocketProtocol GetSocketProtocol() const; + + // returns port number or 0 if error + uint16_t GetTCPLocalPort() const; + +private: + Acceptor(std::unique_ptr &&listener_socket, + llvm::StringRef name); + + const std::unique_ptr m_listener_socket_up; + const std::string m_name; +}; + +} // namespace lldb_server +} // namespace lldb_private + +#endif // lldb_server_Acceptor_h_ Index: tools/lldb-server/Acceptor.cpp =================================================================== --- /dev/null +++ tools/lldb-server/Acceptor.cpp @@ -0,0 +1,84 @@ +//===-- Acceptor.cpp --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Acceptor.h" + +#include "lldb/Core/StreamString.h" +#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/common/TCPSocket.h" +#include "lldb/Host/posix/DomainSocket.h" +#include "llvm/ADT/StringRef.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::lldb_server; +using namespace llvm; + +Error +Acceptor::Listen(int backlog) +{ + return m_listener_socket_up->Listen(StringRef(m_name.c_str()), + backlog); +} + +Error +Acceptor::Accept(const bool child_processes_inherit, Connection *&conn) +{ + Socket* conn_socket = nullptr; + auto error = m_listener_socket_up->Accept(StringRef(m_name.c_str()), + child_processes_inherit, + conn_socket); + if (error.Success()) + conn = new ConnectionFileDescriptor(conn_socket); + + return error; +} + +Socket::SocketProtocol +Acceptor::GetSocketProtocol() const +{ + return m_listener_socket_up->GetSocketProtocol(); +} + +// returns port number or 0 if error +uint16_t +Acceptor::GetTCPLocalPort() const +{ + assert(GetSocketProtocol() == Socket::ProtocolTcp); + const TCPSocket& tcp_socket(static_cast(*m_listener_socket_up)); + return tcp_socket.GetLocalPortNumber(); +} + +std::unique_ptr +Acceptor::Create(StringRef name, const bool child_processes_inherit, Error &error) +{ + error.Clear(); + + std::unique_ptr listener_socket = nullptr; + std::string host_str; + std::string port_str; + int32_t port = INT32_MIN; + if (Socket::DecodeHostAndPort (name, host_str, port_str, port, &error)) + listener_socket.reset(new TCPSocket(child_processes_inherit, error)); + else + listener_socket.reset(new DomainSocket(child_processes_inherit, error)); + + if (error.Success()) + return std::unique_ptr( + new Acceptor(std::move(listener_socket), name)); + + return std::unique_ptr(); +} + +Acceptor::Acceptor(std::unique_ptr &&listener_socket, + StringRef name) + : m_listener_socket_up(std::move(listener_socket)), + m_name(name.str()) +{ +} Index: tools/lldb-server/CMakeLists.txt =================================================================== --- tools/lldb-server/CMakeLists.txt +++ tools/lldb-server/CMakeLists.txt @@ -18,24 +18,18 @@ include(../../cmake/LLDBDependencies.cmake) -if (BUILD_SHARED_LIBS ) - add_lldb_executable(lldb-server +add_lldb_executable(lldb-server + Acceptor.cpp lldb-gdbserver.cpp lldb-platform.cpp lldb-server.cpp LLDBServerUtilities.cpp - ) +) +if (BUILD_SHARED_LIBS ) target_link_libraries(lldb-server liblldb) target_link_libraries(lldb-server ${LLDB_SYSTEM_LIBS}) else() - add_lldb_executable(lldb-server - lldb-gdbserver.cpp - lldb-platform.cpp - lldb-server.cpp - LLDBServerUtilities.cpp - ) - # The Darwin linker doesn't understand --start-group/--end-group. if (LLDB_LINKER_SUPPORTS_GROUPS) target_link_libraries(lldb-server Index: tools/lldb-server/lldb-gdbserver.cpp =================================================================== --- tools/lldb-server/lldb-gdbserver.cpp +++ tools/lldb-server/lldb-gdbserver.cpp @@ -24,18 +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/HostGetOpt.h" -#include "lldb/Host/HostThread.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::lldb_server; using namespace lldb_private::process_gdb_remote; -// lldb-gdbserver state - -namespace -{ -HostThread s_listen_thread; - std::unique_ptr s_listen_connection_up; - std::string s_listen_url; -} - //---------------------------------------------------------------------- // option descriptors for getopt_long_only() //---------------------------------------------------------------------- @@ -263,51 +252,6 @@ } } -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) { @@ -370,14 +314,8 @@ 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 connection_up; + std::unique_ptr connection_up; if (reverse_connect) { @@ -410,66 +348,55 @@ } 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 (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_up(Acceptor::Create(final_host_and_port, false, error)); + if (error.Fail()) { - const uint16_t bound_port = s_listen_connection_up->GetListeningPort (10); - if (bound_port > 0) - { - error = writePortToPipe (named_pipe_path, bound_port); - if (error.Fail ()) - { - fprintf (stderr, "failed to write to the named pipe \'%s\': %s", named_pipe_path, error.AsCString()); - } - } - else - { - fprintf (stderr, "unable to get the bound port for the listening connection\n"); - } + fprintf(stderr, "failed to create acceptor: %s", error.AsCString()); + exit(1); } - - // If we have an unnamed pipe to write the port number back to, do that now. - if (unnamed_pipe_fd >= 0 && connection_portno == 0) + error = acceptor_up->Listen(1); + if (error.Fail()) + { + fprintf(stderr, "failed to listen: %s\n", error.AsCString()); + exit(1); + } + if (acceptor_up->GetSocketProtocol() == Socket::ProtocolTcp && + connection_portno == 0) { - const uint16_t bound_port = s_listen_connection_up->GetListeningPort(10); + const uint16_t bound_port = acceptor_up->GetTCPLocalPort(); if (bound_port > 0) { - error = writePortToPipe(unnamed_pipe_fd, bound_port); - if (error.Fail()) + // If we have a named pipe to write the port number back to, do that now. + if (named_pipe_path && named_pipe_path[0]) + { + error = writePortToPipe (named_pipe_path, bound_port); + if (error.Fail ()) + fprintf (stderr, "failed to write to the named pipe \'%s\': %s", + named_pipe_path, error.AsCString()); + } + // If we have an unnamed pipe to write the port number back to, do that now. + else if (unnamed_pipe_fd >= 0) { - fprintf(stderr, "failed to write to the unnamed pipe: %s", - error.AsCString()); + error = writePortToPipe(unnamed_pipe_fd, bound_port); + 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"); + fprintf (stderr, "unable to get the bound port for the listening connection\n"); } } - // Join the listener thread. - if (!JoinListenThread ()) - { - fprintf (stderr, "failed to join the listener thread\n"); - display_usage (progname, subcommand); - exit (1); - } - - // 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()) Index: tools/lldb-server/lldb-platform.cpp =================================================================== --- tools/lldb-server/lldb-platform.cpp +++ tools/lldb-server/lldb-platform.cpp @@ -32,6 +32,7 @@ #include "lldb/Host/common/TCPSocket.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" +#include "Acceptor.h" #include "LLDBServerUtilities.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" @@ -282,30 +283,29 @@ display_usage(progname, subcommand); exit(option_error); } - - Socket *socket = nullptr; - const bool children_inherit_listen_socket = false; + 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; - std::unique_ptr listening_socket_up(new TCPSocket(children_inherit_listen_socket, error)); + + std::unique_ptr acceptor_up(Acceptor::Create(listen_host_port, children_inherit_listen_socket, error)); if (error.Fail()) { - fprintf(stderr, "failed to create socket: %s", error.AsCString()); + fprintf(stderr, "failed to create acceptor: %s", error.AsCString()); exit(socket_error); } - error = listening_socket_up->Listen(listen_host_port.c_str(), backlog); + error = acceptor_up->Listen(backlog); if (error.Fail()) { - printf("error: %s\n", error.AsCString()); + printf("failed to listen: %s\n", error.AsCString()); exit(socket_error); } - if (port_file) + if (port_file && acceptor_up->GetSocketProtocol() == Socket::ProtocolTcp) { - error = save_port_to_file(listening_socket_up->GetLocalPortNumber(), port_file); + error = save_port_to_file(acceptor_up->GetTCPLocalPort(), port_file); if (error.Fail()) { fprintf(stderr, "failed to write port to %s: %s", port_file.GetPath().c_str(), error.AsCString()); @@ -314,7 +314,7 @@ } do { - GDBRemoteCommunicationServerPlatform platform; + GDBRemoteCommunicationServerPlatform platform(acceptor_up->GetSocketProtocol()); if (port_offset > 0) platform.SetPortOffset(port_offset); @@ -325,8 +325,8 @@ } const bool children_inherit_accept_socket = true; - socket = nullptr; - error = listening_socket_up->Accept(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()); @@ -340,8 +340,7 @@ 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; @@ -351,16 +350,16 @@ // 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()) {