[Lldb-commits] [lldb] [lldb-dap] Add validation for RunInTerminal client capability (PR #180213)
Ebuka Ezike via lldb-commits
lldb-commits at lists.llvm.org
Fri Feb 6 09:34:50 PST 2026
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/180213
>From ae39a57a18785cad0454f746a1ad3b0c8ea0884c Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Fri, 6 Feb 2026 15:24:39 +0000
Subject: [PATCH 1/2] [lldb-dap] Add validation for RunInTerminal client
capability
Check if the client supports RunInTerminal before attempting to
run in the preferred terminal.
One less unknown reason for failed to launch
---
.../lldbsuite/test/tools/lldb-dap/dap_server.py | 13 +++++++++++--
.../test/tools/lldb-dap/lldbdap_testcase.py | 10 ++++++++--
.../lldb-dap/runInTerminal/TestDAP_runInTerminal.py | 12 ++++++++++++
lldb/tools/lldb-dap/Handler/RequestHandler.cpp | 4 ++++
4 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 840c087ceec4d..fdccc9eae9fe4 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -1183,7 +1183,9 @@ def request_exceptionInfo(self, threadId=None):
}
return self._send_recv(command_dict)
- def request_initialize(self, sourceInitFile=False):
+ def request_initialize(
+ self, client_features: Optional[dict[str, bool]] = None, sourceInitFile=False
+ ):
command_dict = {
"command": "initialize",
"type": "request",
@@ -1204,6 +1206,13 @@ def request_initialize(self, sourceInitFile=False):
"$__lldb_sourceInitFile": sourceInitFile,
},
}
+
+ if client_features is not None:
+ arguments = command_dict["arguments"]
+ # replace the default client features.
+ for key, value in client_features.items():
+ arguments[key] = value
+
response = self._send_recv(command_dict)
if response:
if "body" in response:
@@ -1866,7 +1875,7 @@ def attach_options_specified(opts):
def run_adapter(dbg: DebugCommunication, opts: argparse.Namespace) -> None:
- dbg.request_initialize(opts.source_init_file)
+ dbg.request_initialize(sourceInitFile=opts.source_init_file)
source_to_lines: Dict[str, List[int]] = {}
for sbp in cast(List[str], opts.source_bp):
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index f3c16bd849a48..f14742365e70e 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -535,6 +535,7 @@ def _build_error_message(self, base_message, response):
def attach(
self,
*,
+ client_features: Optional[dict[str, bool]] = None,
disconnectAutomatically=True,
sourceInitFile=False,
**kwargs,
@@ -551,7 +552,9 @@ def cleanup():
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
# Initialize and launch the program
- self.dap_server.request_initialize(sourceInitFile)
+ self.dap_server.request_initialize(
+ client_features=client_features, sourceInitFile=sourceInitFile
+ )
return self.dap_server.request_attach(**kwargs)
def attach_and_configurationDone(
@@ -568,6 +571,7 @@ def launch(
self,
program: str,
*,
+ client_features: Optional[dict[str, bool]] = None,
sourceInitFile=False,
disconnectAutomatically=True,
**kwargs,
@@ -585,7 +589,9 @@ def cleanup():
self.addTearDownHook(cleanup)
# Initialize and launch the program
- self.dap_server.request_initialize(sourceInitFile)
+ self.dap_server.request_initialize(
+ client_features=client_features, sourceInitFile=sourceInitFile
+ )
return self.dap_server.request_launch(program, **kwargs)
def launch_and_configurationDone(
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 a996a1a310bd0..dfb4906ae6a49 100644
--- a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
+++ b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
@@ -215,3 +215,15 @@ def test_NonAttachedRunInTerminalLauncher(self):
_, stderr = proc.communicate()
self.assertIn("Timed out trying to get messages from the debug adapter", stderr)
+
+ def test_client_missing_runInTerminal_feature(self):
+ program = self.getBuildArtifact("a.out")
+ self.build_and_create_debug_adapter()
+ response = self.launch_and_configurationDone(
+ program,
+ console="integratedTerminal",
+ client_features={"supportsRunInTerminalRequest": False},
+ )
+ self.assertFalse(response["success"], f"Expected failure got {response!r}")
+ error_message = response["body"]["error"]["format"]
+ self.assertIn("Client does not support RunInTerminal.", error_message)
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index 5cb0055f034da..4d1067a6e7744 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -234,6 +234,10 @@ llvm::Error BaseRequestHandler::LaunchProcess(
ScopeSyncMode scope_sync_mode(dap.debugger);
if (arguments.console != protocol::eConsoleInternal) {
+ if (!dap.clientFeatures.contains(eClientFeatureRunInTerminalRequest))
+ return llvm::make_error<DAPError>(
+ R"(Client does not support RunInTerminal. Please set "console": "integratedConsole" in your launch configuration)");
+
if (llvm::Error err = RunInTerminal(dap, arguments))
return err;
} else if (launchCommands.empty()) {
>From 7e11a54ed5db1aede5eb72c3ce81ecf62bfb9ab2 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Fri, 6 Feb 2026 17:33:32 +0000
Subject: [PATCH 2/2] add review changes
---
lldb/tools/lldb-dap/Handler/RequestHandler.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index 4d1067a6e7744..47ae9a7195a7d 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -236,7 +236,7 @@ llvm::Error BaseRequestHandler::LaunchProcess(
if (arguments.console != protocol::eConsoleInternal) {
if (!dap.clientFeatures.contains(eClientFeatureRunInTerminalRequest))
return llvm::make_error<DAPError>(
- R"(Client does not support RunInTerminal. Please set "console": "integratedConsole" in your launch configuration)");
+ R"(Client does not support RunInTerminal. Please set '"console": "integratedConsole"' in your launch configuration)");
if (llvm::Error err = RunInTerminal(dap, arguments))
return err;
More information about the lldb-commits
mailing list