[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
https://github.com/ashgti approved this pull request. https://github.com/llvm/llvm-project/pull/175048 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
@@ -288,8 +288,8 @@ static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg
&target_arg,
if (!stdio.empty()) {
llvm::SmallVector files;
DrSergei wrote:
I mean using `llvm::SmallVector stdio_files;` to
avoid constant duplication
https://github.com/llvm/llvm-project/pull/175048
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
@@ -288,8 +288,8 @@ static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg
&target_arg,
if (!stdio.empty()) {
llvm::SmallVector files;
da-viper wrote:
I changed it to stdio_files instead as num_of_stdio indicates it is a number.
https://github.com/llvm/llvm-project/pull/175048
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
https://github.com/da-viper updated
https://github.com/llvm/llvm-project/pull/175048
>From e6988e729f084a2775d18c68bb4dbc749133db67 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike
Date: Mon, 29 Dec 2025 01:51:47 +
Subject: [PATCH 1/8] [lldb-dap] fix redirection with program args
---
.../tools/lldb-dap/Handler/RequestHandler.cpp | 24 +--
lldb/tools/lldb-dap/JSONUtils.cpp | 20 +---
.../lldb-dap/Protocol/ProtocolRequests.cpp| 9 ++-
lldb/tools/lldb-dap/tool/lldb-dap.cpp | 4 ++--
4 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index b06a43d7421c1..8be83fac2c117 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -61,25 +61,25 @@ static uint32_t SetLaunchFlag(uint32_t flags, bool flag,
static void
SetupIORedirection(const std::vector> &stdio,
lldb::SBLaunchInfo &launch_info) {
- size_t n = std::max(stdio.size(), static_cast(3));
- for (size_t i = 0; i < n; i++) {
-std::optional path;
-if (stdio.size() <= i)
- path = stdio.back();
-else
- path = stdio[i];
-if (!path)
+ for (const auto &[idx, value_opt] : llvm::enumerate(stdio)) {
+if (!value_opt)
continue;
-switch (i) {
+const std::string &path = value_opt.value();
+assert(!path.empty() && "paths should not be empty");
+
+const int fd = static_cast(idx);
+switch (fd) {
case 0:
- launch_info.AddOpenFileAction(i, path->c_str(), true, false);
+ launch_info.AddOpenFileAction(STDIN_FILENO, path.c_str(), true, false);
break;
case 1:
+ launch_info.AddOpenFileAction(STDOUT_FILENO, path.c_str(), false, true);
+ break;
case 2:
- launch_info.AddOpenFileAction(i, path->c_str(), false, true);
+ launch_info.AddOpenFileAction(STDERR_FILENO, path.c_str(), false, true);
break;
default:
- launch_info.AddOpenFileAction(i, path->c_str(), true, true);
+ launch_info.AddOpenFileAction(fd, path.c_str(), true, true);
break;
}
}
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 9a2142cd847ab..4bf9d6e19ad80 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -720,20 +720,24 @@ llvm::json::Object CreateRunInTerminalReverseRequest(
req_args.push_back("--debugger-pid");
req_args.push_back(std::to_string(debugger_pid));
}
- req_args.push_back("--launch-target");
- req_args.push_back(program.str());
+
if (!stdio.empty()) {
-req_args.push_back("--stdio");
+req_args.emplace_back("--stdio");
+
std::stringstream ss;
+std::string_view delimiter;
for (const std::optional &file : stdio) {
+ ss << std::exchange(delimiter, ":");
if (file)
-ss << *file;
- ss << ":";
+ss << file.value();
}
-std::string files = ss.str();
-files.pop_back();
-req_args.push_back(std::move(files));
+req_args.push_back(ss.str());
}
+
+ // WARNING: Any argument added after `launch-target` is passed to to the
+ // target.
+ req_args.emplace_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", req_args);
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index c3225f6ba0e35..1f8283eba86fa 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
@@ -296,7 +296,7 @@ bool fromJSON(const json::Value &Params, Console &C,
json::Path P) {
bool fromJSON(const json::Value &Params, LaunchRequestArguments &LRA,
json::Path P) {
json::ObjectMapper O(Params, P);
- bool success =
+ const bool success =
O && fromJSON(Params, LRA.configuration, P) &&
O.mapOptional("noDebug", LRA.noDebug) &&
O.mapOptional("launchCommands", LRA.launchCommands) &&
@@ -310,6 +310,13 @@ bool fromJSON(const json::Value &Params,
LaunchRequestArguments &LRA,
O.mapOptional("stdio", LRA.stdio) && parseEnv(Params, LRA.env, P);
if (!success)
return false;
+
+ for (std::optional &io_path : LRA.stdio) {
+// set empty paths to null.
+if (io_path && llvm::StringRef(*io_path).trim().empty())
+ io_path.reset();
+ }
+
// Validate that we have a well formed launch request.
if (!LRA.launchCommands.empty() &&
LRA.console != protocol::eConsoleInternal) {
diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
index e3b9d57e7d3a1..90168dec699b7 100644
--- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
@@ -288,8 +288,8 @@ static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg
&target_arg,
if (!stdio.
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
https://github.com/da-viper updated
https://github.com/llvm/llvm-project/pull/175048
>From e6988e729f084a2775d18c68bb4dbc749133db67 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike
Date: Mon, 29 Dec 2025 01:51:47 +
Subject: [PATCH 1/7] [lldb-dap] fix redirection with program args
---
.../tools/lldb-dap/Handler/RequestHandler.cpp | 24 +--
lldb/tools/lldb-dap/JSONUtils.cpp | 20 +---
.../lldb-dap/Protocol/ProtocolRequests.cpp| 9 ++-
lldb/tools/lldb-dap/tool/lldb-dap.cpp | 4 ++--
4 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index b06a43d7421c1..8be83fac2c117 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -61,25 +61,25 @@ static uint32_t SetLaunchFlag(uint32_t flags, bool flag,
static void
SetupIORedirection(const std::vector> &stdio,
lldb::SBLaunchInfo &launch_info) {
- size_t n = std::max(stdio.size(), static_cast(3));
- for (size_t i = 0; i < n; i++) {
-std::optional path;
-if (stdio.size() <= i)
- path = stdio.back();
-else
- path = stdio[i];
-if (!path)
+ for (const auto &[idx, value_opt] : llvm::enumerate(stdio)) {
+if (!value_opt)
continue;
-switch (i) {
+const std::string &path = value_opt.value();
+assert(!path.empty() && "paths should not be empty");
+
+const int fd = static_cast(idx);
+switch (fd) {
case 0:
- launch_info.AddOpenFileAction(i, path->c_str(), true, false);
+ launch_info.AddOpenFileAction(STDIN_FILENO, path.c_str(), true, false);
break;
case 1:
+ launch_info.AddOpenFileAction(STDOUT_FILENO, path.c_str(), false, true);
+ break;
case 2:
- launch_info.AddOpenFileAction(i, path->c_str(), false, true);
+ launch_info.AddOpenFileAction(STDERR_FILENO, path.c_str(), false, true);
break;
default:
- launch_info.AddOpenFileAction(i, path->c_str(), true, true);
+ launch_info.AddOpenFileAction(fd, path.c_str(), true, true);
break;
}
}
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 9a2142cd847ab..4bf9d6e19ad80 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -720,20 +720,24 @@ llvm::json::Object CreateRunInTerminalReverseRequest(
req_args.push_back("--debugger-pid");
req_args.push_back(std::to_string(debugger_pid));
}
- req_args.push_back("--launch-target");
- req_args.push_back(program.str());
+
if (!stdio.empty()) {
-req_args.push_back("--stdio");
+req_args.emplace_back("--stdio");
+
std::stringstream ss;
+std::string_view delimiter;
for (const std::optional &file : stdio) {
+ ss << std::exchange(delimiter, ":");
if (file)
-ss << *file;
- ss << ":";
+ss << file.value();
}
-std::string files = ss.str();
-files.pop_back();
-req_args.push_back(std::move(files));
+req_args.push_back(ss.str());
}
+
+ // WARNING: Any argument added after `launch-target` is passed to to the
+ // target.
+ req_args.emplace_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", req_args);
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index c3225f6ba0e35..1f8283eba86fa 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
@@ -296,7 +296,7 @@ bool fromJSON(const json::Value &Params, Console &C,
json::Path P) {
bool fromJSON(const json::Value &Params, LaunchRequestArguments &LRA,
json::Path P) {
json::ObjectMapper O(Params, P);
- bool success =
+ const bool success =
O && fromJSON(Params, LRA.configuration, P) &&
O.mapOptional("noDebug", LRA.noDebug) &&
O.mapOptional("launchCommands", LRA.launchCommands) &&
@@ -310,6 +310,13 @@ bool fromJSON(const json::Value &Params,
LaunchRequestArguments &LRA,
O.mapOptional("stdio", LRA.stdio) && parseEnv(Params, LRA.env, P);
if (!success)
return false;
+
+ for (std::optional &io_path : LRA.stdio) {
+// set empty paths to null.
+if (io_path && llvm::StringRef(*io_path).trim().empty())
+ io_path.reset();
+ }
+
// Validate that we have a well formed launch request.
if (!LRA.launchCommands.empty() &&
LRA.console != protocol::eConsoleInternal) {
diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
index e3b9d57e7d3a1..90168dec699b7 100644
--- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
@@ -288,8 +288,8 @@ static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg
&target_arg,
if (!stdio.
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
@@ -288,8 +288,8 @@ static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg
&target_arg,
if (!stdio.empty()) {
llvm::SmallVector files;
DrSergei wrote:
nit: can we use `num_of_stdio` in `SmallVector`
https://github.com/llvm/llvm-project/pull/175048
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
https://github.com/DrSergei approved this pull request. Thank you, LGTM https://github.com/llvm/llvm-project/pull/175048 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
@@ -720,20 +720,24 @@ llvm::json::Object CreateRunInTerminalReverseRequest(
req_args.push_back("--debugger-pid");
req_args.push_back(std::to_string(debugger_pid));
}
- req_args.push_back("--launch-target");
- req_args.push_back(program.str());
+
if (!stdio.empty()) {
-req_args.push_back("--stdio");
+req_args.emplace_back("--stdio");
+
std::stringstream ss;
+std::string_view delimiter;
for (const std::optional &file : stdio) {
+ ss << std::exchange(delimiter, ":");
if (file)
-ss << *file;
- ss << ":";
+ss << file.value();
DrSergei wrote:
nit: I think we can keep `*file`, because `value()` performs checks that
optional contains value. Maybe this check is skipped when we use build wihtout
exceptions, but it looks like that we use `*` more often than `value()`
https://github.com/llvm/llvm-project/pull/175048
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
@@ -406,14 +406,25 @@ def terminate(self): class _LocalProcess(_BaseProcess): def __init__(self, trace_on): -self._proc = None +self._proc: Popen | None = None DrSergei wrote: nit: maybe use `Optional` like in `reverse_process` below https://github.com/llvm/llvm-project/pull/175048 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
https://github.com/DrSergei edited https://github.com/llvm/llvm-project/pull/175048 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
@@ -0,0 +1,24 @@
+#include
+#include
+
+int main(int argc, char *argv[]) {
+ const bool use_stdin = argc <= 1;
+ const char *use_env = std::getenv("FROM_ENV");
+
+ if (use_env != nullptr) { // from environment variable
+std::cout << "[STDOUT][FROM_ENV]: " << use_env;
+std::cerr << "[STDERR][FROM_ENV]: " << use_env;
+
+ } else if (use_stdin) { // from standard in
+std::string line;
+std::getline(std::cin, line);
+std::cout << "[STDOUT][FROM_STDIN]: " << line;
+std::cerr << "[STDERR][FROM_STDIN]: " << line;
+
+ } else { // from argv
+const char *first_arg = argv[1];
+std::cout << "[STDOUT][FROM_ARGV]: " << first_arg;
+std::cerr << "[STDERR][FROM_ARGV]: " << first_arg;
+ }
+ return 0;
+}
DrSergei wrote:
nit: add empty line at the end of file
https://github.com/llvm/llvm-project/pull/175048
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
@@ -25,6 +25,9 @@ #if !defined(_WIN32) #include #endif +#ifdef _WIN32 DrSergei wrote: nit: maybe use `#else` https://github.com/llvm/llvm-project/pull/175048 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
https://github.com/da-viper updated
https://github.com/llvm/llvm-project/pull/175048
>From e6988e729f084a2775d18c68bb4dbc749133db67 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike
Date: Mon, 29 Dec 2025 01:51:47 +
Subject: [PATCH 1/6] [lldb-dap] fix redirection with program args
---
.../tools/lldb-dap/Handler/RequestHandler.cpp | 24 +--
lldb/tools/lldb-dap/JSONUtils.cpp | 20 +---
.../lldb-dap/Protocol/ProtocolRequests.cpp| 9 ++-
lldb/tools/lldb-dap/tool/lldb-dap.cpp | 4 ++--
4 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index b06a43d7421c1..8be83fac2c117 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -61,25 +61,25 @@ static uint32_t SetLaunchFlag(uint32_t flags, bool flag,
static void
SetupIORedirection(const std::vector> &stdio,
lldb::SBLaunchInfo &launch_info) {
- size_t n = std::max(stdio.size(), static_cast(3));
- for (size_t i = 0; i < n; i++) {
-std::optional path;
-if (stdio.size() <= i)
- path = stdio.back();
-else
- path = stdio[i];
-if (!path)
+ for (const auto &[idx, value_opt] : llvm::enumerate(stdio)) {
+if (!value_opt)
continue;
-switch (i) {
+const std::string &path = value_opt.value();
+assert(!path.empty() && "paths should not be empty");
+
+const int fd = static_cast(idx);
+switch (fd) {
case 0:
- launch_info.AddOpenFileAction(i, path->c_str(), true, false);
+ launch_info.AddOpenFileAction(STDIN_FILENO, path.c_str(), true, false);
break;
case 1:
+ launch_info.AddOpenFileAction(STDOUT_FILENO, path.c_str(), false, true);
+ break;
case 2:
- launch_info.AddOpenFileAction(i, path->c_str(), false, true);
+ launch_info.AddOpenFileAction(STDERR_FILENO, path.c_str(), false, true);
break;
default:
- launch_info.AddOpenFileAction(i, path->c_str(), true, true);
+ launch_info.AddOpenFileAction(fd, path.c_str(), true, true);
break;
}
}
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 9a2142cd847ab..4bf9d6e19ad80 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -720,20 +720,24 @@ llvm::json::Object CreateRunInTerminalReverseRequest(
req_args.push_back("--debugger-pid");
req_args.push_back(std::to_string(debugger_pid));
}
- req_args.push_back("--launch-target");
- req_args.push_back(program.str());
+
if (!stdio.empty()) {
-req_args.push_back("--stdio");
+req_args.emplace_back("--stdio");
+
std::stringstream ss;
+std::string_view delimiter;
for (const std::optional &file : stdio) {
+ ss << std::exchange(delimiter, ":");
if (file)
-ss << *file;
- ss << ":";
+ss << file.value();
}
-std::string files = ss.str();
-files.pop_back();
-req_args.push_back(std::move(files));
+req_args.push_back(ss.str());
}
+
+ // WARNING: Any argument added after `launch-target` is passed to to the
+ // target.
+ req_args.emplace_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", req_args);
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index c3225f6ba0e35..1f8283eba86fa 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
@@ -296,7 +296,7 @@ bool fromJSON(const json::Value &Params, Console &C,
json::Path P) {
bool fromJSON(const json::Value &Params, LaunchRequestArguments &LRA,
json::Path P) {
json::ObjectMapper O(Params, P);
- bool success =
+ const bool success =
O && fromJSON(Params, LRA.configuration, P) &&
O.mapOptional("noDebug", LRA.noDebug) &&
O.mapOptional("launchCommands", LRA.launchCommands) &&
@@ -310,6 +310,13 @@ bool fromJSON(const json::Value &Params,
LaunchRequestArguments &LRA,
O.mapOptional("stdio", LRA.stdio) && parseEnv(Params, LRA.env, P);
if (!success)
return false;
+
+ for (std::optional &io_path : LRA.stdio) {
+// set empty paths to null.
+if (io_path && llvm::StringRef(*io_path).trim().empty())
+ io_path.reset();
+ }
+
// Validate that we have a well formed launch request.
if (!LRA.launchCommands.empty() &&
LRA.console != protocol::eConsoleInternal) {
diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
index e3b9d57e7d3a1..90168dec699b7 100644
--- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
@@ -288,8 +288,8 @@ static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg
&target_arg,
if (!stdio.
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
da-viper wrote: darker recommended format style differs from the one in CI. https://github.com/llvm/llvm-project/pull/175048 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add testcases for stdio redirection on different console types. (PR #175048)
https://github.com/da-viper updated
https://github.com/llvm/llvm-project/pull/175048
>From e6988e729f084a2775d18c68bb4dbc749133db67 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike
Date: Mon, 29 Dec 2025 01:51:47 +
Subject: [PATCH 1/5] [lldb-dap] fix redirection with program args
---
.../tools/lldb-dap/Handler/RequestHandler.cpp | 24 +--
lldb/tools/lldb-dap/JSONUtils.cpp | 20 +---
.../lldb-dap/Protocol/ProtocolRequests.cpp| 9 ++-
lldb/tools/lldb-dap/tool/lldb-dap.cpp | 4 ++--
4 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index b06a43d7421c1..8be83fac2c117 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -61,25 +61,25 @@ static uint32_t SetLaunchFlag(uint32_t flags, bool flag,
static void
SetupIORedirection(const std::vector> &stdio,
lldb::SBLaunchInfo &launch_info) {
- size_t n = std::max(stdio.size(), static_cast(3));
- for (size_t i = 0; i < n; i++) {
-std::optional path;
-if (stdio.size() <= i)
- path = stdio.back();
-else
- path = stdio[i];
-if (!path)
+ for (const auto &[idx, value_opt] : llvm::enumerate(stdio)) {
+if (!value_opt)
continue;
-switch (i) {
+const std::string &path = value_opt.value();
+assert(!path.empty() && "paths should not be empty");
+
+const int fd = static_cast(idx);
+switch (fd) {
case 0:
- launch_info.AddOpenFileAction(i, path->c_str(), true, false);
+ launch_info.AddOpenFileAction(STDIN_FILENO, path.c_str(), true, false);
break;
case 1:
+ launch_info.AddOpenFileAction(STDOUT_FILENO, path.c_str(), false, true);
+ break;
case 2:
- launch_info.AddOpenFileAction(i, path->c_str(), false, true);
+ launch_info.AddOpenFileAction(STDERR_FILENO, path.c_str(), false, true);
break;
default:
- launch_info.AddOpenFileAction(i, path->c_str(), true, true);
+ launch_info.AddOpenFileAction(fd, path.c_str(), true, true);
break;
}
}
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 9a2142cd847ab..4bf9d6e19ad80 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -720,20 +720,24 @@ llvm::json::Object CreateRunInTerminalReverseRequest(
req_args.push_back("--debugger-pid");
req_args.push_back(std::to_string(debugger_pid));
}
- req_args.push_back("--launch-target");
- req_args.push_back(program.str());
+
if (!stdio.empty()) {
-req_args.push_back("--stdio");
+req_args.emplace_back("--stdio");
+
std::stringstream ss;
+std::string_view delimiter;
for (const std::optional &file : stdio) {
+ ss << std::exchange(delimiter, ":");
if (file)
-ss << *file;
- ss << ":";
+ss << file.value();
}
-std::string files = ss.str();
-files.pop_back();
-req_args.push_back(std::move(files));
+req_args.push_back(ss.str());
}
+
+ // WARNING: Any argument added after `launch-target` is passed to to the
+ // target.
+ req_args.emplace_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", req_args);
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index c3225f6ba0e35..1f8283eba86fa 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
@@ -296,7 +296,7 @@ bool fromJSON(const json::Value &Params, Console &C,
json::Path P) {
bool fromJSON(const json::Value &Params, LaunchRequestArguments &LRA,
json::Path P) {
json::ObjectMapper O(Params, P);
- bool success =
+ const bool success =
O && fromJSON(Params, LRA.configuration, P) &&
O.mapOptional("noDebug", LRA.noDebug) &&
O.mapOptional("launchCommands", LRA.launchCommands) &&
@@ -310,6 +310,13 @@ bool fromJSON(const json::Value &Params,
LaunchRequestArguments &LRA,
O.mapOptional("stdio", LRA.stdio) && parseEnv(Params, LRA.env, P);
if (!success)
return false;
+
+ for (std::optional &io_path : LRA.stdio) {
+// set empty paths to null.
+if (io_path && llvm::StringRef(*io_path).trim().empty())
+ io_path.reset();
+ }
+
// Validate that we have a well formed launch request.
if (!LRA.launchCommands.empty() &&
LRA.console != protocol::eConsoleInternal) {
diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
index e3b9d57e7d3a1..90168dec699b7 100644
--- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
@@ -288,8 +288,8 @@ static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg
&target_arg,
if (!stdio.
