summaryrefslogtreecommitdiff
path: root/tools/lldb-server/lldb-gdbserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lldb-server/lldb-gdbserver.cpp')
-rw-r--r--tools/lldb-server/lldb-gdbserver.cpp99
1 files changed, 65 insertions, 34 deletions
diff --git a/tools/lldb-server/lldb-gdbserver.cpp b/tools/lldb-server/lldb-gdbserver.cpp
index f1a9b113c8ee..810cb92e4ffc 100644
--- a/tools/lldb-server/lldb-gdbserver.cpp
+++ b/tools/lldb-server/lldb-gdbserver.cpp
@@ -106,6 +106,7 @@ static struct option g_long_options[] = {
// than llgs listening for a connection from address on port.
{"setsid", no_argument, NULL,
'S'}, // Call setsid() to make llgs run in its own session.
+ {"fd", required_argument, NULL, 'F'},
{NULL, 0, NULL, 0}};
//----------------------------------------------------------------------
@@ -132,13 +133,13 @@ static void display_usage(const char *progname, const char *subcommand) {
"[--log-file log-file-name] "
"[--log-channels log-channel-list] "
"[--setsid] "
+ "[--fd file-descriptor]"
"[--named-pipe named-pipe-path] "
"[--native-regs] "
"[--attach pid] "
"[[HOST]:PORT] "
"[-- PROGRAM ARG1 ARG2 ...]\n",
progname, subcommand);
- exit(0);
}
void handle_attach_to_pid(GDBRemoteCommunicationServerLLGS &gdb_server,
@@ -176,27 +177,28 @@ void handle_attach(GDBRemoteCommunicationServerLLGS &gdb_server,
void handle_launch(GDBRemoteCommunicationServerLLGS &gdb_server, int argc,
const char *const argv[]) {
- Status error;
- error = gdb_server.SetLaunchArguments(argv, argc);
- if (error.Fail()) {
- fprintf(stderr, "error: failed to set launch args for '%s': %s\n", argv[0],
- error.AsCString());
+ ProcessLaunchInfo info;
+ info.GetFlags().Set(eLaunchFlagStopAtEntry | eLaunchFlagDebug |
+ eLaunchFlagDisableASLR);
+ info.SetArguments(const_cast<const char **>(argv), true);
+
+ llvm::SmallString<64> cwd;
+ if (std::error_code ec = llvm::sys::fs::current_path(cwd)) {
+ llvm::errs() << "Error getting current directory: " << ec.message() << "\n";
exit(1);
}
+ info.SetWorkingDirectory(FileSpec(cwd, true));
- unsigned int launch_flags = eLaunchFlagStopAtEntry | eLaunchFlagDebug;
+ StringList env;
+ Host::GetEnvironment(env);
+ info.GetEnvironmentEntries() = Args(env);
- error = gdb_server.SetLaunchFlags(launch_flags);
- if (error.Fail()) {
- fprintf(stderr, "error: failed to set launch flags for '%s': %s\n", argv[0],
- error.AsCString());
- exit(1);
- }
+ gdb_server.SetLaunchInfo(info);
- error = gdb_server.LaunchProcess();
+ Status error = gdb_server.LaunchProcess();
if (error.Fail()) {
- fprintf(stderr, "error: failed to launch '%s': %s\n", argv[0],
- error.AsCString());
+ llvm::errs() << llvm::formatv("error: failed to launch '{0}': {1}\n",
+ argv[0], error);
exit(1);
}
}
@@ -232,10 +234,34 @@ void 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) {
+ const char *const named_pipe_path, int unnamed_pipe_fd,
+ int connection_fd) {
Status error;
- if (host_and_port && host_and_port[0]) {
+ std::unique_ptr<Connection> connection_up;
+ if (connection_fd != -1) {
+ // Build the connection string.
+ char connection_url[512];
+ snprintf(connection_url, sizeof(connection_url), "fd://%d", connection_fd);
+
+ // Create the connection.
+#if !defined LLDB_DISABLE_POSIX && !defined _WIN32
+ ::fcntl(connection_fd, F_SETFD, FD_CLOEXEC);
+#endif
+ connection_up.reset(new ConnectionFileDescriptor);
+ auto connection_result = connection_up->Connect(connection_url, &error);
+ if (connection_result != eConnectionStatusSuccess) {
+ fprintf(stderr, "error: failed to connect to client at '%s' "
+ "(connection status: %d)\n",
+ connection_url, static_cast<int>(connection_result));
+ exit(-1);
+ }
+ if (error.Fail()) {
+ fprintf(stderr, "error: failed to connect to client at '%s': %s\n",
+ connection_url, error.AsCString());
+ exit(-1);
+ }
+ } else if (host_and_port && host_and_port[0]) {
// Parse out host and port.
std::string final_host_and_port;
std::string connection_host;
@@ -255,7 +281,6 @@ void ConnectToRemote(MainLoop &mainloop,
connection_portno = StringConvert::ToUInt32(connection_port.c_str(), 0);
}
- std::unique_ptr<Connection> connection_up;
if (reverse_connect) {
// llgs will connect to the gdb-remote client.
@@ -263,7 +288,7 @@ void ConnectToRemote(MainLoop &mainloop,
// Ensure we have a port number for the connection.
if (connection_portno == 0) {
fprintf(stderr, "error: port number must be specified on when using "
- "reverse connect");
+ "reverse connect\n");
exit(1);
}
@@ -277,12 +302,12 @@ void ConnectToRemote(MainLoop &mainloop,
auto connection_result = connection_up->Connect(connection_url, &error);
if (connection_result != eConnectionStatusSuccess) {
fprintf(stderr, "error: failed to connect to client at '%s' "
- "(connection status: %d)",
+ "(connection status: %d)\n",
connection_url, static_cast<int>(connection_result));
exit(-1);
}
if (error.Fail()) {
- fprintf(stderr, "error: failed to connect to client at '%s': %s",
+ fprintf(stderr, "error: failed to connect to client at '%s': %s\n",
connection_url, error.AsCString());
exit(-1);
}
@@ -290,7 +315,7 @@ void ConnectToRemote(MainLoop &mainloop,
std::unique_ptr<Acceptor> acceptor_up(
Acceptor::Create(final_host_and_port, false, error));
if (error.Fail()) {
- fprintf(stderr, "failed to create acceptor: %s", error.AsCString());
+ fprintf(stderr, "failed to create acceptor: %s\n", error.AsCString());
exit(1);
}
error = acceptor_up->Listen(1);
@@ -304,7 +329,7 @@ void ConnectToRemote(MainLoop &mainloop,
if (named_pipe_path && named_pipe_path[0]) {
error = writeSocketIdToPipe(named_pipe_path, socket_id);
if (error.Fail())
- fprintf(stderr, "failed to write to the named pipe \'%s\': %s",
+ fprintf(stderr, "failed to write to the named pipe \'%s\': %s\n",
named_pipe_path, error.AsCString());
}
// If we have an unnamed pipe to write the socket id back to, do that
@@ -312,7 +337,7 @@ void ConnectToRemote(MainLoop &mainloop,
else if (unnamed_pipe_fd >= 0) {
error = writeSocketIdToPipe(unnamed_pipe_fd, socket_id);
if (error.Fail())
- fprintf(stderr, "failed to write to the unnamed pipe: %s",
+ fprintf(stderr, "failed to write to the unnamed pipe: %s\n",
error.AsCString());
}
} else {
@@ -328,14 +353,14 @@ void ConnectToRemote(MainLoop &mainloop,
}
connection_up.reset(conn);
}
- error = gdb_server.InitializeConnection(std::move(connection_up));
- if (error.Fail()) {
- fprintf(stderr, "Failed to initialize connection: %s\n",
- error.AsCString());
- exit(-1);
- }
- printf("Connection established.\n");
}
+ error = gdb_server.InitializeConnection(std::move(connection_up));
+ if (error.Fail()) {
+ fprintf(stderr, "Failed to initialize connection: %s\n",
+ error.AsCString());
+ exit(-1);
+ }
+ printf("Connection established.\n");
}
//----------------------------------------------------------------------
@@ -364,6 +389,7 @@ int main_gdbserver(int argc, char *argv[]) {
log_channels; // e.g. "lldb process threads:gdb-remote default:linux all"
int unnamed_pipe_fd = -1;
bool reverse_connect = false;
+ int connection_fd = -1;
// ProcessLaunchInfo launch_info;
ProcessAttachInfo attach_info;
@@ -413,6 +439,10 @@ int main_gdbserver(int argc, char *argv[]) {
reverse_connect = true;
break;
+ case 'F':
+ connection_fd = StringConvert::ToUInt32(optarg, -1);
+ break;
+
#ifndef _WIN32
case 'S':
// Put llgs into a new session. Terminals group processes
@@ -472,7 +502,8 @@ int main_gdbserver(int argc, char *argv[]) {
argc -= optind;
argv += optind;
- if (argc == 0) {
+ if (argc == 0 && connection_fd == -1) {
+ fputs("No arguments\n", stderr);
display_usage(progname, subcommand);
exit(255);
}
@@ -501,7 +532,7 @@ int main_gdbserver(int argc, char *argv[]) {
ConnectToRemote(mainloop, gdb_server, reverse_connect, host_and_port,
progname, subcommand, named_pipe_path.c_str(),
- unnamed_pipe_fd);
+ unnamed_pipe_fd, connection_fd);
if (!gdb_server.IsConnected()) {
fprintf(stderr, "no connection information provided, unable to run\n");