[Lldb-commits] [lldb] [lldb] Updated lldb-server to spawn the child process and share socket on Windows (PR #101283)
Dmitry Vasilyev via lldb-commits
lldb-commits at lists.llvm.org
Wed Jul 31 06:13:06 PDT 2024
================
@@ -114,6 +120,218 @@ static Status save_socket_id_to_file(const std::string &socket_id,
return status;
}
+static GDBRemoteCommunicationServerPlatform::PortMap gdbserver_portmap;
+static std::mutex gdbserver_portmap_mutex;
+
+#if defined(_WIN32)
+static void SpawnProcessReaped(lldb::pid_t pid, int signal, int status) {
+ std::lock_guard<std::mutex> guard(gdbserver_portmap_mutex);
+ gdbserver_portmap.FreePortForProcess(pid);
+}
+
+static bool SpawnProcessParent(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.AppendArgument(llvm::StringRef("--log-channels"));
+ self_args.AppendArgument(log_channels);
+ }
+ if (args.GetArgumentCount() > 0) {
+ self_args.AppendArgument("--");
+ self_args.AppendArguments(args);
+ }
+
+ launch_info.SetLaunchInSeparateProcessGroup(false);
+ launch_info.SetMonitorProcessCallback(&SpawnProcessReaped);
+
+ // Copy the current environment.
+ // WSASocket(FROM_PROTOCOL_INFO) will fail in the child process
+ // with the error WSAEPROVIDERFAILEDINIT if the SystemRoot is missing
+ // in the environment.
+ launch_info.GetEnvironment() = Host::GetEnvironment();
+
+ launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
+
+ launch_info.AppendCloseFileAction(socket_pipe.GetWriteFileDescriptor());
+
+ // Close STDIN, STDOUT and STDERR.
+ launch_info.AppendCloseFileAction(STDIN_FILENO);
+ launch_info.AppendCloseFileAction(STDOUT_FILENO);
+ launch_info.AppendCloseFileAction(STDERR_FILENO);
+
+ // Redirect STDIN, STDOUT and STDERR to "/dev/null".
+ launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false);
+ launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true);
+ launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true);
+
+ std::string cmd;
+ self_args.GetCommandString(cmd);
+
+ error = Host::LaunchProcess(launch_info);
+ if (error.Fail()) {
+ LLDB_LOGF(log,
+ "lldb-platform parent: "
+ "cannot launch child process for connection: %s",
+ error.AsCString());
+ return false;
+ }
+
+ lldb::pid_t childPid = launch_info.GetProcessID();
+ if (childPid == LLDB_INVALID_PROCESS_ID) {
+ LLDB_LOGF(log, "lldb-platform parent: "
+ "cannot launch child process for connection: invalid pid");
+ return false;
+ }
+ LLDB_LOGF(log,
+ "lldb-platform parent: "
+ "launched '%s', pid=0x%x",
+ cmd.c_str(), childPid);
+
+ {
+ std::lock_guard<std::mutex> guard(gdbserver_portmap_mutex);
+ gdbserver_portmap.AssociatePortWithProcess(gdb_port, childPid);
+ }
+
+ if (socket_pipe.CanRead())
+ socket_pipe.CloseReadFileDescriptor();
+ if (!socket_pipe.CanWrite()) {
+ LLDB_LOGF(log, "lldb-platform parent: "
+ "cannot write to socket_pipe");
+ Host::Kill(childPid, SIGTERM);
+ return false;
+ }
+
+ const TCPSocket &socket =
+ static_cast<const TCPSocket &>(*conn->GetReadObject());
+ NativeSocket nativeSocket = socket.GetNativeSocket();
+
+ WSAPROTOCOL_INFO protocol_info;
+ if (::WSADuplicateSocket(nativeSocket, childPid, &protocol_info) ==
+ SOCKET_ERROR) {
+ LLDB_LOGF(log,
+ "lldb-platform parent: "
+ "WSADuplicateSocket() failed, error: %d",
+ ::WSAGetLastError());
+ Host::Kill(childPid, SIGTERM);
+ return false;
+ }
+
+ size_t num_bytes;
+ error = socket_pipe.WriteWithTimeout(&protocol_info, sizeof(protocol_info),
+ std::chrono::seconds(2), num_bytes);
+ if (error.Fail()) {
+ LLDB_LOGF(log,
+ "lldb-platform parent: "
+ "socket_pipe.WriteWithTimeout(WSAPROTOCOL_INFO) failed: %s",
+ error.AsCString());
+ Host::Kill(childPid, SIGTERM);
+ return false;
+ }
+ if (num_bytes != sizeof(protocol_info)) {
+ LLDB_LOGF(log,
+ "lldb-platform parent: "
+ "socket_pipe.WriteWithTimeout(WSAPROTOCOL_INFO) failed: %d bytes",
+ num_bytes);
+ Host::Kill(childPid, SIGTERM);
+ return false;
+ }
+
+ socket_pipe.Close();
+
+ return true;
+}
+
+static bool SpawnProcessChild(pipe_t accept_fd,
+ const std::string &listen_host_port,
+ uint16_t port_offset,
+ const lldb_private::Args &args) {
+ if (accept_fd == INVALID_HANDLE_VALUE)
+ return false;
+
+ Log *log = GetLog(LLDBLog::Platform);
+ if (!listen_host_port.empty()) {
+ LLDB_LOGF(log, "lldb-platform child: "
+ "ambiguous parameters --listen and --accept");
+ exit(SOCKET_ERROR);
+ }
+
+ Pipe socket_pipe(accept_fd, LLDB_INVALID_PIPE);
+
+ WSAPROTOCOL_INFO protocol_info;
+ size_t num_bytes;
+ Status error =
+ socket_pipe.ReadWithTimeout(&protocol_info, sizeof(protocol_info),
+ std::chrono::seconds(2), num_bytes);
+ if (error.Fail()) {
+ LLDB_LOGF(log,
+ "lldb-platform child: "
+ "socket_pipe(0x%x).ReadWithTimeout(WSAPROTOCOL_INFO) failed: %s",
+ accept_fd, error.AsCString());
+ exit(SOCKET_ERROR);
+ }
+ if (num_bytes != sizeof(protocol_info)) {
+ LLDB_LOGF(log,
+ "lldb-platform child: "
+ "socket_pipe(0x%x).ReadWithTimeout(WSAPROTOCOL_INFO) failed: "
----------------
slydiman wrote:
Thanks. Updated.
https://github.com/llvm/llvm-project/pull/101283
More information about the lldb-commits
mailing list