Skip to content

Commit edaae28

Browse files
committed
[lldb/Target] Slide source display for artificial locations at function start
It can happen that a line entry reports that some source code is located at line 0. In DWARF, line 0 is a special location which indicates that code has no 1-1 mapping with source. When stopping in one of those artificial locations, lldb doesn't know which line to display and shows the beginning of the file instead. This patch mitigates this behaviour by checking if the current symbol context of the line entry has a matching function, in which case, it slides the source listing to the start of that function. This patch also shows the user a warning explaining why lldb couldn't show sources at that location. rdar://83118425 Differential Revision: https://reviews.llvm.org/D115313 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 54ffcc9 commit edaae28

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

lldb/source/Target/StackFrame.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,14 +1892,33 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
18921892
if (m_sc.comp_unit && m_sc.line_entry.IsValid()) {
18931893
have_debuginfo = true;
18941894
if (source_lines_before > 0 || source_lines_after > 0) {
1895+
uint32_t start_line = m_sc.line_entry.line;
1896+
if (!start_line && m_sc.function) {
1897+
FileSpec source_file;
1898+
m_sc.function->GetStartLineSourceInfo(source_file, start_line);
1899+
}
1900+
18951901
size_t num_lines =
18961902
target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
1897-
m_sc.line_entry.file, m_sc.line_entry.line,
1898-
m_sc.line_entry.column, source_lines_before,
1899-
source_lines_after, "->", &strm);
1903+
m_sc.line_entry.file, start_line, m_sc.line_entry.column,
1904+
source_lines_before, source_lines_after, "->", &strm);
19001905
if (num_lines != 0)
19011906
have_source = true;
19021907
// TODO: Give here a one time warning if source file is missing.
1908+
if (!m_sc.line_entry.line) {
1909+
ConstString fn_name = m_sc.GetFunctionName();
1910+
1911+
if (!fn_name.IsEmpty())
1912+
strm.Printf("Warning: the current PC is an artificial location "
1913+
"in function %s.",
1914+
fn_name.AsCString());
1915+
else
1916+
strm.Printf(
1917+
"Warning: the current PC is an artificial location "
1918+
"but lldb couldn't associate it with a function in %s.",
1919+
m_sc.line_entry.file.GetFilename().GetCString());
1920+
strm.EOL();
1921+
}
19031922
}
19041923
}
19051924
switch (disasm_display) {

lldb/test/API/source-manager/TestSourceManager.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ def test_modify_source_file_while_debugging(self):
204204
SOURCE_DISPLAYED_CORRECTLY,
205205
substrs=['Hello world'])
206206

207-
208207
# The '-b' option shows the line table locations from the debug information
209208
# that indicates valid places to set source level breakpoints.
210209

@@ -270,3 +269,19 @@ def test_set_breakpoint_with_absolute_path(self):
270269
substrs=['stopped',
271270
'main-copy.c:%d' % self.line,
272271
'stop reason = breakpoint'])
272+
273+
def test_artificial_source_location(self):
274+
src_file = 'artificial_location.c'
275+
d = {'C_SOURCES': src_file }
276+
self.build(dictionary=d)
277+
278+
lldbutil.run_to_source_breakpoint(
279+
self, 'main',
280+
lldb.SBFileSpec(src_file, False))
281+
282+
self.expect("run", RUN_SUCCEEDED,
283+
substrs=['stop reason = breakpoint', '%s:%d' % (src_file,0),
284+
'Warning: the current PC is an artificial ',
285+
'location in function '
286+
])
287+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
int foo() { return 42; }
2+
3+
int main() {
4+
#line 0
5+
return foo();
6+
}

0 commit comments

Comments
 (0)