[Lldb-commits] [lldb] r196401 - Switch local launching of debugserver over to always use a FIFO in order to handshake with the launched debugserver.

Greg Clayton gclayton at apple.com
Wed Dec 4 11:19:12 PST 2013


Author: gclayton
Date: Wed Dec  4 13:19:12 2013
New Revision: 196401

URL: http://llvm.org/viewvc/llvm-project?rev=196401&view=rev
Log:
Switch local launching of debugserver over to always use a FIFO in order to handshake with the launched debugserver.

This helps ensure that the launched debugserver is ready and listening for a connection. Prior to this we had a race condition.

Consolidate the launching of debugserver into a single place: a static function in GDBRemoteCommunication.


Modified:
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
    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
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp
    lldb/trunk/tools/debugserver/source/RNBSocket.cpp
    lldb/trunk/tools/debugserver/source/debugserver.cpp

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h?rev=196401&r1=196400&r2=196401&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h Wed Dec  4 13:19:12 2013
@@ -142,15 +142,6 @@ public:
     {
         return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
     }
-    //------------------------------------------------------------------
-    // Start a debugserver instance on the current host using the
-    // supplied connection URL.
-    //------------------------------------------------------------------
-    lldb_private::Error
-    StartDebugserverProcess (const char *connect_url,
-                             const char *unix_socket_name,
-                             lldb_private::ProcessLaunchInfo &launch_info); 
-
     
     //------------------------------------------------------------------
     // Public Request Packets

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=196401&r1=196400&r2=196401&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Wed Dec  4 13:19:12 2013
@@ -13,6 +13,7 @@
 // C Includes
 #include <limits.h>
 #include <string.h>
+#include <sys/stat.h>
 
 // C++ Includes
 // Other libraries and framework includes
@@ -539,9 +540,11 @@ GDBRemoteCommunication::CheckForPacket (
 
 Error
 GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
-                                                 const char *unix_socket_name,  // For handshaking
-                                                 lldb_private::ProcessLaunchInfo &launch_info)
+                                                 lldb_private::ProcessLaunchInfo &launch_info,
+                                                 uint16_t &port)
 {
+    port = 0;
+
     Error error;
     // If we locate debugserver, keep that located version around
     static FileSpec g_debugserver_file_spec;
@@ -598,11 +601,34 @@ GDBRemoteCommunication::StartDebugserver
         // special terminal key sequences (^C) don't affect debugserver
         debugserver_args.AppendArgument("--setsid");
         
-        if (unix_socket_name && unix_socket_name[0])
+        char named_pipe_path[PATH_MAX];
+        
+        // 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))
         {
-            debugserver_args.AppendArgument("--unix-socket");
-            debugserver_args.AppendArgument(unix_socket_name);
+            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';
 
         const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
         if (env_debugserver_log_file)
@@ -617,46 +643,33 @@ GDBRemoteCommunication::StartDebugserver
             ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
             debugserver_args.AppendArgument(arg_cstr);
         }
-        //            debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
-        //            debugserver_args.AppendArgument("--log-flags=0x802e0e");
-        
-        // We currently send down all arguments, attach pids, or attach 
-        // process names in dedicated GDB server packets, so we don't need
-        // to pass them as arguments. This is currently because of all the
-        // things we need to setup prior to launching: the environment,
-        // current working dir, file actions, etc.
-#if 0
-        // Now append the program arguments
-        if (inferior_argv)
-        {
-            // Terminate the debugserver args so we can now append the inferior args
-            debugserver_args.AppendArgument("--");
-            
-            for (int i = 0; inferior_argv[i] != NULL; ++i)
-                debugserver_args.AppendArgument (inferior_argv[i]);
-        }
-        else if (attach_pid != LLDB_INVALID_PROCESS_ID)
-        {
-            ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
-            debugserver_args.AppendArgument (arg_cstr);
-        }
-        else if (attach_name && attach_name[0])
-        {
-            if (wait_for_launch)
-                debugserver_args.AppendArgument ("--waitfor");
-            else
-                debugserver_args.AppendArgument ("--attach");
-            debugserver_args.AppendArgument (attach_name);
-        }
-#endif
         
         // Close STDIN, STDOUT and STDERR. We might need to redirect them
         // to "/dev/null" if we run into any problems.
-//        launch_info.AppendCloseFileAction (STDIN_FILENO);
-//        launch_info.AppendCloseFileAction (STDOUT_FILENO);
-//        launch_info.AppendCloseFileAction (STDERR_FILENO);
+        launch_info.AppendCloseFileAction (STDIN_FILENO);
+        launch_info.AppendCloseFileAction (STDOUT_FILENO);
+        launch_info.AppendCloseFileAction (STDERR_FILENO);
         
         error = Host::LaunchProcess(launch_info);
+        
+        if (named_pipe_path[0])
+        {
+            File name_pipe_file;
+            error = name_pipe_file.Open(named_pipe_path, File::eOpenOptionRead);
+            if (error.Success())
+            {
+                char port_cstr[256];
+                port_cstr[0] = '\0';
+                size_t num_bytes = sizeof(port_cstr);
+                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);
+                name_pipe_file.Close();
+            }
+            Host::Unlink(named_pipe_path);
+        }
+
     }
     else
     {

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=196401&r1=196400&r2=196401&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Wed Dec  4 13:19:12 2013
@@ -108,10 +108,10 @@ public:
     // Start a debugserver instance on the current host using the
     // supplied connection URL.
     //------------------------------------------------------------------
-    lldb_private::Error
+    static lldb_private::Error
     StartDebugserverProcess (const char *connect_url,
-                             const char *unix_socket_name,
-                             lldb_private::ProcessLaunchInfo &launch_info); 
+                             lldb_private::ProcessLaunchInfo &launch_info,
+                             uint16_t &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=196401&r1=196400&r2=196401&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Wed Dec  4 13:19:12 2013
@@ -775,7 +775,6 @@ GDBRemoteCommunicationServer::Handle_qLa
     {
         // Sleep and wait a bit for debugserver to start to listen...
         ConnectionFileDescriptor file_conn;
-        char connect_url[PATH_MAX];
         Error error;
         std::string hostname;
         // TODO: /tmp/ should not be hardcoded. User might want to override /tmp
@@ -796,26 +795,6 @@ GDBRemoteCommunicationServer::Handle_qLa
 
         // 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 (::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);
-            }
-            else
-            {
-                error.SetErrorStringWithFormat("failed to make temporary path for a unix socket: %s", strerror(errno));
-            }
-        }
 
         if (error.Success())
         {
@@ -832,9 +811,9 @@ GDBRemoteCommunicationServer::Handle_qLa
 
             debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
             
-            error = StartDebugserverProcess (host_and_port_cstr,
-                                             unix_socket_name,
-                                             debugserver_launch_info);
+            error = GDBRemoteCommunication::StartDebugserverProcess (host_and_port_cstr,
+                                                                     debugserver_launch_info,
+                                                                     port);
 
             lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
 
@@ -856,32 +835,10 @@ GDBRemoteCommunicationServer::Handle_qLa
             {
                 bool success = false;
 
-                if (IS_VALID_LLDB_HOST_THREAD(accept_thread))
-                {
-                    thread_result_t accept_thread_result = NULL;
-                    if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error))
-                    {
-                        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 + m_port_offset);
-                            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 + m_port_offset);
-                    assert (response_len < sizeof(response));
-                    //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID();
-                    success = SendPacketNoLock (response, response_len) > 0;
-
-                }
-                Host::Unlink (unix_socket_name);
+                char response[256];
+                const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
+                assert (response_len < sizeof(response));
+                success = SendPacketNoLock (response, response_len) > 0;
 
                 if (!success)
                 {
@@ -890,10 +847,6 @@ GDBRemoteCommunicationServer::Handle_qLa
                 }
                 return success;
             }
-            else if (accept_thread)
-            {
-                Host::Unlink (unix_socket_name);
-            }
         }
     }
     return SendErrorResponse (9);

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=196401&r1=196400&r2=196401&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Wed Dec  4 13:19:12 2013
@@ -167,34 +167,6 @@ 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()
 {
@@ -728,23 +700,10 @@ ProcessGDBRemote::DoLaunch (Module *exe_
     ObjectFile * object_file = exe_module->GetObjectFile();
     if (object_file)
     {
-        char host_port[128];
-        snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
-        char connect_url[128];
-        snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
-
         // Make sure we aren't already connected?
         if (!m_gdb_comm.IsConnected())
         {
-            error = StartDebugserverProcess (host_port, launch_info);
-            if (error.Fail())
-            {
-                if (log)
-                    log->Printf("failed to start debugserver process: %s", error.AsCString());
-                return error;
-            }
-
-            error = ConnectToDebugserver (connect_url);
+            error = LaunchAndConnectToDebugserver (launch_info);
         }
         
         if (error.Success())
@@ -1040,12 +999,7 @@ ProcessGDBRemote::DoAttachToProcessWithI
         // Make sure we aren't already connected?
         if (!m_gdb_comm.IsConnected())
         {
-            char host_port[128];
-            snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
-            char connect_url[128];
-            snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
-
-            error = StartDebugserverProcess (host_port, attach_info);
+            error = LaunchAndConnectToDebugserver (attach_info);
             
             if (error.Fail())
             {
@@ -1055,10 +1009,6 @@ ProcessGDBRemote::DoAttachToProcessWithI
 
                 SetExitStatus (-1, error_string);
             }
-            else
-            {
-                error = ConnectToDebugserver (connect_url);
-            }
         }
     
         if (error.Success())
@@ -1105,12 +1055,8 @@ ProcessGDBRemote::DoAttachToProcessWithN
         // Make sure we aren't already connected?
         if (!m_gdb_comm.IsConnected())
         {
-            char host_port[128];
-            snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
-            char connect_url[128];
-            snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
+            error = LaunchAndConnectToDebugserver (attach_info);
 
-            error = StartDebugserverProcess (host_port, attach_info);
             if (error.Fail())
             {
                 const char *error_string = error.AsCString();
@@ -1119,10 +1065,6 @@ ProcessGDBRemote::DoAttachToProcessWithN
 
                 SetExitStatus (-1, error_string);
             }
-            else
-            {
-                error = ConnectToDebugserver (connect_url);
-            }
         }
 
         if (error.Success())
@@ -2546,157 +2488,45 @@ ProcessGDBRemote::DoSignal (int signo)
 }
 
 Error
-ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url)
-{
-    ProcessLaunchInfo launch_info;
-    return StartDebugserverProcess(debugserver_url, launch_info);
-}
-
-Error
-ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url, const ProcessInfo &process_info)    // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
+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
         static FileSpec g_debugserver_file_spec;
 
         ProcessLaunchInfo debugserver_launch_info;
-        char debugserver_path[PATH_MAX];
-        FileSpec &debugserver_file_spec = debugserver_launch_info.GetExecutableFile();
+        debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
+        debugserver_launch_info.SetUserID(process_info.GetUserID());
+
+        error = GDBRemoteCommunication::StartDebugserverProcess ("localhost:0",
+                                                                 debugserver_launch_info,
+                                                                 port);
 
-        // Always check to see if we have an environment override for the path
-        // to the debugserver to use and use it if we do.
-        const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
-        if (env_debugserver_path)
-            debugserver_file_spec.SetFile (env_debugserver_path, false);
+        if (error.Success ())
+            m_debugserver_pid = debugserver_launch_info.GetProcessID();
         else
-            debugserver_file_spec = g_debugserver_file_spec;
-        bool debugserver_exists = debugserver_file_spec.Exists();
-        if (!debugserver_exists)
-        {
-            // The debugserver binary is in the LLDB.framework/Resources
-            // directory. 
-            if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
-            {
-                debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
-                debugserver_exists = debugserver_file_spec.Exists();
-                if (debugserver_exists)
-                {
-                    g_debugserver_file_spec = debugserver_file_spec;
-                }
-                else
-                {
-                    g_debugserver_file_spec.Clear();
-                    debugserver_file_spec.Clear();
-                }
-            }
-        }
+            m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
 
-        if (debugserver_exists)
+        if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
+            StartAsyncThread ();
+        
+        if (error.Fail())
         {
-            debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
-
-            m_stdio_communication.Clear();
-
             Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
 
-            Args &debugserver_args = debugserver_launch_info.GetArguments();
-            char arg_cstr[PATH_MAX];
-
-            // Start args with "debugserver /file/path -r --"
-            debugserver_args.AppendArgument(debugserver_path);
-            debugserver_args.AppendArgument(debugserver_url);
-            // use native registers, not the GDB registers
-            debugserver_args.AppendArgument("--native-regs");   
-            // make debugserver run in its own session so signals generated by 
-            // special terminal key sequences (^C) don't affect debugserver
-            debugserver_args.AppendArgument("--setsid");
-
-            const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
-            if (env_debugserver_log_file)
-            {
-                ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
-                debugserver_args.AppendArgument(arg_cstr);
-            }
-
-            const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
-            if (env_debugserver_log_flags)
-            {
-                ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
-                debugserver_args.AppendArgument(arg_cstr);
-            }
-//            debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
-//            debugserver_args.AppendArgument("--log-flags=0x802e0e");
-
-            // We currently send down all arguments, attach pids, or attach 
-            // process names in dedicated GDB server packets, so we don't need
-            // to pass them as arguments. This is currently because of all the
-            // things we need to setup prior to launching: the environment,
-            // current working dir, file actions, etc.
-#if 0
-            // Now append the program arguments
-            if (inferior_argv)
-            {
-                // Terminate the debugserver args so we can now append the inferior args
-                debugserver_args.AppendArgument("--");
-
-                for (int i = 0; inferior_argv[i] != NULL; ++i)
-                    debugserver_args.AppendArgument (inferior_argv[i]);
-            }
-            else if (attach_pid != LLDB_INVALID_PROCESS_ID)
-            {
-                ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
-                debugserver_args.AppendArgument (arg_cstr);
-            }
-            else if (attach_name && attach_name[0])
-            {
-                if (wait_for_launch)
-                    debugserver_args.AppendArgument ("--waitfor");
-                else
-                    debugserver_args.AppendArgument ("--attach");
-                debugserver_args.AppendArgument (attach_name);
-            }
-#endif
-            
-            ProcessLaunchInfo::FileAction file_action;
-            
-            // Close STDIN, STDOUT and STDERR. We might need to redirect them
-            // to "/dev/null" if we run into any problems.
-            file_action.Close (STDIN_FILENO);
-            debugserver_launch_info.AppendFileAction (file_action);
-            file_action.Close (STDOUT_FILENO);
-            debugserver_launch_info.AppendFileAction (file_action);
-            file_action.Close (STDERR_FILENO);
-            debugserver_launch_info.AppendFileAction (file_action);
-
             if (log)
-            {
-                StreamString strm;
-                debugserver_args.Dump (&strm);
-                log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
-            }
-
-            debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
-            debugserver_launch_info.SetUserID(process_info.GetUserID());
-
-            error = Host::LaunchProcess(debugserver_launch_info);
-
-            if (error.Success ())
-                m_debugserver_pid = debugserver_launch_info.GetProcessID();
-            else
-                m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
-
-            if (error.Fail() || log)
-                error.PutToLog(log, "Host::LaunchProcess (launch_info) => pid=%" PRIu64 ", path='%s'", m_debugserver_pid, debugserver_path);
-        }
-        else
-        {
-            error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME);
+                log->Printf("failed to start debugserver process: %s", error.AsCString());
+            return error;
         }
+        
+        char connect_url[128];
+        snprintf (connect_url, sizeof(connect_url), "connect://localhost:%u", port);
+        
+        error = ConnectToDebugserver (connect_url);
 
-        if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
-            StartAsyncThread ();
     }
     return error;
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=196401&r1=196400&r2=196401&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Wed Dec  4 13:19:12 2013
@@ -284,10 +284,7 @@ protected:
                       lldb_private::ThreadList &new_thread_list);
 
     lldb_private::Error
-    StartDebugserverProcess (const char *debugserver_url);
-    
-    lldb_private::Error
-    StartDebugserverProcess (const char *debugserver_url, const lldb_private::ProcessInfo &process_info);
+    LaunchAndConnectToDebugserver (const lldb_private::ProcessInfo &process_info);
 
     void
     KillDebugserverProcess ();

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=196401&r1=196400&r2=196401&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Wed Dec  4 13:19:12 2013
@@ -915,7 +915,6 @@ RNBRemote::InitializeRegisters (bool for
 
                 if (reg_entry.nub_info.value_regs == NULL)
                 {
-                    DNBLogThreaded("%s -> %u", reg_entry.nub_info.name, reg_data_offset);
                     reg_data_offset += reg_entry.nub_info.size;
                 }
 

Modified: lldb/trunk/tools/debugserver/source/RNBSocket.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBSocket.cpp?rev=196401&r1=196400&r2=196401&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBSocket.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBSocket.cpp Wed Dec  4 13:19:12 2013
@@ -120,20 +120,6 @@ RNBSocket::Listen (const char *listen_ho
         return rnb_err;
     }
 
-    if (callback && port == 0)
-    {
-        // We were asked to listen on port zero which means we
-        // must now read the actual port that was given to us 
-        // as port zero is a special code for "find an open port
-        // for me".
-        socklen_t sa_len = sizeof (sa);
-        if (getsockname(listen_fd, (struct sockaddr *)&sa, &sa_len) == 0)
-        {
-            port = ntohs (sa.sin_port);
-            callback (callback_baton, port);
-        }
-    }
-
     error = ::listen (listen_fd, 5);
     if (error == -1)
         err.SetError(errno, DNBError::POSIX);
@@ -146,6 +132,27 @@ RNBSocket::Listen (const char *listen_ho
         ClosePort (listen_fd, false);
         return rnb_err;
     }
+    
+    if (callback)
+    {
+        // We were asked to listen on port zero which means we
+        // must now read the actual port that was given to us
+        // as port zero is a special code for "find an open port
+        // for me".
+        if (port == 0)
+        {
+            socklen_t sa_len = sizeof (sa);
+            if (getsockname(listen_fd, (struct sockaddr *)&sa, &sa_len) == 0)
+            {
+                port = ntohs (sa.sin_port);
+                callback (callback_baton, port);
+            }
+        }
+        else
+        {
+            callback (callback_baton, port);
+        }
+    }
 
     struct sockaddr_in accept_addr;
     ::memset (&accept_addr, 0, sizeof accept_addr);

Modified: lldb/trunk/tools/debugserver/source/debugserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/debugserver.cpp?rev=196401&r1=196400&r2=196401&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/debugserver.cpp (original)
+++ lldb/trunk/tools/debugserver/source/debugserver.cpp Wed Dec  4 13:19:12 2013
@@ -625,73 +625,32 @@ RNBRunLoopPlatform (RNBRemote *remote)
     return eRNBRunLoopModeExit;
 }
 
-//----------------------------------------------------------------------
-// Convenience function to set up the remote listening port
-// Returns 1 for success 0 for failure.
-//----------------------------------------------------------------------
-
 static void
-PortWasBoundCallback (const void *baton, in_port_t port)
+PortWasBoundCallbackNamedPipe (const void *baton, in_port_t port)
 {
-    //::printf ("PortWasBoundCallback (baton = %p, port = %u)\n", baton, port);
-
-    const char *unix_socket_name = (const char *)baton;
-    
-    if (unix_socket_name && unix_socket_name[0])
+    const char *named_pipe = (const char *)baton;
+    if (named_pipe && named_pipe[0])
     {
-        // We were given a unix socket name to use to communicate the port
-        // that we ended up binding to back to our parent process
-        struct sockaddr_un saddr_un;
-        int s = ::socket (AF_UNIX, SOCK_STREAM, 0);
-        if (s < 0)
-        {
-            perror("error: socket (AF_UNIX, SOCK_STREAM, 0)");
-            exit(1);
-        }
-        
-        saddr_un.sun_family = AF_UNIX;
-        ::strncpy(saddr_un.sun_path, unix_socket_name, sizeof(saddr_un.sun_path) - 1);
-        saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
-        saddr_un.sun_len = SUN_LEN (&saddr_un);
-        
-        if (::connect (s, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) 
-        {
-            perror("error: connect (socket, &saddr_un, saddr_un_len)");
-            exit(1);
-        }
-        
-        //::printf ("connect () sucess!!\n");
-
-        
-        // We were able to connect to the socket, now write our PID so whomever
-        // launched us will know this process's ID
-        RNBLogSTDOUT ("Listening to port %i...\n", port);
-        
-        char pid_str[64];
-        const int pid_str_len = ::snprintf (pid_str, sizeof(pid_str), "%u", port);
-        const int bytes_sent = ::send (s, pid_str, pid_str_len, 0);
-        
-        if (pid_str_len != bytes_sent)
+        int fd = ::open(named_pipe, O_WRONLY);
+        if (fd > -1)
         {
-            perror("error: send (s, pid_str, pid_str_len, 0)");
-            exit (1);
+            char port_str[64];
+            const ssize_t port_str_len = ::snprintf (port_str, sizeof(port_str), "%u", port);
+            // Write the port number as a C string with the NULL terminator
+            ::write (fd, port_str, port_str_len + 1);
+            close (fd);
         }
-
-        //::printf ("send () sucess!!\n");
-
-        // We are done with the socket
-        close (s);
     }
 }
 
 static int
-StartListening (RNBRemote *remote, const char *listen_host, int listen_port, const char *unix_socket_name)
+StartListening (RNBRemote *remote, const char *listen_host, int listen_port, const char *named_pipe_path)
 {
     if (!remote->Comm().IsConnected())
     {
         if (listen_port != 0)
             RNBLogSTDOUT ("Listening to port %i for a connection from %s...\n", listen_port, listen_host ? listen_host : "localhost");
-        if (remote->Comm().Listen(listen_host, listen_port, PortWasBoundCallback, unix_socket_name) != rnb_success)
+        if (remote->Comm().Listen(listen_host, listen_port, PortWasBoundCallbackNamedPipe, named_pipe_path) != rnb_success)
         {
             RNBLogSTDERR ("Failed to get connection from a remote gdb process.\n");
             return 0;
@@ -786,7 +745,7 @@ static struct option g_long_options[] =
     { "disable-aslr",       no_argument,        NULL,               'D' },  // Use _POSIX_SPAWN_DISABLE_ASLR to avoid shared library randomization
     { "working-dir",        required_argument,  NULL,               'W' },  // The working directory that the inferior process should have (only if debugserver launches the process)
     { "platform",           required_argument,  NULL,               'p' },  // Put this executable into a remote platform mode
-    { "unix-socket",        required_argument,  NULL,               'u' },  // If we need to handshake with our parent process, an option will be passed down that specifies a unix socket name to use
+    { "named-pipe",         required_argument,  NULL,               'P' },
     { NULL,                 0,                  NULL,               0   }
 };
 
@@ -838,7 +797,7 @@ main (int argc, char *argv[])
     std::string attach_pid_name;
     std::string arch_name;
     std::string working_dir;                // The new working directory to use for the inferior
-    std::string unix_socket_name;           // If we need to handshake with our parent process, an option will be passed down that specifies a unix socket name to use
+    std::string named_pipe_path;            // If we need to handshake with our parent process, an option will be passed down that specifies a named pipe to use
     useconds_t waitfor_interval = 1000;     // Time in usecs between process lists polls when waiting for a process by name, default 1 msec.
     useconds_t waitfor_duration = 0;        // Time in seconds to wait for a process by name, 0 means wait forever.
     bool no_stdio = false;
@@ -1086,8 +1045,8 @@ main (int argc, char *argv[])
                 start_mode = eRNBRunLoopModePlatformMode;
                 break;
 
-            case 'u':
-                unix_socket_name.assign (optarg);
+            case 'P':
+                named_pipe_path.assign (optarg);
                 break;
         }
     }
@@ -1306,7 +1265,7 @@ main (int argc, char *argv[])
 #endif
                 if (listen_port != INT32_MAX)
                 {
-                    if (!StartListening (remote, listen_host.c_str(), listen_port, unix_socket_name.c_str()))
+                    if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
                         mode = eRNBRunLoopModeExit;
                 }
                 else if (str[0] == '/')
@@ -1419,7 +1378,7 @@ main (int argc, char *argv[])
                 {
                     if (listen_port != INT32_MAX)
                     {
-                        if (!StartListening (remote, listen_host.c_str(), listen_port, unix_socket_name.c_str()))
+                        if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
                             mode = eRNBRunLoopModeExit;
                     }
                     else if (str[0] == '/')
@@ -1444,7 +1403,7 @@ main (int argc, char *argv[])
                     {
                         if (listen_port != INT32_MAX)
                         {
-                            if (!StartListening (remote, listen_host.c_str(), listen_port, unix_socket_name.c_str()))
+                            if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
                                 mode = eRNBRunLoopModeExit;
                         }
                         else if (str[0] == '/')
@@ -1471,7 +1430,7 @@ main (int argc, char *argv[])
             case eRNBRunLoopModePlatformMode:
                 if (listen_port != INT32_MAX)
                 {
-                    if (!StartListening (remote, listen_host.c_str(), listen_port, unix_socket_name.c_str()))
+                    if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
                         mode = eRNBRunLoopModeExit;
                 }
                 else if (str[0] == '/')





More information about the lldb-commits mailing list