Skip to content

Commit 0f9f57f

Browse files
author
Jeffrey Tan
committed
Fix lldb-dap non-leaf frame source resolution issue
1 parent 4ac74fc commit 0f9f57f

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -657,18 +657,31 @@ std::optional<protocol::Source> DAP::ResolveSource(const lldb::SBFrame &frame) {
657657
if (!frame.IsValid())
658658
return std::nullopt;
659659

660-
const lldb::SBAddress frame_pc = frame.GetPCAddress();
661-
if (DisplayAssemblySource(debugger, frame_pc))
660+
// IMPORTANT: Get line entry from symbol context, NOT from PC address.
661+
// When a frame's PC points to a return address (the instruction
662+
// after a call), that address may have line number 0 for compiler generated
663+
// code.
664+
//
665+
// EXAMPLE: If PC is at 0x1004 (frame return address after the call
666+
// instruction) with no line info, but 0x1003 (in the middle of previous call
667+
// instruction) is at line 42, symbol context returns line 42.
668+
//
669+
// NOTE: This issue is non-deterministic and depends on compiler debug info
670+
// generation, making it difficult to create a reliable automated test.
671+
const lldb::SBLineEntry frame_line_entry = frame.GetLineEntry();
672+
if (DisplayAssemblySource(debugger, frame_line_entry)) {
673+
const lldb::SBAddress frame_pc = frame.GetPCAddress();
662674
return ResolveAssemblySource(frame_pc);
675+
}
663676

664-
return CreateSource(frame.GetLineEntry().GetFileSpec());
677+
return CreateSource(frame_line_entry.GetFileSpec());
665678
}
666679

667680
std::optional<protocol::Source> DAP::ResolveSource(lldb::SBAddress address) {
668-
if (DisplayAssemblySource(debugger, address))
681+
lldb::SBLineEntry line_entry = GetLineEntryForAddress(target, address);
682+
if (DisplayAssemblySource(debugger, line_entry))
669683
return ResolveAssemblySource(address);
670684

671-
lldb::SBLineEntry line_entry = GetLineEntryForAddress(target, address);
672685
if (!line_entry.IsValid())
673686
return std::nullopt;
674687

lldb/tools/lldb-dap/ProtocolUtils.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ using namespace lldb_dap::protocol;
2727
namespace lldb_dap {
2828

2929
static bool ShouldDisplayAssemblySource(
30-
lldb::SBAddress address,
30+
lldb::SBLineEntry line_entry,
3131
lldb::StopDisassemblyType stop_disassembly_display) {
3232
if (stop_disassembly_display == lldb::eStopDisassemblyTypeNever)
3333
return false;
@@ -37,7 +37,6 @@ static bool ShouldDisplayAssemblySource(
3737

3838
// A line entry of 0 indicates the line is compiler generated i.e. no source
3939
// file is associated with the frame.
40-
auto line_entry = address.GetLineEntry();
4140
auto file_spec = line_entry.GetFileSpec();
4241
if (!file_spec.IsValid() || line_entry.GetLine() == 0 ||
4342
line_entry.GetLine() == LLDB_INVALID_LINE_NUMBER)
@@ -174,10 +173,10 @@ bool IsAssemblySource(const protocol::Source &source) {
174173
}
175174

176175
bool DisplayAssemblySource(lldb::SBDebugger &debugger,
177-
lldb::SBAddress address) {
176+
lldb::SBLineEntry line_entry) {
178177
const lldb::StopDisassemblyType stop_disassembly_display =
179178
GetStopDisassemblyDisplay(debugger);
180-
return ShouldDisplayAssemblySource(address, stop_disassembly_display);
179+
return ShouldDisplayAssemblySource(line_entry, stop_disassembly_display);
181180
}
182181

183182
std::string GetLoadAddressString(const lldb::addr_t addr) {

lldb/tools/lldb-dap/ProtocolUtils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ std::optional<protocol::Source> CreateSource(const lldb::SBFileSpec &file);
5353
/// Checks if the given source is for assembly code.
5454
bool IsAssemblySource(const protocol::Source &source);
5555

56-
bool DisplayAssemblySource(lldb::SBDebugger &debugger, lldb::SBAddress address);
56+
bool DisplayAssemblySource(lldb::SBDebugger &debugger,
57+
lldb::SBLineEntry line_entry);
5758

5859
/// Get the address as a 16-digit hex string, e.g. "0x0000000000012345"
5960
std::string GetLoadAddressString(const lldb::addr_t addr);

0 commit comments

Comments
 (0)