[Lldb-commits] [lldb] r198963 - Revert to getting a random port and sending that down to debugserver for iOS. The sandboxing is not letting debugserver reverse connect back to lldb.

Greg Clayton gclayton at apple.com
Fri Jan 10 14:24:11 PST 2014


Author: gclayton
Date: Fri Jan 10 16:24:11 2014
New Revision: 198963

URL: http://llvm.org/viewvc/llvm-project?rev=198963&view=rev
Log:
Revert to getting a random port and sending that down to debugserver for iOS. The sandboxing is not letting debugserver reverse connect back to lldb.

<rdar://problem/15789865>


Modified:
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=198963&r1=198962&r2=198963&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Fri Jan 10 16:24:11 2014
@@ -598,12 +598,12 @@ GDBRemoteCommunication::ListenThread (ll
 }
 
 Error
-GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
+GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
+                                                 uint16_t in_port,
                                                  lldb_private::ProcessLaunchInfo &launch_info,
-                                                 uint16_t &port)
+                                                 uint16_t &out_port)
 {
-    port = 0;
-
+    out_port = in_port;
     Error error;
     // If we locate debugserver, keep that located version around
     static FileSpec g_debugserver_file_spec;
@@ -651,8 +651,17 @@ GDBRemoteCommunication::StartDebugserver
         debugserver_args.AppendArgument(debugserver_path);
 
         // If a host and port is supplied then use it
-        if (host_and_port)
+        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';
+        }
+
         // use native registers, not the GDB registers
         debugserver_args.AppendArgument("--native-regs");   
         // make debugserver run in its own session so signals generated by 
@@ -661,34 +670,45 @@ GDBRemoteCommunication::StartDebugserver
 
         char named_pipe_path[PATH_MAX];
 
-        if (host_and_port)
+        bool listen = false;
+        if (host_and_port[0])
         {
             // 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
             // if all goes well and fill the data into "command_output_ptr"
-            FileSpec tmpdir_file_spec;
-            if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
-            {
-                tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX");
-                strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));
-            }
-            else
-            {
-                strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path));
-            }
 
-            if (::mktemp (named_pipe_path))
+            if (in_port == 0)
             {
-                if (::mkfifo(named_pipe_path, 0600) == 0)
+                // Binding to port zero, we need to figure out what port it ends up
+                // using using a named pipe...
+                FileSpec tmpdir_file_spec;
+                if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
                 {
-                    debugserver_args.AppendArgument("--named-pipe");
-                    debugserver_args.AppendArgument(named_pipe_path);
+                    tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX");
+                    strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));
+                }
+                else
+                {
+                    strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path));
+                }
+
+                if (::mktemp (named_pipe_path))
+                {
+                    if (::mkfifo(named_pipe_path, 0600) == 0)
+                    {
+                        debugserver_args.AppendArgument("--named-pipe");
+                        debugserver_args.AppendArgument(named_pipe_path);
+                    }
+                    else
+                        named_pipe_path[0] = '\0';
                 }
                 else
                     named_pipe_path[0] = '\0';
             }
             else
-                named_pipe_path[0] = '\0';
+            {
+                listen = true;
+            }
         }
         else
         {
@@ -701,10 +721,10 @@ GDBRemoteCommunication::StartDebugserver
                 return error;
 
             ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
-            port = connection->GetBoundPort(3);
-            assert (port != 0);
+            out_port = connection->GetBoundPort(3);
+            assert (out_port != 0);
             char port_cstr[32];
-            snprintf(port_cstr, sizeof(port_cstr), "localhost:%i", port);
+            snprintf(port_cstr, sizeof(port_cstr), "localhost:%i", out_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");
@@ -746,11 +766,15 @@ GDBRemoteCommunication::StartDebugserver
                 error = name_pipe_file.Read(port_cstr, num_bytes);
                 assert (error.Success());
                 assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
-                port = Args::StringToUInt32(port_cstr, 0);
+                out_port = Args::StringToUInt32(port_cstr, 0);
                 name_pipe_file.Close();
             }
             Host::Unlink(named_pipe_path);
         }
+        else if (listen)
+        {
+            
+        }
         else
         {
             // Make sure we actually connect with the debugserver...

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=198963&r1=198962&r2=198963&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Fri Jan 10 16:24:11 2014
@@ -121,9 +121,10 @@ public:
     // supplied connection URL.
     //------------------------------------------------------------------
     lldb_private::Error
-    StartDebugserverProcess (const char *host_and_port,
+    StartDebugserverProcess (const char *hostname,
+                             uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
                              lldb_private::ProcessLaunchInfo &launch_info,
-                             uint16_t &port);
+                             uint16_t &out_port);
 
     void
     DumpHistory(lldb_private::Stream &strm);

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=198963&r1=198962&r2=198963&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Fri Jan 10 16:24:11 2014
@@ -841,18 +841,16 @@ GDBRemoteCommunicationServer::Handle_qLa
         {
             // 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);
+                log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port);
 
             debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
             
-            error = StartDebugserverProcess (host_and_port_cstr,
+            error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(),
+                                             port,
                                              debugserver_launch_info,
                                              port);
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=198963&r1=198962&r2=198963&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Jan 10 16:24:11 2014
@@ -167,6 +167,34 @@ namespace {
     
 } // anonymous namespace end
 
+static bool rand_initialized = false;
+
+// TODO Randomly assigning a port is unsafe.  We should get an unused
+// ephemeral port from the kernel and make sure we reserve it before passing
+// it to debugserver.
+
+#if defined (__APPLE__)
+#define LOW_PORT    (IPPORT_RESERVED)
+#define HIGH_PORT   (IPPORT_HIFIRSTAUTO)
+#else
+#define LOW_PORT    (1024u)
+#define HIGH_PORT   (49151u)
+#endif
+
+static inline uint16_t
+get_random_port ()
+{
+    if (!rand_initialized)
+    {
+        time_t seed = time(NULL);
+        
+        rand_initialized = true;
+        srand(seed);
+    }
+    return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT;
+}
+
+
 lldb_private::ConstString
 ProcessGDBRemote::GetPluginNameStatic()
 {
@@ -2514,7 +2542,6 @@ Error
 ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
 {
     Error error;
-    uint16_t port = 0;
     if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
     {
         // If we locate debugserver, keep that located version around
@@ -2524,7 +2551,20 @@ ProcessGDBRemote::LaunchAndConnectToDebu
         debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
         debugserver_launch_info.SetUserID(process_info.GetUserID());
 
-        error = m_gdb_comm.StartDebugserverProcess (NULL,
+#if defined (__APPLE__) && defined (__arm__)
+        // On iOS, still do a local connection using a random port
+        const char *hostname = "localhost";
+        uint16_t port = get_random_port ();
+#else
+        // 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;
+        uint16_t port = 0;
+#endif
+
+        error = m_gdb_comm.StartDebugserverProcess (hostname,
+                                                    port,
                                                     debugserver_launch_info,
                                                     port);
 
@@ -2552,9 +2592,9 @@ ProcessGDBRemote::LaunchAndConnectToDebu
         }
         else
         {
-            char connect_url[128];
-            snprintf (connect_url, sizeof(connect_url), "connect://localhost:%u", port);
-            error = ConnectToDebugserver (connect_url);
+            StreamString connect_url;
+            connect_url.Printf("connect://%s:%u", hostname, port);
+            error = ConnectToDebugserver (connect_url.GetString().c_str());
         }
 
     }





More information about the lldb-commits mailing list