Skip to content

Commit 2f7885c

Browse files
committed
[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.
1 parent 79261d4 commit 2f7885c

File tree

2 files changed

+48
-18
lines changed

2 files changed

+48
-18
lines changed

lldb/tools/lldb-dap/JSONUtils.cpp

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
#include "llvm/Support/ScopedPrinter.h"
4646
#include "llvm/Support/raw_ostream.h"
4747
#include <chrono>
48-
#include <climits>
4948
#include <cstddef>
5049
#include <iomanip>
5150
#include <optional>
@@ -698,14 +697,22 @@ llvm::json::Value CreateSource(llvm::StringRef source_path) {
698697
return llvm::json::Value(std::move(source));
699698
}
700699

701-
static std::optional<llvm::json::Value> CreateSource(lldb::SBFrame &frame) {
700+
static llvm::json::Value CreateSource(lldb::SBFrame &frame,
701+
llvm::StringRef frame_name) {
702702
auto line_entry = frame.GetLineEntry();
703703
// A line entry of 0 indicates the line is compiler generated i.e. no source
704704
// file is associated with the frame.
705705
if (line_entry.GetFileSpec().IsValid() && line_entry.GetLine() != 0)
706706
return CreateSource(line_entry);
707707

708-
return {};
708+
llvm::json::Object source;
709+
EmplaceSafeString(source, "name", frame_name);
710+
source.try_emplace("sourceReference", MakeDAPFrameID(frame));
711+
// If we don't have a filespec then we don't have the original source. Mark
712+
// the source as deemphasized since users will only be able to view assembly
713+
// for these frames.
714+
EmplaceSafeString(source, "presentationHint", "deemphasize");
715+
return std::move(source);
709716
}
710717

711718
// "StackFrame": {
@@ -799,21 +806,22 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame,
799806

800807
EmplaceSafeString(object, "name", frame_name);
801808

802-
auto source = CreateSource(frame);
803-
804-
if (source) {
805-
object.try_emplace("source", *source);
806-
auto line_entry = frame.GetLineEntry();
807-
auto line = line_entry.GetLine();
808-
if (line && line != LLDB_INVALID_LINE_NUMBER)
809-
object.try_emplace("line", line);
810-
else
811-
object.try_emplace("line", 0);
809+
object.try_emplace("source", CreateSource(frame, frame_name));
810+
auto line_entry = frame.GetLineEntry();
811+
if (line_entry.IsValid() &&
812+
(line_entry.GetLine() != 0 ||
813+
line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) {
814+
object.try_emplace("line", line_entry.GetLine());
812815
auto column = line_entry.GetColumn();
813816
object.try_emplace("column", column);
814817
} else {
815-
object.try_emplace("line", 0);
816-
object.try_emplace("column", 0);
818+
lldb::addr_t inst_offset = frame.GetPCAddress().GetOffset() -
819+
frame.GetSymbol().GetStartAddress().GetOffset();
820+
lldb::addr_t inst_line =
821+
inst_offset / (frame.GetThread().GetProcess().GetAddressByteSize() / 2);
822+
// lines are base-1 indexed
823+
object.try_emplace("line", inst_line + 1);
824+
object.try_emplace("column", 1);
817825
}
818826

819827
const auto pc = frame.GetPC();

lldb/tools/lldb-dap/lldb-dap.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
#include "RunInTerminal.h"
1414
#include "Watchpoint.h"
1515
#include "lldb/API/SBDeclaration.h"
16+
#include "lldb/API/SBDefines.h"
1617
#include "lldb/API/SBEvent.h"
18+
#include "lldb/API/SBFile.h"
1719
#include "lldb/API/SBInstruction.h"
1820
#include "lldb/API/SBListener.h"
1921
#include "lldb/API/SBMemoryRegionInfo.h"
@@ -38,9 +40,6 @@
3840
#include "llvm/Support/raw_ostream.h"
3941
#include <algorithm>
4042
#include <array>
41-
#include <cassert>
42-
#include <climits>
43-
#include <cstdarg>
4443
#include <cstdint>
4544
#include <cstdio>
4645
#include <cstdlib>
@@ -3488,6 +3487,29 @@ void request_source(DAP &dap, const llvm::json::Object &request) {
34883487
llvm::json::Object response;
34893488
FillResponse(request, response);
34903489
llvm::json::Object body{{"content", ""}};
3490+
3491+
const auto *arguments = request.getObject("arguments");
3492+
const auto *source = arguments->getObject("source");
3493+
int64_t source_ref = GetUnsigned(
3494+
source, "sourceReference", GetUnsigned(arguments, "sourceReference", 0));
3495+
3496+
lldb::SBProcess process = dap.target.GetProcess();
3497+
// Upper 32 bits is the thread index ID
3498+
lldb::SBThread thread =
3499+
process.GetThreadByIndexID(GetLLDBThreadIndexID(source_ref));
3500+
// Lower 32 bits is the frame index
3501+
lldb::SBFrame frame = thread.GetFrameAtIndex(GetLLDBFrameID(source_ref));
3502+
if (!frame.IsValid()) {
3503+
response["success"] = false;
3504+
response["message"] = "source not found";
3505+
} else {
3506+
lldb::SBInstructionList insts = frame.GetSymbol().GetInstructions(dap.target);
3507+
lldb::SBStream stream;
3508+
insts.GetDescription(stream);
3509+
body["content"] = stream.GetData();
3510+
body["mimeType"] = "text/x-lldb.disassembly";
3511+
}
3512+
34913513
response.try_emplace("body", std::move(body));
34923514
dap.SendJSON(llvm::json::Value(std::move(response)));
34933515
}

0 commit comments

Comments
 (0)