Skip to content

Commit 4c3e009

Browse files
committed
[lldb-dap] Add stdio redirection
1 parent acd0899 commit 4c3e009

File tree

7 files changed

+62
-1
lines changed

7 files changed

+62
-1
lines changed

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,7 @@ def request_launch(
10391039
disableSTDIO=False,
10401040
shellExpandArguments=False,
10411041
console: Optional[str] = None,
1042+
stdio: Optional[list[str]] = None,
10421043
enableAutoVariableSummaries=False,
10431044
displayExtendedBacktrace=False,
10441045
enableSyntheticChildDebugging=False,
@@ -1090,6 +1091,8 @@ def request_launch(
10901091
args_dict["sourceMap"] = sourceMap
10911092
if console:
10921093
args_dict["console"] = console
1094+
if stdio:
1095+
args_dict["stdio"] = stdio
10931096
if postRunCommands:
10941097
args_dict["postRunCommands"] = postRunCommands
10951098
if customFrameFormat:

lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from lldbsuite.test.lldbtest import *
77
import lldbdap_testcase
88
import os
9+
import pathlib
910
import re
1011
import tempfile
1112

@@ -624,3 +625,23 @@ def test_no_lldbinit_flag(self):
624625

625626
# Verify the initCommands were executed
626627
self.verify_commands("initCommands", output, initCommands)
628+
629+
def test_stdio_redirection(self):
630+
"""
631+
Test stdio redirection.
632+
"""
633+
temp_file = tempfile.NamedTemporaryFile().name
634+
self.build_and_create_debug_adapter()
635+
program = self.getBuildArtifact("a.out")
636+
637+
self.launch(program, stdio=[None, temp_file, None])
638+
self.continue_to_exit()
639+
640+
try:
641+
with open(temp_file, "r") as f:
642+
lines = f.readlines()
643+
self.assertIn(
644+
program, lines[0], "make sure program path is in first argument"
645+
)
646+
finally:
647+
pathlib.Path(temp_file).unlink(missing_ok=True)

lldb/tools/lldb-dap/Handler/RequestHandler.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,31 @@ llvm::Error BaseRequestHandler::LaunchProcess(
177177
launch_info.SetEnvironment(env, true);
178178
}
179179

180+
if (!arguments.stdio.empty() && !arguments.disableSTDIO) {
181+
size_t n = std::max(arguments.stdio.size(), static_cast<size_t>(3));
182+
for (size_t i = 0; i < n; i++) {
183+
std::optional<std::string> path;
184+
if (arguments.stdio.size() < i)
185+
path = arguments.stdio.back();
186+
else
187+
path = arguments.stdio[i];
188+
if (!path)
189+
continue;
190+
switch (i) {
191+
case 0:
192+
launch_info.AddOpenFileAction(i, path->c_str(), true, false);
193+
break;
194+
case 1:
195+
case 2:
196+
launch_info.AddOpenFileAction(i, path->c_str(), false, true);
197+
break;
198+
default:
199+
launch_info.AddOpenFileAction(i, path->c_str(), true, true);
200+
break;
201+
}
202+
}
203+
}
204+
180205
launch_info.SetDetachOnError(arguments.detachOnError);
181206
launch_info.SetShellExpandArguments(arguments.shellExpandArguments);
182207

lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ bool fromJSON(const json::Value &Params, LaunchRequestArguments &LRA,
303303
O.mapOptional("disableSTDIO", LRA.disableSTDIO) &&
304304
O.mapOptional("shellExpandArguments", LRA.shellExpandArguments) &&
305305
O.mapOptional("runInTerminal", LRA.console) &&
306-
O.mapOptional("console", LRA.console) && parseEnv(Params, LRA.env, P);
306+
O.mapOptional("console", LRA.console) &&
307+
O.mapOptional("stdio", LRA.stdio) && parseEnv(Params, LRA.env, P);
307308
}
308309

309310
bool fromJSON(const json::Value &Params, AttachRequestArguments &ARA,

lldb/tools/lldb-dap/Protocol/ProtocolRequests.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ struct LaunchRequestArguments {
300300
/// terminal or external terminal.
301301
Console console = eConsoleInternal;
302302

303+
std::vector<std::optional<std::string>> stdio;
304+
303305
/// @}
304306
};
305307
bool fromJSON(const llvm::json::Value &, LaunchRequestArguments &,

lldb/tools/lldb-dap/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ contain the following key/value pairs:
237237
| **stopOnEntry** | boolean | | Whether to stop program immediately after launching.
238238
| **runInTerminal** (deprecated) | boolean | | Launch the program inside an integrated terminal in the IDE. Useful for debugging interactive command line programs.
239239
| **console** | string | | Specify where to launch the program: internal console (`internalConsole`), integrated terminal (`integratedTerminal`) or external terminal (`externalTerminal`). Supported from lldb-dap 21.0 version.
240+
| **stdio** | [string] | | Destination for program stdio streams (0 - stdin, 1 - stdout, 2 - stderr, ...). Using `null` value means no redirection. Supported from lldb-dap 22.0 version.
240241
| **launchCommands** | [string] | | LLDB commands executed to launch the program.
241242

242243
For JSON configurations of `"type": "attach"`, the JSON configuration can contain

lldb/tools/lldb-dap/package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,14 @@
615615
"description": "Specify where to launch the program: internal console, integrated terminal or external terminal.",
616616
"default": "internalConsole"
617617
},
618+
"stdio": {
619+
"type": "array",
620+
"items": {
621+
"type": "string"
622+
},
623+
"description": "Destination for program stdio streams (0 - stdin, 1 - stdout, 2 - stderr, ...). Using null value means no redirection.",
624+
"default": []
625+
},
618626
"timeout": {
619627
"type": "number",
620628
"description": "The time in seconds to wait for a program to stop at entry point when launching with \"launchCommands\". Defaults to 30 seconds."

0 commit comments

Comments
 (0)