[Lldb-commits] [lldb] [lldb-dap] Add validation for RunInTerminal client capability (PR #180213)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Feb 6 07:27:20 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Ebuka Ezike (da-viper)
<details>
<summary>Changes</summary>
Check if the client supports RunInTerminal before attempting to run in the preferred terminal.
One less unknown reason for failed to launch
---
Full diff: https://github.com/llvm/llvm-project/pull/180213.diff
4 Files Affected:
- (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py (+11-2)
- (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py (+8-2)
- (modified) lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py (+12)
- (modified) lldb/tools/lldb-dap/Handler/RequestHandler.cpp (+4)
``````````diff
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()) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/180213
More information about the lldb-commits
mailing list