Author: Ebuka Ezike Date: 2026-02-06T18:08:20Z New Revision: 8244528aee54e823c62f7bee6c6184b530b3f772
URL: https://github.com/llvm/llvm-project/commit/8244528aee54e823c62f7bee6c6184b530b3f772 DIFF: https://github.com/llvm/llvm-project/commit/8244528aee54e823c62f7bee6c6184b530b3f772.diff LOG: [lldb-dap] Add validation for RunInTerminal client capability (#180213) Check if the client supports RunInTerminal before attempting to run in the preferred terminal. One less unknown reason for failed to launch Added: Modified: lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py lldb/tools/lldb-dap/Handler/RequestHandler.cpp Removed: ################################################################################ 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..47ae9a7195a7d 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()) { _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
