diff options
author | Greg Clayton <gclayton@apple.com> | 2013-11-21 01:44:58 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-11-21 01:44:58 +0000 |
commit | 29b8fc4da9abc1c599899c3cd90dfb88fcd71562 (patch) | |
tree | 768dbab79a26e23b56071b2bf4a3743617770d84 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp | |
parent | a16725b6b65ddad7c29830814bceafbf42731fbb (diff) | |
download | llvm-29b8fc4da9abc1c599899c3cd90dfb88fcd71562.zip llvm-29b8fc4da9abc1c599899c3cd90dfb88fcd71562.tar.gz llvm-29b8fc4da9abc1c599899c3cd90dfb88fcd71562.tar.bz2 |
Added new options to lldb-platform:
--gdbserver-port PORT
--min-gdbserver-port PORT
--max-gdbserver-port PORT
The --gdbserver-port option can be specified multiple times to tell lldb-platform which ports it can use when launching child GDB server processes.
The --min-gdbserver-port and --max-gdbserver-port options allow a range of ports to be specified for use when launching child GDB server processes.
Fixed the code to manage these ports correctly in GDBRemoteCommunicationServer.
Also changed GDBRemoteCommunicationClient to not set a port when sending the "qLaunchGDBServer" packet so that the remote lldb-platform can decide which ports to use. If the lldb-platform was launched with no --gdbserver-port or --min-gdbserver-port/--max-gdbserver-port options, then port 0 is always used and a unix socket is used between the lldb-platform and child GDB server process to coordinate the use of valid port.
llvm-svn: 195300
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp | 191 |
1 files changed, 93 insertions, 98 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 77cc640..6d1891a 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -47,27 +47,8 @@ GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) : m_spawned_pids_mutex (Mutex::eMutexTypeRecursive), m_proc_infos (), m_proc_infos_index (0), - m_lo_port_num (0), - m_hi_port_num (0), - m_next_port (0), - m_use_port_range (false) + m_port_map () { - // We seldom need to override the port number that the debugserver process - // starts with. We just pass in 0 to let the system choose a random port. - // In rare situation where the need arises, use two environment variables - // to override. - uint16_t lo_port_num = 0; - uint16_t hi_port_num = 0; - const char *lo_port_c_str = getenv("LLDB_PLATFORM_START_DEBUG_SERVER_LO_PORT"); - if (lo_port_c_str) - lo_port_num = ::atoi(lo_port_c_str); - const char *hi_port_c_str = getenv("LLDB_PLATFORM_START_DEBUG_SERVER_HI_PORT"); - if (hi_port_c_str) - hi_port_num = ::atoi(hi_port_c_str); - if (lo_port_num && hi_port_num && lo_port_num < hi_port_num) - { - SetPortRange(lo_port_num, hi_port_num); - } } //---------------------------------------------------------------------- @@ -743,6 +724,7 @@ bool GDBRemoteCommunicationServer::DebugserverProcessReaped (lldb::pid_t pid) { Mutex::Locker locker (m_spawned_pids_mutex); + FreePortForProcess(pid); return m_spawned_pids.erase(pid) > 0; } bool @@ -776,106 +758,119 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote std::string hostname; // TODO: /tmp/ should not be hardcoded. User might want to override /tmp // with the TMPDIR environnement variable - char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX"; - if (::mkstemp (unix_socket_name) == -1) + packet.SetFilePos(::strlen ("qLaunchGDBServer;")); + std::string name; + std::string value; + uint16_t port = UINT16_MAX; + while (packet.GetNameColonValue(name, value)) { - error.SetErrorStringWithFormat("failed to make temporary path for a unix socket: %s", strerror(errno)); + if (name.compare ("host") == 0) + hostname.swap(value); + else if (name.compare ("port") == 0) + port = Args::StringToUInt32(value.c_str(), 0, 0); } - else - { - packet.SetFilePos(::strlen ("qLaunchGDBServer:")); - std::string name; - std::string value; - uint16_t port = UINT16_MAX; - while (packet.GetNameColonValue(name, value)) - { - if (name.compare ("host") == 0) - hostname.swap(value); - else if (name.compare ("port") == 0) - port = Args::StringToUInt32(value.c_str(), 0, 0); - } - if (port == UINT16_MAX) - port = GetAndUpdateNextPort(); + if (port == UINT16_MAX) + port = GetNextAvailablePort(); - ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name); - // Spawn a new thread to accept the port that gets bound after - // binding to port 0 (zero). - lldb::thread_t accept_thread = LLDB_INVALID_HOST_THREAD; + // Spawn a new thread to accept the port that gets bound after + // binding to port 0 (zero). + lldb::thread_t accept_thread = LLDB_INVALID_HOST_THREAD; + const char *unix_socket_name = NULL; + char unix_socket_name_buf[PATH_MAX] = "/tmp/XXXXXXXXX"; - if (port == 0) + if (port == 0) + { + if (::mkstemp (unix_socket_name_buf) == 0) { + unix_socket_name = unix_socket_name_buf; + ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name); accept_thread = Host::ThreadCreate (unix_socket_name, AcceptPortFromInferior, connect_url, &error); } - - if (IS_VALID_LLDB_HOST_THREAD(accept_thread)) + else { - // Spawn a debugserver and try to get the port it listens to. - ProcessLaunchInfo debugserver_launch_info; - StreamString host_and_port; - if (hostname.empty()) - hostname = "localhost"; - host_and_port.Printf("%s:%u", hostname.c_str(), port); - const char *host_and_port_cstr = host_and_port.GetString().c_str(); - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) - log->Printf("Launching debugserver with: %s...\n", host_and_port_cstr); - - debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); - - error = StartDebugserverProcess (host_and_port_cstr, - unix_socket_name, - debugserver_launch_info); - - lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); + error.SetErrorStringWithFormat("failed to make temporary path for a unix socket: %s", strerror(errno)); + } + } + if (error.Success()) + { + // Spawn a debugserver and try to get the port it listens to. + ProcessLaunchInfo debugserver_launch_info; + StreamString host_and_port; + if (hostname.empty()) + hostname = "localhost"; + host_and_port.Printf("%s:%u", hostname.c_str(), port); + const char *host_and_port_cstr = host_and_port.GetString().c_str(); + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) + log->Printf("Launching debugserver with: %s...\n", host_and_port_cstr); + + debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); + + error = StartDebugserverProcess (host_and_port_cstr, + unix_socket_name, + debugserver_launch_info); + + lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); + + + if (debugserver_pid != LLDB_INVALID_PROCESS_ID) + { + Mutex::Locker locker (m_spawned_pids_mutex); + m_spawned_pids.insert(debugserver_pid); + if (port > 0) + AssociatePortWithProcess(port, debugserver_pid); + } + else + { + if (port > 0) + FreePort (port); + } - if (debugserver_pid != LLDB_INVALID_PROCESS_ID) - { - Mutex::Locker locker (m_spawned_pids_mutex); - m_spawned_pids.insert(debugserver_pid); - } + if (error.Success()) + { + bool success = false; - if (error.Success()) + if (IS_VALID_LLDB_HOST_THREAD(accept_thread)) { - bool success = false; - - if (accept_thread) + thread_result_t accept_thread_result = NULL; + if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error)) { - thread_result_t accept_thread_result = NULL; - if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error)) + if (accept_thread_result) { - if (accept_thread_result) - { - port = (intptr_t)accept_thread_result; - char response[256]; - const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port); - assert (response_len < sizeof(response)); - //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); - success = SendPacketNoLock (response, response_len) > 0; - } + port = (intptr_t)accept_thread_result; + char response[256]; + const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port); + assert (response_len < sizeof(response)); + //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); + success = SendPacketNoLock (response, response_len) > 0; } } - else - { - char response[256]; - const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port); - assert (response_len < sizeof(response)); - //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); - success = SendPacketNoLock (response, response_len) > 0; + } + else + { + char response[256]; + const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port); + assert (response_len < sizeof(response)); + //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); + success = SendPacketNoLock (response, response_len) > 0; - } - ::unlink (unix_socket_name); + } + Host::Unlink (unix_socket_name); - if (!success) - { - if (debugserver_pid != LLDB_INVALID_PROCESS_ID) - ::kill (debugserver_pid, SIGINT); - } - return success; + if (!success) + { + if (debugserver_pid != LLDB_INVALID_PROCESS_ID) + ::kill (debugserver_pid, SIGINT); } + return success; + } + else if (accept_thread) + { + Host::Unlink (unix_socket_name); } } } |