summaryrefslogtreecommitdiffstats
path: root/lldb/tools/lldb-server/lldb-gdbserver.cpp
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2015-07-13 10:44:55 +0000
committerPavel Labath <labath@google.com>2015-07-13 10:44:55 +0000
commit77dc9569c6304c4b2a0a012ae327010ecd3e5067 (patch)
tree8e09354c59088599fc6d938e0f35d5b482043b0d /lldb/tools/lldb-server/lldb-gdbserver.cpp
parentc9627aeae6a496443b389086aef58844ff4823ba (diff)
downloadbcm5719-llvm-77dc9569c6304c4b2a0a012ae327010ecd3e5067.tar.gz
bcm5719-llvm-77dc9569c6304c4b2a0a012ae327010ecd3e5067.zip
Introduce a MainLoop class and switch llgs to use it
Summary: This is the first part of our effort to make llgs single threaded. Currently, llgs consists of about three threads and the synchronisation between them is a major source of latency when debugging linux and android applications. In order to be able to go single threaded, we must have the ability to listen for events from multiple sources (primarily, client commands coming over the network and debug events from the inferior) and perform necessary actions. For this reason I introduce the concept of a MainLoop. A main loop has the ability to register callback's which will be invoked upon receipt of certain events. MainLoopPosix has the ability to listen for file descriptors and signals. For the moment, I have merely made the GDBRemoteCommunicationServerLLGS class use MainLoop instead of waiting on the network socket directly, but the other threads still remain. In the followup patches I indend to migrate NativeProcessLinux to this class and remove the remaining threads. Reviewers: ovyalov, clayborg, amccarth, zturner, emaste Subscribers: tberghammer, lldb-commits Differential Revision: http://reviews.llvm.org/D11066 llvm-svn: 242018
Diffstat (limited to 'lldb/tools/lldb-server/lldb-gdbserver.cpp')
-rw-r--r--lldb/tools/lldb-server/lldb-gdbserver.cpp98
1 files changed, 37 insertions, 61 deletions
diff --git a/lldb/tools/lldb-server/lldb-gdbserver.cpp b/lldb/tools/lldb-server/lldb-gdbserver.cpp
index a286e3df0de..30bb2d68677 100644
--- a/lldb/tools/lldb-server/lldb-gdbserver.cpp
+++ b/lldb/tools/lldb-server/lldb-gdbserver.cpp
@@ -109,16 +109,21 @@ signal_handler(int signo)
case SIGPIPE:
g_sigpipe_received = 1;
break;
- case SIGHUP:
- ++g_sighup_received_count;
-
- // For now, swallow SIGHUP.
- if (log)
- log->Printf ("lldb-server:%s swallowing SIGHUP (receive count=%d)", __FUNCTION__, g_sighup_received_count);
- signal (SIGHUP, signal_handler);
- break;
}
}
+
+static void
+sighup_handler(MainLoopBase &mainloop)
+{
+ ++g_sighup_received_count;
+
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf ("lldb-server:%s swallowing SIGHUP (receive count=%d)", __FUNCTION__, g_sighup_received_count);
+
+ if (g_sighup_received_count >= 2)
+ mainloop.RequestTermination();
+}
#endif // #ifndef _WIN32
static void
@@ -338,7 +343,7 @@ writePortToPipe(int unnamed_pipe_fd, const uint16_t port)
}
void
-ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server,
+ConnectToRemote(MainLoop &mainloop, GDBRemoteCommunicationServerLLGS &gdb_server,
bool reverse_connect, const char *const host_and_port,
const char *const progname, const char *const subcommand,
const char *const named_pipe_path, int unnamed_pipe_fd)
@@ -372,6 +377,8 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server,
exit (1);
}
+ std::unique_ptr<ConnectionFileDescriptor> connection_up;
+
if (reverse_connect)
{
// llgs will connect to the gdb-remote client.
@@ -388,8 +395,7 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server,
snprintf(connection_url, sizeof(connection_url), "connect://%s", final_host_and_port.c_str ());
// Create the connection.
- std::unique_ptr<ConnectionFileDescriptor> connection_up (new ConnectionFileDescriptor ());
- connection_up.reset (new ConnectionFileDescriptor ());
+ connection_up.reset(new ConnectionFileDescriptor);
auto connection_result = connection_up->Connect (connection_url, &error);
if (connection_result != eConnectionStatusSuccess)
{
@@ -401,10 +407,6 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server,
fprintf (stderr, "error: failed to connect to client at '%s': %s", connection_url, error.AsCString ());
exit (-1);
}
-
- // We're connected.
- printf ("Connection established.\n");
- gdb_server.SetConnection (connection_up.release());
}
else
{
@@ -461,10 +463,7 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server,
// Ensure we connected.
if (s_listen_connection_up)
- {
- printf ("Connection established '%s'\n", s_listen_connection_up->GetURI().c_str());
- gdb_server.SetConnection (s_listen_connection_up.release());
- }
+ connection_up = std::move(s_listen_connection_up);
else
{
fprintf (stderr, "failed to connect to '%s': %s\n", final_host_and_port.c_str (), error.AsCString ());
@@ -472,46 +471,13 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server,
exit (1);
}
}
- }
-
- if (gdb_server.IsConnected())
- {
- // After we connected, we need to get an initial ack from...
- if (gdb_server.HandshakeWithClient(&error))
+ error = gdb_server.InitializeConnection (std::move(connection_up));
+ if (error.Fail())
{
- // We'll use a half a second timeout interval so that an exit conditions can
- // be checked that often.
- const uint32_t TIMEOUT_USEC = 500000;
-
- bool interrupt = false;
- bool done = false;
- while (!interrupt && !done && (g_sighup_received_count < 2))
- {
- const GDBRemoteCommunication::PacketResult result = gdb_server.GetPacketAndSendResponse (TIMEOUT_USEC, error, interrupt, done);
- if ((result != GDBRemoteCommunication::PacketResult::Success) &&
- (result != GDBRemoteCommunication::PacketResult::ErrorReplyTimeout))
- {
- // We're bailing out - we only support successful handling and timeouts.
- fprintf(stderr, "leaving packet loop due to PacketResult %d\n", result);
- break;
- }
- }
-
- if (error.Fail())
- {
- fprintf(stderr, "error: %s\n", error.AsCString());
- }
- }
- else
- {
- fprintf(stderr, "error: handshake with client failed\n");
+ fprintf(stderr, "Failed to initialize connection: %s\n", error.AsCString());
+ exit(-1);
}
- }
- else
- {
- fprintf (stderr, "no connection information provided, unable to run\n");
- display_usage (progname, subcommand);
- exit (1);
+ printf ("Connection established.\n");
}
}
@@ -521,10 +487,12 @@ ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server,
int
main_gdbserver (int argc, char *argv[])
{
+ Error error;
+ MainLoop mainloop;
#ifndef _WIN32
// Setup signal handlers first thing.
signal (SIGPIPE, signal_handler);
- signal (SIGHUP, signal_handler);
+ MainLoop::SignalHandleUP sighup_handle = mainloop.RegisterSignal(SIGHUP, sighup_handler, error);
#endif
#ifdef __linux__
// Block delivery of SIGCHLD on linux. NativeProcessLinux will read it using signalfd.
@@ -539,7 +507,6 @@ main_gdbserver (int argc, char *argv[])
argc--;
argv++;
int long_option_index = 0;
- Error error;
int ch;
std::string platform_name;
std::string attach_target;
@@ -670,7 +637,7 @@ main_gdbserver (int argc, char *argv[])
// Setup the platform that GDBRemoteCommunicationServerLLGS will use.
lldb::PlatformSP platform_sp = setup_platform (platform_name);
- GDBRemoteCommunicationServerLLGS gdb_server (platform_sp);
+ GDBRemoteCommunicationServerLLGS gdb_server (platform_sp, mainloop);
const char *const host_and_port = argv[0];
argc -= 1;
@@ -688,10 +655,19 @@ main_gdbserver (int argc, char *argv[])
// Print version info.
printf("%s-%s", LLGS_PROGRAM_NAME, LLGS_VERSION_STR);
- ConnectToRemote(gdb_server, reverse_connect,
+ ConnectToRemote(mainloop, gdb_server, reverse_connect,
host_and_port, progname, subcommand,
named_pipe_path.c_str(), unnamed_pipe_fd);
+
+ if (! gdb_server.IsConnected())
+ {
+ fprintf (stderr, "no connection information provided, unable to run\n");
+ display_usage (progname, subcommand);
+ return 1;
+ }
+
+ mainloop.Run();
fprintf(stderr, "lldb-server exiting...\n");
return 0;
OpenPOWER on IntegriCloud