<div dir="ltr"><div>Please update the usage description in lldb-platform to reflect this change.<br></div><div><br></div><div>Thanks,</div><div>Tamas</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 25, 2015 at 12:51 PM, Robert Flack <span dir="ltr"><<a href="mailto:flackr@gmail.com" target="_blank">flackr@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: flackr<br>
Date: Wed Mar 25 07:51:31 2015<br>
New Revision: 233185<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=233185&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=233185&view=rev</a><br>
Log:<br>
Allow multiple simultaneous connections to platform.<br>
<br>
Adds the --server argument to lldb-server platform which when specified will allow multiple simultaneous connections by forking off to handle each individual connection. This will allow us to run the remote tests in parallel.<br>
<br>
Test Plan:<br>
Run: lldb-server platform --listen *:1234 --server<br>
Connect from multiple lldb clients simultaneously.<br>
I will also test running the test suite remotely with multiple simultaneous jobs.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D8452" target="_blank">http://reviews.llvm.org/D8452</a><br>
<br>
Modified:<br>
lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h<br>
lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp<br>
lldb/trunk/tools/lldb-server/lldb-platform.cpp<br>
<br>
Modified: lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h?rev=233185&r1=233184&r2=233185&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h?rev=233185&r1=233184&r2=233185&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h (original)<br>
+++ lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h Wed Mar 25 07:51:31 2015<br>
@@ -38,6 +38,8 @@ class ConnectionFileDescriptor : public<br>
<br>
ConnectionFileDescriptor(int fd, bool owns_fd);<br>
<br>
+ ConnectionFileDescriptor(Socket* socket);<br>
+<br>
virtual ~ConnectionFileDescriptor();<br>
<br>
bool IsConnected() const override;<br>
@@ -104,6 +106,8 @@ class ConnectionFileDescriptor : public<br>
std::string m_uri;<br>
<br>
private:<br>
+ void InitializeSocket(Socket* socket);<br>
+<br>
DISALLOW_COPY_AND_ASSIGN(ConnectionFileDescriptor);<br>
};<br>
<br>
<br>
Modified: lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp?rev=233185&r1=233184&r2=233185&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp?rev=233185&r1=233184&r2=233185&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp (original)<br>
+++ lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp Wed Mar 25 07:51:31 2015<br>
@@ -81,6 +81,17 @@ ConnectionFileDescriptor::ConnectionFile<br>
OpenCommandPipe();<br>
}<br>
<br>
+ConnectionFileDescriptor::ConnectionFileDescriptor(Socket* socket)<br>
+ : Connection()<br>
+ , m_pipe()<br>
+ , m_mutex(Mutex::eMutexTypeRecursive)<br>
+ , m_shutting_down(false)<br>
+ , m_waiting_for_accept(false)<br>
+ , m_child_processes_inherit(false)<br>
+{<br>
+ InitializeSocket(socket);<br>
+}<br>
+<br>
ConnectionFileDescriptor::~ConnectionFileDescriptor()<br>
{<br>
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));<br>
@@ -758,15 +769,7 @@ ConnectionFileDescriptor::SocketListenAn<br>
if (error.Fail())<br>
return eConnectionStatusError;<br>
<br>
- m_write_sp.reset(socket);<br>
- m_read_sp = m_write_sp;<br>
- if (error.Fail())<br>
- {<br>
- return eConnectionStatusError;<br>
- }<br>
- StreamString strm;<br>
- strm.Printf("connect://%s:%u",socket->GetRemoteIPAddress().c_str(), socket->GetRemotePortNumber());<br>
- m_uri.swap(strm.GetString());<br>
+ InitializeSocket(socket);<br>
return eConnectionStatusSuccess;<br>
}<br>
<br>
@@ -831,3 +834,13 @@ ConnectionFileDescriptor::SetChildProces<br>
{<br>
m_child_processes_inherit = child_processes_inherit;<br>
}<br>
+<br>
+void<br>
+ConnectionFileDescriptor::InitializeSocket(Socket* socket)<br>
+{<br>
+ m_write_sp.reset(socket);<br>
+ m_read_sp = m_write_sp;<br>
+ StreamString strm;<br>
+ strm.Printf("connect://%s:%u",socket->GetRemoteIPAddress().c_str(), socket->GetRemotePortNumber());<br>
+ m_uri.swap(strm.GetString());<br>
+}<br>
<br>
Modified: lldb/trunk/tools/lldb-server/lldb-platform.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-server/lldb-platform.cpp?rev=233185&r1=233184&r2=233185&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-server/lldb-platform.cpp?rev=233185&r1=233184&r2=233185&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/tools/lldb-server/lldb-platform.cpp (original)<br>
+++ lldb/trunk/tools/lldb-server/lldb-platform.cpp Wed Mar 25 07:51:31 2015<br>
@@ -19,6 +19,7 @@<br>
#include <stdio.h><br>
#include <stdlib.h><br>
#include <string.h><br>
+#include <sys/wait.h><br>
<br>
// C++ Includes<br>
<br>
@@ -30,6 +31,7 @@<br>
#include "lldb/Host/ConnectionFileDescriptor.h"<br>
#include "lldb/Host/HostGetOpt.h"<br>
#include "lldb/Host/OptionParser.h"<br>
+#include "lldb/Host/Socket.h"<br>
#include "lldb/Interpreter/CommandInterpreter.h"<br>
#include "lldb/Interpreter/CommandReturnObject.h"<br>
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h"<br>
@@ -44,19 +46,19 @@ using namespace lldb_private;<br>
<br>
static int g_debug = 0;<br>
static int g_verbose = 0;<br>
-static int g_stay_alive = 0;<br>
+static int g_server = 0;<br>
<br>
static struct option g_long_options[] =<br>
{<br>
{ "debug", no_argument, &g_debug, 1 },<br>
{ "verbose", no_argument, &g_verbose, 1 },<br>
- { "stay-alive", no_argument, &g_stay_alive, 1 },<br>
{ "listen", required_argument, NULL, 'L' },<br>
{ "port-offset", required_argument, NULL, 'p' },<br>
{ "gdbserver-port", required_argument, NULL, 'P' },<br>
{ "min-gdbserver-port", required_argument, NULL, 'm' },<br>
{ "max-gdbserver-port", required_argument, NULL, 'M' },<br>
{ "lldb-command", required_argument, NULL, 'c' },<br>
+ { "server", no_argument, &g_server, 1 },<br>
{ NULL, 0, NULL, 0 }<br>
};<br>
<br>
@@ -125,6 +127,7 @@ main_platform (int argc, char *argv[])<br>
std::vector<std::string> lldb_commands;<br>
bool show_usage = false;<br>
int option_error = 0;<br>
+ int socket_error = -1;<br>
<br>
std::string short_options(OptionParser::GetShortOptionString(g_long_options));<br>
<br>
@@ -246,6 +249,17 @@ main_platform (int argc, char *argv[])<br>
puts(output);<br>
}<br>
<br>
+ std::unique_ptr<Socket> listening_socket_up;<br>
+ Socket *socket = nullptr;<br>
+ printf ("Listening for a connection from %s...\n", listen_host_port.c_str());<br>
+ const bool children_inherit_listen_socket = false;<br>
+ error = Socket::TcpListen(listen_host_port.c_str(), children_inherit_listen_socket, socket, NULL);<br>
+ if (error.Fail())<br>
+ {<br>
+ printf("error: %s\n", error.AsCString());<br>
+ exit(socket_error);<br>
+ }<br>
+ listening_socket_up.reset(socket);<br>
<br>
do {<br>
GDBRemoteCommunicationServerPlatform platform;<br>
@@ -258,51 +272,64 @@ main_platform (int argc, char *argv[])<br>
platform.SetPortMap(std::move(gdbserver_portmap));<br>
}<br>
<br>
- if (!listen_host_port.empty())<br>
+ const bool children_inherit_accept_socket = true;<br>
+ socket = nullptr;<br>
+ error = listening_socket_up->BlockingAccept(listen_host_port.c_str(), children_inherit_accept_socket, socket);<br>
+ if (error.Fail())<br>
+ {<br>
+ printf ("error: %s\n", error.AsCString());<br>
+ exit(socket_error);<br>
+ }<br>
+ printf ("Connection established.\n");<br>
+ if (g_server)<br>
{<br>
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());<br>
- if (conn_ap.get())<br>
+ // Collect child zombie processes.<br>
+ while (waitpid(-1, nullptr, WNOHANG) > 0);<br>
+ if (fork())<br>
{<br>
- std::string connect_url ("listen://");<br>
- connect_url.append(listen_host_port.c_str());<br>
-<br>
- printf ("Listening for a connection from %s...\n", listen_host_port.c_str());<br>
- if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)<br>
- {<br>
- printf ("Connection established.\n");<br>
- platform.SetConnection (conn_ap.release());<br>
- }<br>
- else<br>
- {<br>
- printf ("error: %s\n", error.AsCString());<br>
- }<br>
+ // Parent will continue to listen for new connections.<br>
+ continue;<br>
+ }<br>
+ else<br>
+ {<br>
+ // Child process will handle the connection and exit.<br>
+ g_server = 0;<br>
+ // Listening socket is owned by parent process.<br>
+ listening_socket_up.release();<br>
}<br>
+ }<br>
+ else<br>
+ {<br>
+ // If not running as a server, this process will not accept<br>
+ // connections while a connection is active.<br>
+ listening_socket_up.reset();<br>
+ }<br>
+ platform.SetConnection (new ConnectionFileDescriptor(socket));<br>
<br>
- if (platform.IsConnected())<br>
+ if (platform.IsConnected())<br>
+ {<br>
+ // After we connected, we need to get an initial ack from...<br>
+ if (platform.HandshakeWithClient(&error))<br>
{<br>
- // After we connected, we need to get an initial ack from...<br>
- if (platform.HandshakeWithClient(&error))<br>
+ bool interrupt = false;<br>
+ bool done = false;<br>
+ while (!interrupt && !done)<br>
{<br>
- bool interrupt = false;<br>
- bool done = false;<br>
- while (!interrupt && !done)<br>
- {<br>
- if (platform.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success)<br>
- break;<br>
- }<br>
-<br>
- if (error.Fail())<br>
- {<br>
- fprintf(stderr, "error: %s\n", error.AsCString());<br>
- }<br>
+ if (platform.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success)<br>
+ break;<br>
}<br>
- else<br>
+<br>
+ if (error.Fail())<br>
{<br>
- fprintf(stderr, "error: handshake with client failed\n");<br>
+ fprintf(stderr, "error: %s\n", error.AsCString());<br>
}<br>
}<br>
+ else<br>
+ {<br>
+ fprintf(stderr, "error: handshake with client failed\n");<br>
+ }<br>
}<br>
- } while (g_stay_alive);<br>
+ } while (g_server);<br>
<br>
fprintf(stderr, "lldb-server exiting...\n");<br>
<br>
<br>
<br>
_______________________________________________<br>
lldb-commits mailing list<br>
<a href="mailto:lldb-commits@cs.uiuc.edu">lldb-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits</a><br>
</blockquote></div><br></div>