Modified local spawning in debugserver processes to use a new --reverse-connect option so that debugserver actually connects back to LLDB instead of LLDB connecting to debugserver.
This gets rid of our hacky "get_random_port()" which would grab a random port and tell debugserver to open that port. Now LLDB creates, binds, listens and accepts a connection by binding to port zero and sending the correctly bound port down as the host:port to connect back to.
Fixed the "ConnectionFileDescriptor" to be able to correctly listen for connections from a specified host, localhost, or any host. Prior to this fix "listen://" only accepted the following format:
listen://<port>
But now it can accept:
listen://<port> // Listen for connection from localhost on port <port>
listen://<host>:<port> // Listen for connection from <host> and <port>
listen://*:<port> // Listen for connection from any host on port <port>
llvm-svn: 196547
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 4527897..c6dc6cf 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -845,31 +845,35 @@
ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
{
Error error;
- // Sleep and wait a bit for debugserver to start to listen...
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
- if (conn_ap.get())
+ // Only connect if we have a valid connect URL
+
+ if (connect_url && connect_url[0])
{
- const uint32_t max_retry_count = 50;
- uint32_t retry_count = 0;
- while (!m_gdb_comm.IsConnected())
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
+ if (conn_ap.get())
{
- if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
+ const uint32_t max_retry_count = 50;
+ uint32_t retry_count = 0;
+ while (!m_gdb_comm.IsConnected())
{
- m_gdb_comm.SetConnection (conn_ap.release());
- break;
- }
- else if (error.WasInterrupted())
- {
- // If we were interrupted, don't keep retrying.
- break;
- }
-
- retry_count++;
-
- if (retry_count >= max_retry_count)
- break;
+ if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
+ {
+ m_gdb_comm.SetConnection (conn_ap.release());
+ break;
+ }
+ else if (error.WasInterrupted())
+ {
+ // If we were interrupted, don't keep retrying.
+ break;
+ }
+
+ retry_count++;
+
+ if (retry_count >= max_retry_count)
+ break;
- usleep (100000);
+ usleep (100000);
+ }
}
}
@@ -2501,9 +2505,9 @@
debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
debugserver_launch_info.SetUserID(process_info.GetUserID());
- error = GDBRemoteCommunication::StartDebugserverProcess ("localhost:0",
- debugserver_launch_info,
- port);
+ error = m_gdb_comm.StartDebugserverProcess (NULL,
+ debugserver_launch_info,
+ port);
if (error.Success ())
m_debugserver_pid = debugserver_launch_info.GetProcessID();
@@ -2522,10 +2526,17 @@
return error;
}
- char connect_url[128];
- snprintf (connect_url, sizeof(connect_url), "connect://localhost:%u", port);
-
- error = ConnectToDebugserver (connect_url);
+ if (m_gdb_comm.IsConnected())
+ {
+ // Finish the connection process by doing the handshake without connecting (send NULL URL)
+ ConnectToDebugserver (NULL);
+ }
+ else
+ {
+ char connect_url[128];
+ snprintf (connect_url, sizeof(connect_url), "connect://localhost:%u", port);
+ error = ConnectToDebugserver (connect_url);
+ }
}
return error;