[Lldb-commits] [lldb] [lldb-dap] Allow empty memory reference in disassemble arguments (PR #162517)

Sergei Druzhkov via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 10 04:46:45 PDT 2025


https://github.com/DrSergei updated https://github.com/llvm/llvm-project/pull/162517

>From 3d548533d38277eb2ba59c810f7634909bb7adbd Mon Sep 17 00:00:00 2001
From: Druzhkov Sergei <serzhdruzhok at gmail.com>
Date: Wed, 8 Oct 2025 11:38:55 +0300
Subject: [PATCH 1/2] [lldb-dap] Allow empty memory reference in disassemble
 arguments

---
 .../disassemble/TestDAP_disassemble.py        | 22 +++++++++++++++++++
 .../Handler/DisassembleRequestHandler.cpp     |  5 +++++
 lldb/tools/lldb-dap/JSONUtils.cpp             |  7 +++++-
 lldb/tools/lldb-dap/JSONUtils.h               |  5 ++++-
 .../lldb-dap/Protocol/ProtocolRequests.cpp    |  2 +-
 5 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
index 0562f20335a23..6c41c86ff9ae5 100644
--- a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
+++ b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py
@@ -91,3 +91,25 @@ def test_disassemble_backwards(self):
         # clear breakpoints
         self.set_source_breakpoints(source, [])
         self.continue_to_exit()
+
+    def test_disassemble_empty_memory_reference(self):
+        """
+        Tests the 'disassemble' request with empty memory reference.
+        """
+        program = self.getBuildArtifact("a.out")
+        self.build_and_launch(program)
+        source = "main.c"
+        bp_line_no = line_number(source, "// breakpoint 1")
+        self.set_source_breakpoints(source, [bp_line_no])
+        self.continue_to_next_stop()
+
+        instructions = self.dap_server.request_disassemble(
+            memoryReference="", instructionOffset=0, instructionCount=50
+        )
+        self.assertEqual(len(instructions), 50)
+        for instruction in instructions:
+            self.assertEqual(instruction["presentationHint"], "invalid")
+
+        # clear breakpoints
+        self.set_source_breakpoints(source, [])
+        self.continue_to_exit()
diff --git a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
index 9542f091b055e..6d2eb74a9634c 100644
--- a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp
@@ -182,6 +182,11 @@ static DisassembledInstruction ConvertSBInstructionToDisassembledInstruction(
 /// `supportsDisassembleRequest` is true.
 llvm::Expected<DisassembleResponseBody>
 DisassembleRequestHandler::Run(const DisassembleArguments &args) const {
+  if (args.memoryReference == LLDB_INVALID_ADDRESS) {
+    std::vector<DisassembledInstruction> invalid_instructions(
+        args.instructionCount, GetInvalidInstruction());
+    return DisassembleResponseBody{std::move(invalid_instructions)};
+  }
   const lldb::addr_t addr_ptr = args.memoryReference + args.offset;
   lldb::SBAddress addr(addr_ptr, dap.target);
   if (!addr.IsValid())
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp
index 4f26599a49bac..c00e39c86b92a 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -122,7 +122,7 @@ DecodeMemoryReference(llvm::StringRef memoryReference) {
 
 bool DecodeMemoryReference(const llvm::json::Value &v, llvm::StringLiteral key,
                            lldb::addr_t &out, llvm::json::Path path,
-                           bool required) {
+                           bool required, bool allow_empty) {
   const llvm::json::Object *v_obj = v.getAsObject();
   if (!v_obj) {
     path.report("expected object");
@@ -145,6 +145,11 @@ bool DecodeMemoryReference(const llvm::json::Value &v, llvm::StringLiteral key,
     return false;
   }
 
+  if (allow_empty && mem_ref_str->empty()) {
+    out = LLDB_INVALID_ADDRESS;
+    return true;
+  }
+
   const std::optional<lldb::addr_t> addr_opt =
       DecodeMemoryReference(*mem_ref_str);
   if (!addr_opt) {
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index e9094f67b94ec..b8187fe988350 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -156,11 +156,14 @@ DecodeMemoryReference(llvm::StringRef memoryReference);
 ///    Indicates if the key is required to be present, otherwise report an error
 ///    if the key is missing.
 ///
+/// \param[in] allow_empty
+///    Interpret empty string as a valid value, don't report an error.
+///
 /// \return
 ///    Returns \b true if the address was decoded successfully.
 bool DecodeMemoryReference(const llvm::json::Value &v, llvm::StringLiteral key,
                            lldb::addr_t &out, llvm::json::Path path,
-                           bool required);
+                           bool required, bool allow_empty = false);
 
 /// Extract an array of strings for the specified key from an object.
 ///
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index b455112cd37d9..fc046d18825ec 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
@@ -511,7 +511,7 @@ bool fromJSON(const llvm::json::Value &Params, DisassembleArguments &DA,
   json::ObjectMapper O(Params, P);
   return O &&
          DecodeMemoryReference(Params, "memoryReference", DA.memoryReference, P,
-                               /*required=*/true) &&
+                               /*required=*/true, /*allow_empty*/ true) &&
          O.mapOptional("offset", DA.offset) &&
          O.mapOptional("instructionOffset", DA.instructionOffset) &&
          O.map("instructionCount", DA.instructionCount) &&

>From dd76a75cc25d70078fdce1a995a9ae5d55597298 Mon Sep 17 00:00:00 2001
From: Druzhkov Sergei <serzhdruzhok at gmail.com>
Date: Fri, 10 Oct 2025 14:31:47 +0300
Subject: [PATCH 2/2] Fix review comments

---
 lldb/tools/lldb-dap/JSONUtils.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index b8187fe988350..cbfb35b942a5d 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -157,7 +157,8 @@ DecodeMemoryReference(llvm::StringRef memoryReference);
 ///    if the key is missing.
 ///
 /// \param[in] allow_empty
-///    Interpret empty string as a valid value, don't report an error.
+///    Interpret empty string as a valid value, don't report an error (see
+///    VSCode issue https://github.com/microsoft/vscode/issues/270593).
 ///
 /// \return
 ///    Returns \b true if the address was decoded successfully.



More information about the lldb-commits mailing list