https://github.com/piyushjaiswal98 updated https://github.com/llvm/llvm-project/pull/156131
>From 661f40f73df432937e2436233a04c448a9cbd054 Mon Sep 17 00:00:00 2001 From: Piyush Jaiswal <piyushj...@meta.com> Date: Fri, 29 Aug 2025 14:04:34 -0700 Subject: [PATCH 1/3] Add --no-lldbinit as a CLI flag --- .../test/tools/lldb-dap/dap_server.py | 8 +++- .../test/tools/lldb-dap/lldbdap_testcase.py | 5 ++- .../tools/lldb-dap/launch/TestDAP_launch.py | 44 +++++++++++++++++++ lldb/tools/lldb-dap/DAP.cpp | 5 ++- lldb/tools/lldb-dap/DAP.h | 10 ++++- .../Handler/InitializeRequestHandler.cpp | 7 ++- lldb/tools/lldb-dap/Options.td | 6 +++ lldb/tools/lldb-dap/tool/lldb-dap.cpp | 15 ++++--- lldb/unittests/DAP/DAPTest.cpp | 1 + lldb/unittests/DAP/TestBase.cpp | 1 + 10 files changed, 88 insertions(+), 14 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 0608ac3fd83be..3e83b8d5bdad7 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 @@ -1490,12 +1490,14 @@ def __init__( init_commands: list[str] = [], log_file: Optional[TextIO] = None, env: Optional[dict[str, str]] = None, + additional_args: list[str] = [], ): self.process = None self.connection = None if executable is not None: process, connection = DebugAdapterServer.launch( - executable=executable, connection=connection, env=env, log_file=log_file + executable=executable, connection=connection, env=env, log_file=log_file, + additional_args=additional_args ) self.process = process self.connection = connection @@ -1528,6 +1530,7 @@ def launch( env: Optional[dict[str, str]] = None, log_file: Optional[TextIO] = None, connection: Optional[str] = None, + additional_args: list[str] = [], ) -> tuple[subprocess.Popen, Optional[str]]: adapter_env = os.environ.copy() if env is not None: @@ -1537,6 +1540,9 @@ def launch( adapter_env["LLDBDAP_LOG"] = log_file args = [executable] + # Add additional arguments first (like --no-lldbinit) + args.extend(additional_args) + if connection is not None: args.append("--connection") args.append(connection) 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 b28a78792c70f..fffd4c23d6fcd 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 @@ -21,6 +21,7 @@ def create_debug_adapter( self, lldbDAPEnv: Optional[dict[str, str]] = None, connection: Optional[str] = None, + additional_args: Optional[list[str]] = None, ): """Create the Visual Studio Code debug adapter""" self.assertTrue( @@ -33,15 +34,17 @@ def create_debug_adapter( init_commands=self.setUpCommands(), log_file=log_file_path, env=lldbDAPEnv, + additional_args=additional_args or [], ) def build_and_create_debug_adapter( self, lldbDAPEnv: Optional[dict[str, str]] = None, dictionary: Optional[dict] = None, + additional_args: Optional[list[str]] = None, ): self.build(dictionary=dictionary) - self.create_debug_adapter(lldbDAPEnv) + self.create_debug_adapter(lldbDAPEnv, additional_args=additional_args) def build_and_create_debug_adapter_for_attach(self): """Variant of build_and_create_debug_adapter that builds a uniquely diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py index 41112a4f5b9e3..4b384e260ad24 100644 --- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py +++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py @@ -7,6 +7,7 @@ import lldbdap_testcase import os import re +import tempfile # Many tests are skipped on Windows because get_stdout() returns None there. # Despite the test program printing correctly. See @@ -582,3 +583,46 @@ def test_version(self): version_string.splitlines(), "version string does not match", ) + + def test_no_lldbinit_flag(self): + """ + Test that the --no-lldbinit flag prevents sourcing .lldbinit files. + """ + # Create a temporary .lldbinit file in the home directory + with tempfile.TemporaryDirectory() as temp_home: + lldbinit_path = os.path.join(temp_home, ".lldbinit") + + # Write a command to the .lldbinit file that would set a unique setting + with open(lldbinit_path, "w") as f: + f.write("settings set stop-disassembly-display never\n") + f.write("settings set target.x86-disassembly-flavor intel\n") + + # Test with --no-lldbinit flag (should NOT source .lldbinit) + self.build_and_create_debug_adapter( + lldbDAPEnv={"HOME": temp_home}, + additional_args=["--no-lldbinit"] + ) + program = self.getBuildArtifact("a.out") + + # Use initCommands to check if .lldbinit was sourced + initCommands = ["settings show stop-disassembly-display"] + + # Initialize the DAP session (should NOT source .lldbinit due to --no-lldbinit) + self.dap_server.request_initialize() + + # Launch with initCommands to check the setting + self.launch(program, initCommands=initCommands, stopOnEntry=True) + + # Get console output to verify the setting was NOT set from .lldbinit + output = self.get_console() + self.assertTrue(output and len(output) > 0, "expect console output") + + # Verify the setting has default value, not "never" from .lldbinit + self.assertNotIn( + "never", + output, + "Setting should have default value when --no-lldbinit is used", + ) + + # Verify the initCommands were executed + self.verify_commands("initCommands", output, initCommands) diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index b1ad38d983893..9c1966ea4238a 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -121,12 +121,13 @@ static std::string capitalize(llvm::StringRef str) { llvm::StringRef DAP::debug_adapter_path = ""; DAP::DAP(Log *log, const ReplMode default_repl_mode, - std::vector<std::string> pre_init_commands, + std::vector<std::string> pre_init_commands, bool no_lldbinit, llvm::StringRef client_name, DAPTransport &transport, MainLoop &loop) : log(log), transport(transport), broadcaster("lldb-dap"), progress_event_reporter( [&](const ProgressEvent &event) { SendJSON(event.ToJSON()); }), - repl_mode(default_repl_mode), m_client_name(client_name), m_loop(loop) { + repl_mode(default_repl_mode), no_lldbinit(no_lldbinit), + m_client_name(client_name), m_loop(loop) { configuration.preInitCommands = std::move(pre_init_commands); RegisterRequests(); } diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h index 04f70f76a09cd..71681fd4b51ed 100644 --- a/lldb/tools/lldb-dap/DAP.h +++ b/lldb/tools/lldb-dap/DAP.h @@ -156,6 +156,9 @@ struct DAP final : private DAPTransport::MessageHandler { /// The set of features supported by the connected client. llvm::DenseSet<ClientFeature> clientFeatures; + /// Whether to disable sourcing .lldbinit files. + bool no_lldbinit; + /// The initial thread list upon attaching. std::vector<protocol::Thread> initial_thread_list; @@ -178,13 +181,16 @@ struct DAP final : private DAPTransport::MessageHandler { /// \param[in] pre_init_commands /// LLDB commands to execute as soon as the debugger instance is /// allocated. + /// \param[in] no_lldbinit + /// Whether to disable sourcing .lldbinit files. /// \param[in] transport /// Transport for this debug session. /// \param[in] loop /// Main loop associated with this instance. DAP(Log *log, const ReplMode default_repl_mode, - std::vector<std::string> pre_init_commands, llvm::StringRef client_name, - DAPTransport &transport, lldb_private::MainLoop &loop); + std::vector<std::string> pre_init_commands, bool no_lldbinit, + llvm::StringRef client_name, DAPTransport &transport, + lldb_private::MainLoop &loop); ~DAP(); diff --git a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp index b499a69876e2c..9069de4a3a690 100644 --- a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp @@ -42,8 +42,11 @@ llvm::Expected<InitializeResponse> InitializeRequestHandler::Run( // The sourceInitFile option is not part of the DAP specification. It is an // extension used by the test suite to prevent sourcing `.lldbinit` and - // changing its behavior. - if (arguments.lldbExtSourceInitFile.value_or(true)) { + // changing its behavior. The CLI flag --no-lldbinit takes precedence over + // the DAP parameter. + bool should_source_init_files = + !dap.no_lldbinit && arguments.lldbExtSourceInitFile.value_or(true); + if (should_source_init_files) { dap.debugger.SkipLLDBInitFiles(false); dap.debugger.SkipAppInitFiles(false); lldb::SBCommandReturnObject init; diff --git a/lldb/tools/lldb-dap/Options.td b/lldb/tools/lldb-dap/Options.td index 867753e9294a6..b3fb592c84a8e 100644 --- a/lldb/tools/lldb-dap/Options.td +++ b/lldb/tools/lldb-dap/Options.td @@ -61,3 +61,9 @@ def pre_init_command: S<"pre-init-command">, def: Separate<["-"], "c">, Alias<pre_init_command>, HelpText<"Alias for --pre-init-command">; + +def no_lldbinit: F<"no-lldbinit">, + HelpText<"Do not automatically parse any '.lldbinit' files.">; +def: Flag<["-"], "x">, + Alias<no_lldbinit>, + HelpText<"Alias for --no-lldbinit">; diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp b/lldb/tools/lldb-dap/tool/lldb-dap.cpp index b74085f25f4e2..2431cf8fb2f24 100644 --- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp @@ -258,7 +258,8 @@ validateConnection(llvm::StringRef conn) { static llvm::Error serveConnection(const Socket::SocketProtocol &protocol, const std::string &name, Log *log, const ReplMode default_repl_mode, - const std::vector<std::string> &pre_init_commands) { + const std::vector<std::string> &pre_init_commands, + bool no_lldbinit) { Status status; static std::unique_ptr<Socket> listener = Socket::Create(protocol, status); if (status.Fail()) { @@ -303,8 +304,8 @@ serveConnection(const Socket::SocketProtocol &protocol, const std::string &name, llvm::set_thread_name(client_name + ".runloop"); MainLoop loop; Transport transport(client_name, log, io, io); - DAP dap(log, default_repl_mode, pre_init_commands, client_name, transport, - loop); + DAP dap(log, default_repl_mode, pre_init_commands, no_lldbinit, + client_name, transport, loop); if (auto Err = dap.ConfigureIO()) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), @@ -508,6 +509,8 @@ int main(int argc, char *argv[]) { pre_init_commands.push_back(arg); } + bool no_lldbinit = input_args.hasArg(OPT_no_lldbinit); + if (!connection.empty()) { auto maybeProtoclAndName = validateConnection(connection); if (auto Err = maybeProtoclAndName.takeError()) { @@ -520,7 +523,7 @@ int main(int argc, char *argv[]) { std::string name; std::tie(protocol, name) = *maybeProtoclAndName; if (auto Err = serveConnection(protocol, name, log.get(), default_repl_mode, - pre_init_commands)) { + pre_init_commands, no_lldbinit)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "Connection failed: "); return EXIT_FAILURE; @@ -556,8 +559,8 @@ int main(int argc, char *argv[]) { constexpr llvm::StringLiteral client_name = "stdio"; MainLoop loop; Transport transport(client_name, log.get(), input, output); - DAP dap(log.get(), default_repl_mode, pre_init_commands, client_name, - transport, loop); + DAP dap(log.get(), default_repl_mode, pre_init_commands, no_lldbinit, + client_name, transport, loop); // stdout/stderr redirection to the IDE's console if (auto Err = dap.ConfigureIO(stdout, stderr)) { diff --git a/lldb/unittests/DAP/DAPTest.cpp b/lldb/unittests/DAP/DAPTest.cpp index d5a9591ad0a43..2090fe6896d6b 100644 --- a/lldb/unittests/DAP/DAPTest.cpp +++ b/lldb/unittests/DAP/DAPTest.cpp @@ -28,6 +28,7 @@ TEST_F(DAPTest, SendProtocolMessages) { /*log=*/nullptr, /*default_repl_mode=*/ReplMode::Auto, /*pre_init_commands=*/{}, + /*no_lldbinit=*/false, /*client_name=*/"test_client", /*transport=*/*transport, /*loop=*/loop, diff --git a/lldb/unittests/DAP/TestBase.cpp b/lldb/unittests/DAP/TestBase.cpp index 54ac27da694e6..ba7baf2103799 100644 --- a/lldb/unittests/DAP/TestBase.cpp +++ b/lldb/unittests/DAP/TestBase.cpp @@ -55,6 +55,7 @@ void DAPTestBase::SetUp() { /*log=*/log.get(), /*default_repl_mode=*/ReplMode::Auto, /*pre_init_commands=*/std::vector<std::string>(), + /*no_lldbinit=*/false, /*client_name=*/"test_client", /*transport=*/*transport, /*loop=*/loop); } >From 2d7a46d5a0b9414fc2acd66912517ed09ff69a7c Mon Sep 17 00:00:00 2001 From: Piyush Jaiswal <piyushj...@meta.com> Date: Fri, 29 Aug 2025 18:02:37 -0700 Subject: [PATCH 2/3] Double DAP Server Initialize bug fix for --no-lldbinit Test --- lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py index 4b384e260ad24..79609a025b47c 100644 --- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py +++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py @@ -607,9 +607,6 @@ def test_no_lldbinit_flag(self): # Use initCommands to check if .lldbinit was sourced initCommands = ["settings show stop-disassembly-display"] - # Initialize the DAP session (should NOT source .lldbinit due to --no-lldbinit) - self.dap_server.request_initialize() - # Launch with initCommands to check the setting self.launch(program, initCommands=initCommands, stopOnEntry=True) >From cfe771e5f6aa472da20a6a30c9398472e32d740f Mon Sep 17 00:00:00 2001 From: Piyush Jaiswal <piyushj...@meta.com> Date: Fri, 29 Aug 2025 18:18:44 -0700 Subject: [PATCH 3/3] Fix Formatting Issue --- .../Python/lldbsuite/test/tools/lldb-dap/dap_server.py | 7 +++++-- lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py | 3 +-- 2 files changed, 6 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 3e83b8d5bdad7..66aa070a537e0 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 @@ -1496,8 +1496,11 @@ def __init__( self.connection = None if executable is not None: process, connection = DebugAdapterServer.launch( - executable=executable, connection=connection, env=env, log_file=log_file, - additional_args=additional_args + executable=executable, + connection=connection, + env=env, + log_file=log_file, + additional_args=additional_args, ) self.process = process self.connection = connection diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py index 79609a025b47c..5aaf5985ba749 100644 --- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py +++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py @@ -599,8 +599,7 @@ def test_no_lldbinit_flag(self): # Test with --no-lldbinit flag (should NOT source .lldbinit) self.build_and_create_debug_adapter( - lldbDAPEnv={"HOME": temp_home}, - additional_args=["--no-lldbinit"] + lldbDAPEnv={"HOME": temp_home}, additional_args=["--no-lldbinit"] ) program = self.getBuildArtifact("a.out") _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits