https://github.com/slydiman updated
https://github.com/llvm/llvm-project/pull/101283
>From 6b2a41ba3d71270e81e24a42d3b4f5dc2f96b939 Mon Sep 17 00:00:00 2001
From: Dmitry Vasilyev
Date: Wed, 31 Jul 2024 05:41:21 +0400
Subject: [PATCH 1/6] [lldb] Updated lldb-server to spawn the child process and
share socket on Windows
`lldb-server platform --server` works on Windows now w/o multithreading. The
rest functionality remains unchanged.
Depends on #101383.
Fixes #90923, fixes #56346.
This is the part 1 of the replacement of #100670.
In the part 2 I plan to switch `lldb-server gdbserver` to use `--fd` and listen
a common gdb port for all gdbserver connections. Then we can remove gdb port
mapping to fix #97537.
---
lldb/tools/lldb-server/lldb-platform.cpp | 347 ---
1 file changed, 306 insertions(+), 41 deletions(-)
diff --git a/lldb/tools/lldb-server/lldb-platform.cpp
b/lldb/tools/lldb-server/lldb-platform.cpp
index 7148a1d2a30941..e23237ef574c30 100644
--- a/lldb/tools/lldb-server/lldb-platform.cpp
+++ b/lldb/tools/lldb-server/lldb-platform.cpp
@@ -22,6 +22,7 @@
#include
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
@@ -32,8 +33,10 @@
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostGetOpt.h"
#include "lldb/Host/OptionParser.h"
+#include "lldb/Host/Socket.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
@@ -60,6 +63,9 @@ static struct option g_long_options[] = {
{"max-gdbserver-port", required_argument, nullptr, 'M'},
{"socket-file", required_argument, nullptr, 'f'},
{"server", no_argument, &g_server, 1},
+#if defined(_WIN32)
+{"accept", required_argument, nullptr, 'a'},
+#endif
{nullptr, 0, nullptr, 0}};
#if defined(__APPLE__)
@@ -114,6 +120,249 @@ static Status save_socket_id_to_file(const std::string
&socket_id,
return status;
}
+static void client_handle(GDBRemoteCommunicationServerPlatform &platform,
+ const lldb_private::Args &args) {
+ if (!platform.IsConnected())
+return;
+
+ if (args.GetArgumentCount() > 0) {
+lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+std::optional port;
+std::string socket_name;
+Status error = platform.LaunchGDBServer(args,
+"", // hostname
+pid, port, socket_name);
+if (error.Success())
+ platform.SetPendingGdbServer(pid, *port, socket_name);
+else
+ fprintf(stderr, "failed to start gdbserver: %s\n", error.AsCString());
+ }
+
+ bool interrupt = false;
+ bool done = false;
+ Status error;
+ while (!interrupt && !done) {
+if (platform.GetPacketAndSendResponse(std::nullopt, error, interrupt,
+ done) !=
+GDBRemoteCommunication::PacketResult::Success)
+ break;
+ }
+
+ if (error.Fail())
+WithColor::error() << error.AsCString() << '\n';
+}
+
+static GDBRemoteCommunicationServerPlatform::PortMap gdbserver_portmap;
+static std::mutex gdbserver_portmap_mutex;
+
+#if defined(_WIN32)
+static void spawn_process_reaped(lldb::pid_t pid, int signal, int status) {
+ std::lock_guard guard(gdbserver_portmap_mutex);
+ gdbserver_portmap.FreePortForProcess(pid);
+}
+
+static bool spawn_process_parent(const char *progname, Connection *conn,
+ uint16_t gdb_port, uint16_t port_offset,
+ const lldb_private::Args &args,
+ const std::string &log_file,
+ const StringRef log_channels) {
+ Log *log = GetLog(LLDBLog::Platform);
+ Pipe socket_pipe;
+ Status error = socket_pipe.CreateNew(true);
+ if (error.Fail()) {
+LLDB_LOGF(log,
+ "lldb-platform parent: "
+ "cannot create pipe: %s",
+ error.AsCString());
+return false;
+ }
+
+ ProcessLaunchInfo launch_info;
+ FileSpec self_spec(progname, FileSpec::Style::native);
+ launch_info.SetExecutableFile(self_spec, true);
+ Args &self_args = launch_info.GetArguments();
+ self_args.AppendArgument(llvm::StringRef("platform"));
+ self_args.AppendArgument(llvm::StringRef("--accept"));
+ self_args.AppendArgument(llvm::to_string(socket_pipe.GetReadPipe()));
+ if (gdb_port) {
+self_args.AppendArgument(llvm::StringRef("--gdbserver-port"));
+self_args.AppendArgument(llvm::to_string(gdb_port));
+ }
+ if (port_offset > 0) {
+self_args.AppendArgument(llvm::StringRef("--port-offset"));
+self_args.AppendArgument(llvm::to_string(port_offset));
+ }
+ if (!log_file.empty()) {
+self_args.AppendArgument(llvm::StringRef("--log-file"));
+self_args.AppendArgument(log_file);
+ }
+ if (!log_channels.empty()) {
+self_args.AppendA