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