Skip to content

Fix the lldb-dap error when empty source map is specified #137722

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jeffreytan81
Copy link
Contributor

We have some lldb-dap clients that are specifying an empty source map during launching, we noticed that, even empty source map is specified, lldb-dap still tries to run it without any arguments which shows as following error in VSCode:

Setting source map:
(lldb) settings set target.source-map 
error: 'settings set' takes more arguments

This PR fixes the regression by detecting the mapping is empty and do not run the command. A test is added which fails before but passes with this PR.

@llvmbot
Copy link
Member

llvmbot commented Apr 28, 2025

@llvm/pr-subscribers-lldb

Author: None (jeffreytan81)

Changes

We have some lldb-dap clients that are specifying an empty source map during launching, we noticed that, even empty source map is specified, lldb-dap still tries to run it without any arguments which shows as following error in VSCode:

Setting source map:
(lldb) settings set target.source-map 
error: 'settings set' takes more arguments

This PR fixes the regression by detecting the mapping is empty and do not run the command. A test is added which fails before but passes with this PR.


Full diff: https://github.com/llvm/llvm-project/pull/137722.diff

3 Files Affected:

  • (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py (+1-1)
  • (modified) lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py (+17)
  • (modified) lldb/tools/lldb-dap/Handler/RequestHandler.cpp (+5-4)
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 a9915ba2f6de6..921bbc9b7200b 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
@@ -845,7 +845,7 @@ def request_launch(
             args_dict["debuggerRoot"] = debuggerRoot
         if launchCommands:
             args_dict["launchCommands"] = launchCommands
-        if sourceMap:
+        if sourceMap is not None: # sourceMap can be empty array.
             args_dict["sourceMap"] = sourceMap
         if runInTerminal:
             args_dict["runInTerminal"] = runInTerminal
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 1599ee5de7075..30a14caebb565 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -65,6 +65,23 @@ def test_stopOnEntry(self):
                         reason, "breakpoint", 'verify stop isn\'t "main" breakpoint'
                     )
 
+    def test_empty_sourceMap(self):
+        """
+        Tests the launch with empty source map should not issue source map command.
+        """
+        program = self.getBuildArtifact("a.out")
+        self.build_and_create_debug_adapter()
+        empty_source_map = []
+        self.launch(program, sourceMap=empty_source_map)
+        self.continue_to_exit()
+
+        # Now get the console output and verify no source map command was issued for empty source map.
+        console_output = self.get_console()
+        self.assertTrue(
+            console_output and len(console_output) > 0, "expect some console output"
+        )
+        self.assertNotIn("Setting source map:", console_output)
+
     def test_cwd(self):
         """
         Tests the default launch of a simple program with a current working
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
index 3520dc2c71a55..266146363b17c 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.cpp
@@ -56,9 +56,8 @@ void BaseRequestHandler::SetSourceMapFromArguments(
       "source must be be an array of two-element arrays, "
       "each containing a source and replacement path string.\n";
 
-  std::string sourceMapCommand;
-  llvm::raw_string_ostream strm(sourceMapCommand);
-  strm << "settings set target.source-map ";
+  std::string sourceMapCommandMappings;
+  llvm::raw_string_ostream strm(sourceMapCommandMappings);
   const auto sourcePath = GetString(arguments, "sourcePath").value_or("");
 
   // sourceMap is the new, more general form of sourcePath and overrides it.
@@ -93,7 +92,9 @@ void BaseRequestHandler::SetSourceMapFromArguments(
     // Do any source remapping needed before we create our targets
     strm << "\".\" \"" << sourcePath << "\"";
   }
-  if (!sourceMapCommand.empty()) {
+  if (!sourceMapCommandMappings.empty()) {
+    std::string sourceMapCommand = "settings set target.source-map ";
+    sourceMapCommand += sourceMapCommandMappings;
     dap.RunLLDBCommands("Setting source map:", {sourceMapCommand});
   }
 }

@jeffreytan81 jeffreytan81 force-pushed the fix_empty_source_map_error branch from 7df198a to 06307d4 Compare April 28, 2025 22:26
Copy link

⚠️ Python code formatter, darker found issues in your code. ⚠️

You can test this locally with the following command:
darker --check --diff -r HEAD~1...HEAD lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
View the diff from darker here.
--- packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py	2025-04-28 22:26:27.000000 +0000
+++ packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py	2025-04-28 22:28:46.790461 +0000
@@ -849,11 +849,11 @@
             args_dict["sourcePath"] = sourcePath
         if debuggerRoot:
             args_dict["debuggerRoot"] = debuggerRoot
         if launchCommands:
             args_dict["launchCommands"] = launchCommands
-        if sourceMap is not None: # sourceMap can be empty array.
+        if sourceMap is not None:  # sourceMap can be empty array.
             args_dict["sourceMap"] = sourceMap
         if runInTerminal:
             args_dict["runInTerminal"] = runInTerminal
         if postRunCommands:
             args_dict["postRunCommands"] = postRunCommands

Copy link
Contributor

@ashgti ashgti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also add a test for the attach request as well?

@@ -57,9 +57,8 @@ void BaseRequestHandler::SetSourceMapFromArguments(
"source must be be an array of two-element arrays, "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI, the launch command has been updated and is going through

void DAP::ConfigureSourceMaps() {
for setting the target.source-map value. I've been working on migrating the requests to not use raw json objects but I haven't updated the attach handler yet.

The test, as currently written, is not actually going to run this code. Its still good to have and check though.

Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGMT modulo nits

Comment on lines +60 to +61
std::string sourceMapCommandMappings;
llvm::raw_string_ostream strm(sourceMapCommandMappings);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::string sourceMapCommandMappings;
llvm::raw_string_ostream strm(sourceMapCommandMappings);
std::string source_map_command_mappings;
llvm::raw_string_ostream strm(source_map_command_mappings);

Comment on lines +96 to +98
if (!sourceMapCommandMappings.empty()) {
std::string sourceMapCommand = "settings set target.source-map ";
sourceMapCommand += sourceMapCommandMappings;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!sourceMapCommandMappings.empty()) {
std::string sourceMapCommand = "settings set target.source-map ";
sourceMapCommand += sourceMapCommandMappings;
if (!sourceMapCommandMappings.empty()) {
dap.RunLLDBCommands("Setting source map:", llvm::formatv("settings set target.source-map {0}", source_map_command_mappings));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants