https://github.com/ashgti created https://github.com/llvm/llvm-project/pull/128268
This adds 'source' references to all stack frames. When opening a stack frame users will see the disassembly of the frame if the source is not available. This works around the odd behavior of navigating frames without the VSCode disassembly view open, which causes 'step' to step in the first frame with a source instead of the active frame. This fixes #128260 Old behavior: https://github.com/user-attachments/assets/3f40582d-ac96-451a-a5ae-498a323bf30e New behavior: https://github.com/user-attachments/assets/3a3f9ac6-3e6c-4795-9bb2-1132b3916b6f >From 2f7885cfac5d5049c317de56109eed3bd2579acc Mon Sep 17 00:00:00 2001 From: John Harrison <harj...@google.com> Date: Fri, 21 Feb 2025 17:45:17 -0800 Subject: [PATCH] [lldb-dap] Add 'source' references to stack frames without source files. This adds 'source' references to all stack frames. When opening a stack frame users will see the disassembly of the frame if the source is not available. This works around the odd behavior of navigating frames without the VSCode disassembly view open, which causes 'step' to step in the first frame with a source instead of the active frame. --- lldb/tools/lldb-dap/JSONUtils.cpp | 38 +++++++++++++++++++------------ lldb/tools/lldb-dap/lldb-dap.cpp | 28 ++++++++++++++++++++--- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 6ca4dfb4711a1..ee8fcef6f2503 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -45,7 +45,6 @@ #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/raw_ostream.h" #include <chrono> -#include <climits> #include <cstddef> #include <iomanip> #include <optional> @@ -698,14 +697,22 @@ llvm::json::Value CreateSource(llvm::StringRef source_path) { return llvm::json::Value(std::move(source)); } -static std::optional<llvm::json::Value> CreateSource(lldb::SBFrame &frame) { +static llvm::json::Value CreateSource(lldb::SBFrame &frame, + llvm::StringRef frame_name) { auto line_entry = frame.GetLineEntry(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. if (line_entry.GetFileSpec().IsValid() && line_entry.GetLine() != 0) return CreateSource(line_entry); - return {}; + llvm::json::Object source; + EmplaceSafeString(source, "name", frame_name); + source.try_emplace("sourceReference", MakeDAPFrameID(frame)); + // If we don't have a filespec then we don't have the original source. Mark + // the source as deemphasized since users will only be able to view assembly + // for these frames. + EmplaceSafeString(source, "presentationHint", "deemphasize"); + return std::move(source); } // "StackFrame": { @@ -799,21 +806,22 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); - auto source = CreateSource(frame); - - if (source) { - object.try_emplace("source", *source); - auto line_entry = frame.GetLineEntry(); - auto line = line_entry.GetLine(); - if (line && line != LLDB_INVALID_LINE_NUMBER) - object.try_emplace("line", line); - else - object.try_emplace("line", 0); + object.try_emplace("source", CreateSource(frame, frame_name)); + auto line_entry = frame.GetLineEntry(); + if (line_entry.IsValid() && + (line_entry.GetLine() != 0 || + line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { + object.try_emplace("line", line_entry.GetLine()); auto column = line_entry.GetColumn(); object.try_emplace("column", column); } else { - object.try_emplace("line", 0); - object.try_emplace("column", 0); + lldb::addr_t inst_offset = frame.GetPCAddress().GetOffset() - + frame.GetSymbol().GetStartAddress().GetOffset(); + lldb::addr_t inst_line = + inst_offset / (frame.GetThread().GetProcess().GetAddressByteSize() / 2); + // lines are base-1 indexed + object.try_emplace("line", inst_line + 1); + object.try_emplace("column", 1); } const auto pc = frame.GetPC(); diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index e323990d8b6ed..1da8358eb5224 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -13,7 +13,9 @@ #include "RunInTerminal.h" #include "Watchpoint.h" #include "lldb/API/SBDeclaration.h" +#include "lldb/API/SBDefines.h" #include "lldb/API/SBEvent.h" +#include "lldb/API/SBFile.h" #include "lldb/API/SBInstruction.h" #include "lldb/API/SBListener.h" #include "lldb/API/SBMemoryRegionInfo.h" @@ -38,9 +40,6 @@ #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <array> -#include <cassert> -#include <climits> -#include <cstdarg> #include <cstdint> #include <cstdio> #include <cstdlib> @@ -3488,6 +3487,29 @@ void request_source(DAP &dap, const llvm::json::Object &request) { llvm::json::Object response; FillResponse(request, response); llvm::json::Object body{{"content", ""}}; + + const auto *arguments = request.getObject("arguments"); + const auto *source = arguments->getObject("source"); + int64_t source_ref = GetUnsigned( + source, "sourceReference", GetUnsigned(arguments, "sourceReference", 0)); + + lldb::SBProcess process = dap.target.GetProcess(); + // Upper 32 bits is the thread index ID + lldb::SBThread thread = + process.GetThreadByIndexID(GetLLDBThreadIndexID(source_ref)); + // Lower 32 bits is the frame index + lldb::SBFrame frame = thread.GetFrameAtIndex(GetLLDBFrameID(source_ref)); + if (!frame.IsValid()) { + response["success"] = false; + response["message"] = "source not found"; + } else { + lldb::SBInstructionList insts = frame.GetSymbol().GetInstructions(dap.target); + lldb::SBStream stream; + insts.GetDescription(stream); + body["content"] = stream.GetData(); + body["mimeType"] = "text/x-lldb.disassembly"; + } + response.try_emplace("body", std::move(body)); dap.SendJSON(llvm::json::Value(std::move(response))); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits