REPOSITORY
  rL LLVM

http://reviews.llvm.org/D8452

Files:
  lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
  lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
  lldb/trunk/tools/lldb-server/lldb-platform.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
===================================================================
--- lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
+++ lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
@@ -38,6 +38,8 @@
 
     ConnectionFileDescriptor(int fd, bool owns_fd);
 
+    ConnectionFileDescriptor(Socket* socket);
+
     virtual ~ConnectionFileDescriptor();
 
     bool IsConnected() const override;
@@ -104,6 +106,8 @@
     std::string m_uri;
 
   private:
+    void InitializeSocket(Socket* socket);
+
     DISALLOW_COPY_AND_ASSIGN(ConnectionFileDescriptor);
 };
 
Index: lldb/trunk/tools/lldb-server/lldb-platform.cpp
===================================================================
--- lldb/trunk/tools/lldb-server/lldb-platform.cpp
+++ lldb/trunk/tools/lldb-server/lldb-platform.cpp
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/wait.h>
 
 // C++ Includes
 
@@ -30,6 +31,7 @@
 #include "lldb/Host/ConnectionFileDescriptor.h"
 #include "lldb/Host/HostGetOpt.h"
 #include "lldb/Host/OptionParser.h"
+#include "lldb/Host/Socket.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h"
@@ -44,19 +46,19 @@
 
 static int g_debug = 0;
 static int g_verbose = 0;
-static int g_stay_alive = 0;
+static int g_server = 0;
 
 static struct option g_long_options[] =
 {
     { "debug",              no_argument,        &g_debug,           1   },
     { "verbose",            no_argument,        &g_verbose,         1   },
-    { "stay-alive",         no_argument,        &g_stay_alive,      1   },
     { "listen",             required_argument,  NULL,               'L' },
     { "port-offset",        required_argument,  NULL,               'p' },
     { "gdbserver-port",     required_argument,  NULL,               'P' },
     { "min-gdbserver-port", required_argument,  NULL,               'm' },
     { "max-gdbserver-port", required_argument,  NULL,               'M' },
     { "lldb-command",       required_argument,  NULL,               'c' },
+    { "server",             no_argument,        &g_server,          1   },
     { NULL,                 0,                  NULL,               0   }
 };
 
@@ -125,6 +127,7 @@
     std::vector<std::string> lldb_commands;
     bool show_usage = false;
     int option_error = 0;
+    int socket_error = -1;
     
     std::string short_options(OptionParser::GetShortOptionString(g_long_options));
                             
@@ -246,6 +249,17 @@
             puts(output);
     }
 
+    std::unique_ptr<Socket> listening_socket_up;
+    Socket *socket = nullptr;
+    printf ("Listening for a connection from %s...\n", listen_host_port.c_str());
+    const bool children_inherit_listen_socket = false;
+    error = Socket::TcpListen(listen_host_port.c_str(), children_inherit_listen_socket, socket, NULL);
+    if (error.Fail())
+    {
+        printf("error: %s\n", error.AsCString());
+        exit(socket_error);
+    }
+    listening_socket_up.reset(socket);
 
     do {
         GDBRemoteCommunicationServerPlatform platform;
@@ -258,51 +272,64 @@
             platform.SetPortMap(std::move(gdbserver_portmap));
         }
 
-        if (!listen_host_port.empty())
+        const bool children_inherit_accept_socket = true;
+        socket = nullptr;
+        error = listening_socket_up->BlockingAccept(listen_host_port.c_str(), children_inherit_accept_socket, socket);
+        if (error.Fail())
+        {
+            printf ("error: %s\n", error.AsCString());
+            exit(socket_error);
+        }
+        printf ("Connection established.\n");
+        if (g_server)
         {
-            std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
-            if (conn_ap.get())
+            // Collect child zombie processes.
+            while (waitpid(-1, nullptr, WNOHANG) > 0);
+            if (fork())
             {
-                std::string connect_url ("listen://");
-                connect_url.append(listen_host_port.c_str());
-
-                printf ("Listening for a connection from %s...\n", listen_host_port.c_str());
-                if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
-                {
-                    printf ("Connection established.\n");
-                    platform.SetConnection (conn_ap.release());
-                }
-                else
-                {
-                    printf ("error: %s\n", error.AsCString());
-                }
+                // Parent will continue to listen for new connections.
+                continue;
+            }
+            else
+            {
+                // Child process will handle the connection and exit.
+                g_server = 0;
+                // Listening socket is owned by parent process.
+                listening_socket_up.release();
             }
+        }
+        else
+        {
+            // If not running as a server, this process will not accept
+            // connections while a connection is active.
+            listening_socket_up.reset();
+        }
+        platform.SetConnection (new ConnectionFileDescriptor(socket));
 
-            if (platform.IsConnected())
+        if (platform.IsConnected())
+        {
+            // After we connected, we need to get an initial ack from...
+            if (platform.HandshakeWithClient(&error))
             {
-                // After we connected, we need to get an initial ack from...
-                if (platform.HandshakeWithClient(&error))
+                bool interrupt = false;
+                bool done = false;
+                while (!interrupt && !done)
                 {
-                    bool interrupt = false;
-                    bool done = false;
-                    while (!interrupt && !done)
-                    {
-                        if (platform.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success)
-                            break;
-                    }
-                    
-                    if (error.Fail())
-                    {
-                        fprintf(stderr, "error: %s\n", error.AsCString());
-                    }
+                    if (platform.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success)
+                        break;
                 }
-                else
+
+                if (error.Fail())
                 {
-                    fprintf(stderr, "error: handshake with client failed\n");
+                    fprintf(stderr, "error: %s\n", error.AsCString());
                 }
             }
+            else
+            {
+                fprintf(stderr, "error: handshake with client failed\n");
+            }
         }
-    } while (g_stay_alive);
+    } while (g_server);
 
     fprintf(stderr, "lldb-server exiting...\n");
 
Index: lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
===================================================================
--- lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -81,6 +81,17 @@
     OpenCommandPipe();
 }
 
+ConnectionFileDescriptor::ConnectionFileDescriptor(Socket* socket)
+    : Connection()
+    , m_pipe()
+    , m_mutex(Mutex::eMutexTypeRecursive)
+    , m_shutting_down(false)
+    , m_waiting_for_accept(false)
+    , m_child_processes_inherit(false)
+{
+    InitializeSocket(socket);
+}
+
 ConnectionFileDescriptor::~ConnectionFileDescriptor()
 {
     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
@@ -758,15 +769,7 @@
     if (error.Fail())
         return eConnectionStatusError;
 
-    m_write_sp.reset(socket);
-    m_read_sp = m_write_sp;
-    if (error.Fail())
-    {
-        return eConnectionStatusError;
-    }
-    StreamString strm;
-    strm.Printf("connect://%s:%u",socket->GetRemoteIPAddress().c_str(), socket->GetRemotePortNumber());
-    m_uri.swap(strm.GetString());
+    InitializeSocket(socket);
     return eConnectionStatusSuccess;
 }
 
@@ -831,3 +834,13 @@
 {
     m_child_processes_inherit = child_processes_inherit;
 }
+
+void
+ConnectionFileDescriptor::InitializeSocket(Socket* socket)
+{
+    m_write_sp.reset(socket);
+    m_read_sp = m_write_sp;
+    StreamString strm;
+    strm.Printf("connect://%s:%u",socket->GetRemoteIPAddress().c_str(), socket->GetRemotePortNumber());
+    m_uri.swap(strm.GetString());
+}
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to