-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[lldb-dap] Add runInTerminal support for Windows #138160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[lldb-dap] Add runInTerminal support for Windows #138160
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-lldb Author: None (DrSergei) ChangesAdded Patch is 20.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138160.diff 8 Files Affected:
diff --git a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
index 9aab7ca3293db..d5355f3bacd9c 100644
--- a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
+++ b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
@@ -43,7 +43,6 @@ def isTestSupported(self):
except:
return False
- @skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminal(self):
if not self.isTestSupported():
@@ -113,7 +112,6 @@ def test_runInTerminalWithObjectEnv(self):
self.assertIn("FOO", request_envs)
self.assertEqual("BAR", request_envs["FOO"])
- @skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminalInvalidTarget(self):
if not self.isTestSupported():
@@ -132,7 +130,6 @@ def test_runInTerminalInvalidTarget(self):
response["message"],
)
- @skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_missingArgInRunInTerminalLauncher(self):
if not self.isTestSupported():
diff --git a/lldb/tools/lldb-dap/FifoFiles.cpp b/lldb/tools/lldb-dap/FifoFiles.cpp
index 1f1bba80bd3b1..43eb4679b592f 100644
--- a/lldb/tools/lldb-dap/FifoFiles.cpp
+++ b/lldb/tools/lldb-dap/FifoFiles.cpp
@@ -24,26 +24,53 @@ using namespace llvm;
namespace lldb_dap {
-FifoFile::FifoFile(StringRef path) : m_path(path) {}
+#if defined(_WIN32)
+FifoFile::FifoFile(StringRef path, HANDLE handle, bool is_server)
+ : m_path(path), m_is_server(is_server), m_pipe_fd(handle) {}
+#else
+FifoFile::FifoFile(StringRef path, bool is_server)
+ : m_path(path), m_is_server(is_server) {}
+#endif
FifoFile::~FifoFile() {
-#if !defined(_WIN32)
- unlink(m_path.c_str());
+#if defined(_WIN32)
+ if (m_pipe_fd == INVALID_HANDLE_VALUE)
+ return;
+ if (m_is_server)
+ DisconnectNamedPipe(m_pipe_fd);
+ CloseHandle(m_pipe_fd);
+#else
+ if (m_is_server)
+ unlink(m_path.c_str());
#endif
}
-Expected<std::shared_ptr<FifoFile>> CreateFifoFile(StringRef path) {
+Expected<std::shared_ptr<FifoFile>> CreateFifoFile(StringRef path,
+ bool is_server) {
#if defined(_WIN32)
- return createStringError(inconvertibleErrorCode(), "Unimplemented");
+ if (!is_server)
+ return std::make_shared<FifoFile>(path, INVALID_HANDLE_VALUE, is_server);
+ HANDLE handle =
+ CreateNamedPipeA(path.data(), PIPE_ACCESS_DUPLEX,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1,
+ 1024 * 16, 1024 * 16, 0, NULL);
+ if (handle == INVALID_HANDLE_VALUE)
+ return createStringError(
+ std::error_code(GetLastError(), std::generic_category()),
+ "Couldn't create fifo file: %s", path.data());
+ return std::make_shared<FifoFile>(path, handle, is_server);
#else
+ if (!is_server)
+ return std::make_shared<FifoFile>(path, is_server);
if (int err = mkfifo(path.data(), 0600))
return createStringError(std::error_code(err, std::generic_category()),
"Couldn't create fifo file: %s", path.data());
- return std::make_shared<FifoFile>(path);
+ return std::make_shared<FifoFile>(path, is_server);
#endif
}
-FifoFileIO::FifoFileIO(StringRef fifo_file, StringRef other_endpoint_name)
+FifoFileIO::FifoFileIO(std::shared_ptr<FifoFile> fifo_file,
+ StringRef other_endpoint_name)
: m_fifo_file(fifo_file), m_other_endpoint_name(other_endpoint_name) {}
Expected<json::Value> FifoFileIO::ReadJSON(std::chrono::milliseconds timeout) {
@@ -52,11 +79,27 @@ Expected<json::Value> FifoFileIO::ReadJSON(std::chrono::milliseconds timeout) {
std::optional<std::string> line;
std::future<void> *future =
new std::future<void>(std::async(std::launch::async, [&]() {
- std::ifstream reader(m_fifo_file, std::ifstream::in);
+#if defined(_WIN32)
+ std::string buffer;
+ buffer.reserve(4096);
+ char ch;
+ DWORD bytes_read = 0;
+ while (ReadFile(m_fifo_file->m_pipe_fd, &ch, 1, &bytes_read, NULL) &&
+ (bytes_read == 1)) {
+ buffer.push_back(ch);
+ if (ch == '\n') {
+ break;
+ }
+ }
+ if (!buffer.empty())
+ line = std::move(buffer);
+#else
+ std::ifstream reader(m_fifo_file->m_path, std::ifstream::in);
std::string buffer;
std::getline(reader, buffer);
if (!buffer.empty())
line = buffer;
+#endif
}));
if (future->wait_for(timeout) == std::future_status::timeout || !line)
// Indeed this is a leak, but it's intentional. "future" obj destructor
@@ -78,9 +121,19 @@ Error FifoFileIO::SendJSON(const json::Value &json,
bool done = false;
std::future<void> *future =
new std::future<void>(std::async(std::launch::async, [&]() {
+#if defined(_WIN32)
+ std::string buffer = JSONToString(json);
+ buffer.append("\n");
+ DWORD bytes_write = 0;
+ WriteFile(m_fifo_file->m_pipe_fd, buffer.c_str(), buffer.size(),
+ &bytes_write, NULL);
+ done = bytes_write == buffer.size();
+#else
+ std::ofstream writer(m_fifo_file->m_path, std::ofstream::out);
std::ofstream writer(m_fifo_file, std::ofstream::out);
writer << JSONToString(json) << std::endl;
done = true;
+#endif
}));
if (future->wait_for(timeout) == std::future_status::timeout || !done) {
// Indeed this is a leak, but it's intentional. "future" obj destructor will
@@ -98,4 +151,20 @@ Error FifoFileIO::SendJSON(const json::Value &json,
return Error::success();
}
+#if defined(_WIN32)
+bool FifoFileIO::Connect() {
+ if (m_fifo_file->m_is_server) {
+ return ConnectNamedPipe(m_fifo_file->m_pipe_fd, NULL);
+ }
+ if (!WaitNamedPipeA(m_fifo_file->m_path.c_str(), NMPWAIT_WAIT_FOREVER))
+ return false;
+ m_fifo_file->m_pipe_fd =
+ CreateFileA(m_fifo_file->m_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0,
+ NULL, OPEN_EXISTING, 0, NULL);
+ if (m_fifo_file->m_pipe_fd == INVALID_HANDLE_VALUE)
+ return false;
+ return true;
+}
+#endif
+
} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/FifoFiles.h b/lldb/tools/lldb-dap/FifoFiles.h
index 633ebeb2aedd4..335c7561040dd 100644
--- a/lldb/tools/lldb-dap/FifoFiles.h
+++ b/lldb/tools/lldb-dap/FifoFiles.h
@@ -12,19 +12,35 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/JSON.h"
+#if defined(_WIN32)
+#include "lldb/Host/windows/windows.h"
+#endif
+
#include <chrono>
namespace lldb_dap {
+class FifoFileIO;
+
/// Struct that controls the life of a fifo file in the filesystem.
///
/// The file is destroyed when the destructor is invoked.
struct FifoFile {
- FifoFile(llvm::StringRef path);
+#if defined(_WIN32)
+ FifoFile(llvm::StringRef path, HANDLE handle, bool is_server);
+#else
+ FifoFile(llvm::StringRef path, bool is_server);
+#endif
~FifoFile();
std::string m_path;
+ bool m_is_server;
+#if defined(_WIN32)
+ HANDLE m_pipe_fd = INVALID_HANDLE_VALUE;
+#endif
+
+ friend FifoFileIO;
};
/// Create a fifo file in the filesystem.
@@ -32,20 +48,26 @@ struct FifoFile {
/// \param[in] path
/// The path for the fifo file.
///
+/// \param[in] is_server
+/// If \a is_server is true, then created instance of FifoFile will own
+/// created file.
+///
/// \return
/// A \a std::shared_ptr<FifoFile> if the file could be created, or an
/// \a llvm::Error in case of failures.
-llvm::Expected<std::shared_ptr<FifoFile>> CreateFifoFile(llvm::StringRef path);
+llvm::Expected<std::shared_ptr<FifoFile>> CreateFifoFile(llvm::StringRef path,
+ bool is_server);
class FifoFileIO {
public:
/// \param[in] fifo_file
- /// The path to an input fifo file that exists in the file system.
+ /// The std::shared_ptr<FifoFile> to an existing fifo file.
///
/// \param[in] other_endpoint_name
/// A human readable name for the other endpoint that will communicate
/// using this file. This is used for error messages.
- FifoFileIO(llvm::StringRef fifo_file, llvm::StringRef other_endpoint_name);
+ FifoFileIO(std::shared_ptr<FifoFile> fifo_file,
+ llvm::StringRef other_endpoint_name);
/// Read the next JSON object from the underlying input fifo file.
///
@@ -75,8 +97,12 @@ class FifoFileIO {
const llvm::json::Value &json,
std::chrono::milliseconds timeout = std::chrono::milliseconds(20000));
+#if defined(_WIN32)
+ bool Connect();
+#endif
+
private:
- std::string m_fifo_file;
+ std::shared_ptr<FifoFile> m_fifo_file;
std::string m_other_endpoint_name;
};
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index 7a75cd93abc19..e68597194c296 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -119,9 +119,9 @@ RunInTerminal(DAP &dap, const protocol::LaunchRequestArguments &arguments) {
CreateRunInTerminalCommFile();
if (!comm_file_or_err)
return comm_file_or_err.takeError();
- FifoFile &comm_file = *comm_file_or_err.get();
+ std::shared_ptr<FifoFile> comm_file = *comm_file_or_err;
- RunInTerminalDebugAdapterCommChannel comm_channel(comm_file.m_path);
+ RunInTerminalDebugAdapterCommChannel comm_channel(comm_file);
lldb::pid_t debugger_pid = LLDB_INVALID_PROCESS_ID;
#if !defined(_WIN32)
@@ -130,10 +130,16 @@ RunInTerminal(DAP &dap, const protocol::LaunchRequestArguments &arguments) {
llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
*arguments.configuration.program, arguments.args, arguments.env,
- arguments.cwd.value_or(""), comm_file.m_path, debugger_pid);
+ arguments.cwd.value_or(""), comm_file->m_path, debugger_pid);
dap.SendReverseRequest<LogFailureResponseHandler>("runInTerminal",
std::move(reverse_request));
+#if defined(_WIN32)
+ if (!comm_channel.Connect())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Failed to connect to the named pipe.");
+#endif
+
if (llvm::Expected<lldb::pid_t> pid = comm_channel.GetLauncherPid())
attach_info.SetProcessID(*pid);
else
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp
index 4409cf5b27e5b..f29ab09e4feb9 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -1463,7 +1463,7 @@ llvm::json::Object CreateRunInTerminalReverseRequest(
req_args.push_back("--launch-target");
req_args.push_back(program.str());
req_args.insert(req_args.end(), args.begin(), args.end());
- run_in_terminal_args.try_emplace("args", args);
+ run_in_terminal_args.try_emplace("args", req_args);
if (!cwd.empty())
run_in_terminal_args.try_emplace("cwd", cwd);
diff --git a/lldb/tools/lldb-dap/RunInTerminal.cpp b/lldb/tools/lldb-dap/RunInTerminal.cpp
index 9f309dd78221a..8afe6e8907710 100644
--- a/lldb/tools/lldb-dap/RunInTerminal.cpp
+++ b/lldb/tools/lldb-dap/RunInTerminal.cpp
@@ -9,7 +9,9 @@
#include "RunInTerminal.h"
#include "JSONUtils.h"
-#if !defined(_WIN32)
+#if defined(_WIN32)
+#include "lldb/Host/windows/windows.h"
+#else
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -96,7 +98,7 @@ static Error ToError(const RunInTerminalMessage &message) {
}
RunInTerminalLauncherCommChannel::RunInTerminalLauncherCommChannel(
- StringRef comm_file)
+ std::shared_ptr<FifoFile> comm_file)
: m_io(comm_file, "debug adapter") {}
Error RunInTerminalLauncherCommChannel::WaitUntilDebugAdapterAttaches(
@@ -111,8 +113,8 @@ Error RunInTerminalLauncherCommChannel::WaitUntilDebugAdapterAttaches(
return message.takeError();
}
-Error RunInTerminalLauncherCommChannel::NotifyPid() {
- return m_io.SendJSON(RunInTerminalMessagePid(getpid()).ToJSON());
+Error RunInTerminalLauncherCommChannel::NotifyPid(lldb::pid_t pid) {
+ return m_io.SendJSON(RunInTerminalMessagePid(pid).ToJSON());
}
void RunInTerminalLauncherCommChannel::NotifyError(StringRef error) {
@@ -121,8 +123,12 @@ void RunInTerminalLauncherCommChannel::NotifyError(StringRef error) {
llvm::errs() << llvm::toString(std::move(err)) << "\n";
}
+#if defined(_WIN32)
+bool RunInTerminalLauncherCommChannel::Connect() { return m_io.Connect(); }
+#endif
+
RunInTerminalDebugAdapterCommChannel::RunInTerminalDebugAdapterCommChannel(
- StringRef comm_file)
+ std::shared_ptr<FifoFile> comm_file)
: m_io(comm_file, "runInTerminal launcher") {}
// Can't use \a std::future<llvm::Error> because it doesn't compile on Windows
@@ -148,6 +154,10 @@ Expected<lldb::pid_t> RunInTerminalDebugAdapterCommChannel::GetLauncherPid() {
}
}
+#if defined(_WIN32)
+bool RunInTerminalDebugAdapterCommChannel::Connect() { return m_io.Connect(); }
+#endif
+
std::string RunInTerminalDebugAdapterCommChannel::GetLauncherError() {
// We know there's been an error, so a small timeout is enough.
if (Expected<RunInTerminalMessageUP> message =
@@ -158,13 +168,25 @@ std::string RunInTerminalDebugAdapterCommChannel::GetLauncherError() {
}
Expected<std::shared_ptr<FifoFile>> CreateRunInTerminalCommFile() {
+#if defined(_WIN32)
+ static constexpr llvm::StringLiteral g_pipe_name_prefix = "\\\\.\\Pipe\\";
+ SmallString<256> comm_file;
+ sys::fs::createUniquePath("lldb-dap-run-in-terminal-comm-%%%%%%", comm_file,
+ +false);
+ return CreateFifoFile((g_pipe_name_prefix + comm_file.str()).str(), true);
+#else
SmallString<256> comm_file;
if (std::error_code EC = sys::fs::getPotentiallyUniqueTempFileName(
"lldb-dap-run-in-terminal-comm", "", comm_file))
return createStringError(EC, "Error making unique file name for "
"runInTerminal communication files");
+ return CreateFifoFile(comm_file.str(), true);
+#endif
+}
- return CreateFifoFile(comm_file.str());
+Expected<std::shared_ptr<FifoFile>>
+OpenRunInTerminalCommFile(llvm::StringRef fifo_file) {
+ return CreateFifoFile(fifo_file, false);
}
} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/RunInTerminal.h b/lldb/tools/lldb-dap/RunInTerminal.h
index 457850c8ea538..10e715d1d12e1 100644
--- a/lldb/tools/lldb-dap/RunInTerminal.h
+++ b/lldb/tools/lldb-dap/RunInTerminal.h
@@ -70,7 +70,7 @@ struct RunInTerminalMessageDidAttach : RunInTerminalMessage {
class RunInTerminalLauncherCommChannel {
public:
- RunInTerminalLauncherCommChannel(llvm::StringRef comm_file);
+ RunInTerminalLauncherCommChannel(std::shared_ptr<FifoFile> comm_file);
/// Wait until the debug adapter attaches.
///
@@ -82,23 +82,31 @@ class RunInTerminalLauncherCommChannel {
/// out.
llvm::Error WaitUntilDebugAdapterAttaches(std::chrono::milliseconds timeout);
- /// Notify the debug adapter this process' pid.
+ /// Notify the debug adaptor debuggee's pid.
+ ///
+ /// \param[in] pid
+ /// The process ID to be attached.
///
/// \return
/// An \a llvm::Error object in case of errors or if this operation times
/// out.
- llvm::Error NotifyPid();
+ llvm::Error NotifyPid(lldb::pid_t pid);
/// Notify the debug adapter that there's been an error.
void NotifyError(llvm::StringRef error);
+#if defined(_WIN32)
+ /// Connect to RunInTerminalDebugAdapterCommChannel instance.
+ bool Connect();
+#endif
+
private:
FifoFileIO m_io;
};
class RunInTerminalDebugAdapterCommChannel {
public:
- RunInTerminalDebugAdapterCommChannel(llvm::StringRef comm_file);
+ RunInTerminalDebugAdapterCommChannel(std::shared_ptr<FifoFile> comm_file);
/// Notify the runInTerminal launcher that it was attached.
///
@@ -118,6 +126,11 @@ class RunInTerminalDebugAdapterCommChannel {
/// default error message if a certain timeout if reached.
std::string GetLauncherError();
+#if defined(_WIN32)
+ /// Connect to RunInTerminalLauncherCommChannel instance.
+ bool Connect();
+#endif
+
private:
FifoFileIO m_io;
};
@@ -126,6 +139,14 @@ class RunInTerminalDebugAdapterCommChannel {
/// the runInTerminal launcher.
llvm::Expected<std::shared_ptr<FifoFile>> CreateRunInTerminalCommFile();
+/// Open a fifo file used to communicate the debug adaptor with
+/// the runInTerminal launcher.
+///
+/// \param[in] fifo_file
+/// The path to a fifo file that exists in the file system.
+llvm::Expected<std::shared_ptr<FifoFile>>
+OpenRunInTerminalCommFile(llvm::StringRef fifo_file);
+
} // namespace lldb_dap
#endif // LLDB_TOOLS_LLDB_DAP_RUNINTERMINAL_H
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 6e17b13cc9e33..13fdd0e57ad1a 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -44,9 +44,11 @@
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
+#include <iomanip>
#include <map>
#include <memory>
#include <mutex>
+#include <sstream>
#include <string>
#include <system_error>
#include <thread>
@@ -204,14 +206,73 @@ static void PrintVersion() {
// In case of errors launching the target, a suitable error message will be
// emitted to the debug adapter.
static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg &target_arg,
- llvm::StringRef comm_file,
+ llvm::StringRef fifo_file,
lldb::pid_t debugger_pid,
char *argv[]) {
+ llvm::Expected<std::shared_ptr<FifoFile>> comm_file_or_err =
+ OpenRunInTerminalCommFile(fifo_file);
+ if (!comm_file_or_err) {
+ llvm::errs() << llvm::toString(comm_file_or_err.takeError()) << "\n";
+ exit(EXIT_FAILURE);
+ }
+ std::shared_ptr<FifoFile> comm_file = *comm_file_or_err;
+ RunInTerminalLauncherCommChannel comm_channel(comm_file);
+
#if defined(_WIN32)
- return llvm::createStringError(
- "runInTerminal is only supported on POSIX systems");
-#else
+ if (!comm_channel.Connect()) {
+ llvm::errs() << "Failed to connect to the named pipe.\n";
+ exit(EXIT_FAILURE);
+ }
+
+ STARTUPINFOA si;
+ PROCESS_INFORMATION pi;
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ ZeroMemory(&pi, sizeof(pi));
+
+ std::string cmd;
+ while (*argv != nullptr) {
+ std::stringstream ss;
+ ss << std::quoted(*(argv++));
+ cmd += ss.str();
+ cmd += " ";
+ }
+ cmd.pop_back();
+
+ if (!CreateProcessA(NULL, cmd.data(), NULL, NULL, FALSE, CREATE_SUSPENDED,
+ NULL, NULL, &si, &pi)) {
+ llvm::errs() << "Create process failed: " << GetLastError() << "\n";
+ exit(EXIT_FAILURE);
+ }
+ if (llvm::Error err = comm_channel.NotifyPid(pi.dwProcessId)) {
+ llvm::errs() << llvm::toString(std::move(err)) << "\n";
+ exit(EXIT_FAILURE);
+ }
+
+ // We will wait to be attached with a timeout. We don't wait indefinitely
+ // using a signal to prevent being paused forever.
+
+ // This env var should be used only for tests.
+ const char *timeout_env_var = getenv("LLDB_DAP_RIT_TIMEOUT_IN_MS");
+ int timeout_in_ms =
+ timeout_env_var != nullptr ? atoi(timeout_env_var) : 20000;
+ if (llvm::Error err = comm_channel.WaitUntilDebugAdapterAttaches(
+ std::chrono::milliseconds(timeout_in_ms))) {
+ llvm::errs() << llvm::toString(std::move(err)) << "\n";
+ exit(EXIT_FAILURE);
+ }
+
+ if (ResumeThread(pi.hThread) == (DWORD)-1) {
+ llvm::errs() << "Resume process failed: " << GetLastError() << "\n";
+ exit(EXIT_FAILURE);
+ }
+
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ exit(EXIT_SUCCESS);
+#else
// On Linux with the Yama security module enabled, a process can only attach
// to its descendants by default. In the runInTerminal case the target
// process is launched by the client so we need to allow tracing explicitly.
@@ -220,8 +281,7 @@ static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg &target_arg,
(void)prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);
#endif
- RunInTerminalLauncherCommChannel comm_channel(comm_file);
- if (llvm::Error err = comm_channel.NotifyPid())
+ if (ll...
[truncated]
|
c60a556
to
95b85c7
Compare
There's an existing PR that adds this functionality as well: #121269 with quite a bit of discussion. Does this PR have anything that's lacking in the other PR? |
It's quite similar. I use slightly different functionalites, but main idea is the same. Another PR looks abandoned. I am very interested in this functionality. You can close my PR and continue work on previous PR, thanks. |
Just a question, as far as I see, there is no |
It is actually not (yet). I have been actively waiting for maintainers to drop another review and have pinged & rebased several times over these three months. |
Added
runInTerminal
support for Windows based on Windows Named Pipes. Adapted existedFifoFile
class to Windows client-server pipes model. When server side owns the assosieted filesystem handle and client side only provide read-write acces to it. Also, fixed small typo inJSONUtill.cpp
related torunInTerminal
functionality.