https://github.com/eronnen updated 
https://github.com/llvm/llvm-project/pull/136777

>From e513345b74d5dac5b80fcddebcd52ff1aa2ea4dd Mon Sep 17 00:00:00 2001
From: Ely Ronnen <elyron...@gmail.com>
Date: Wed, 23 Apr 2025 00:06:28 +0200
Subject: [PATCH] [lldb-dap] handle stack frames without a module

---
 .../lldb-dap/stackTraceMissingModule/Makefile |  2 +
 .../TestDAP_stackTraceMissingModule.py        | 54 +++++++++++++++++++
 .../lldb-dap/stackTraceMissingModule/main.c   | 37 +++++++++++++
 .../lldb-dap/Handler/SourceRequestHandler.cpp | 14 ++++-
 lldb/tools/lldb-dap/JSONUtils.cpp             | 10 ++++
 5 files changed, 115 insertions(+), 2 deletions(-)
 create mode 100644 
lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile
 create mode 100644 
lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py
 create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c

diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile 
b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile
new file mode 100644
index 0000000000000..c9319d6e6888a
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile
@@ -0,0 +1,2 @@
+C_SOURCES := main.c
+include Makefile.rules
diff --git 
a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py
 
b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py
new file mode 100644
index 0000000000000..1eb00f9935a22
--- /dev/null
+++ 
b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py
@@ -0,0 +1,54 @@
+"""
+Test lldb-dap stack trace when module is missing
+"""
+
+from lldbsuite.test.decorators import skipUnlessPlatform
+from lldbsuite.test.lldbtest import line_number
+import lldbdap_testcase
+import re
+
+
+class TestDAP_stackTraceMissingModule(lldbdap_testcase.DAPTestCaseBase):
+    @skipUnlessPlatform(["linux"])
+    def test_missingModule(self):
+        """
+        Test that the stack frame without a module still has assembly source.
+        """
+        program = self.getBuildArtifact("a.out")
+        self.build_and_launch(program, commandEscapePrefix="")
+
+        source = "main.c"
+        self.set_source_breakpoints(
+            source,
+            [line_number(source, "// Break here")],
+        )
+        self.continue_to_next_stop()
+
+        # Evaluate expr -- func
+        expr_result = self.dap_server.request_evaluate(
+            expression="expr -f pointer -- func",
+            context="repl",
+        )
+
+        expr_result_address = re.search(
+            r"0x[0-9a-fA-F]+", expr_result["body"]["result"]
+        )
+        self.assertIsNotNone(
+            expr_result_address, "Failed to get address of dynamic allocated 
func"
+        )
+        func_address = expr_result_address.group(0)
+
+        self.dap_server.request_evaluate(
+            expression=f"breakpoint set --address {func_address}",
+            context="repl",
+        )
+
+        self.continue_to_next_stop()
+
+        frame_without_module = self.get_stackFrames()[0]
+
+        self.assertIn("line", frame_without_module, "Line number missing.")
+        self.assertIn("column", frame_without_module, "Column number missing.")
+        self.assertIn("source", frame_without_module, "Source location 
missing.")
+        source = frame_without_module["source"]
+        self.assertIn("sourceReference", source, "Source reference missing.")
diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c 
b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c
new file mode 100644
index 0000000000000..d706231fbd5c2
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c
@@ -0,0 +1,37 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+extern uint8_t __start_target_section[];
+extern uint8_t __stop_target_section[];
+
+__attribute__((used, section("target_section"))) int target_function(void) {
+  return 42;
+}
+
+typedef int (*target_function_t)(void);
+
+int main(void) {
+  size_t target_function_size = __stop_target_section - __start_target_section;
+  size_t page_size = sysconf(_SC_PAGESIZE);
+  size_t page_aligned_size =
+      (target_function_size + page_size - 1) & ~(page_size - 1);
+
+  void *executable_memory =
+      mmap(NULL, page_aligned_size, PROT_READ | PROT_WRITE | PROT_EXEC,
+           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (executable_memory == MAP_FAILED) {
+    perror("mmap");
+    return 1;
+  }
+
+  memcpy(executable_memory, __start_target_section, target_function_size);
+
+  target_function_t func = (target_function_t)executable_memory;
+  int result = func(); // Break here
+  printf("Result from target function: %d\n", result);
+
+  return 0;
+}
diff --git a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp
index 327198bab0395..fa80eb10877bf 100644
--- a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp
@@ -16,6 +16,7 @@
 #include "lldb/API/SBInstructionList.h"
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBStream.h"
+#include "lldb/API/SBSymbol.h"
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBThread.h"
 #include "llvm/Support/Error.h"
@@ -42,10 +43,19 @@ SourceRequestHandler::Run(const protocol::SourceArguments 
&args) const {
   if (!frame.IsValid())
     return llvm::make_error<DAPError>("source not found");
 
-  lldb::SBInstructionList insts = 
frame.GetSymbol().GetInstructions(dap.target);
   lldb::SBStream stream;
   lldb::SBExecutionContext exe_ctx(frame);
-  insts.GetDescription(stream, exe_ctx);
+  lldb::SBSymbol symbol = frame.GetSymbol();
+
+  if (symbol.IsValid()) {
+    lldb::SBInstructionList insts = symbol.GetInstructions(dap.target);
+    insts.GetDescription(stream, exe_ctx);
+  } else {
+    // No valid symbol, just return the disassembly
+    lldb::SBInstructionList insts =
+        dap.target.ReadInstructions(frame.GetPCAddress(), 32);
+    insts.GetDescription(stream, exe_ctx);
+  }
 
   return protocol::SourceResponseBody{/*content=*/stream.GetData(),
                                       /*mimeType=*/"text/x-lldb.disassembly"};
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 33f10c93d2ada..30d277abce11e 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -783,6 +783,16 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame,
     // Line numbers are 1-based.
     object.try_emplace("line", inst_line + 1);
     object.try_emplace("column", 1);
+  } else {
+    // No valid line entry or symbol
+    llvm::json::Object source;
+    EmplaceSafeString(source, "name", frame_name);
+    source.try_emplace("sourceReference", MakeDAPFrameID(frame));
+    EmplaceSafeString(source, "presentationHint", "deemphasize");
+    object.try_emplace("source", std::move(source));
+
+    object.try_emplace("line", 1);
+    object.try_emplace("column", 1);
   }
 
   const auto pc = frame.GetPC();

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to