Skip to content

Commit edf410e

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 cfd1d49 commit edf410e

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
@@ -1883,14 +1883,33 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
18831883
if (m_sc.comp_unit && m_sc.line_entry.IsValid()) {
18841884
have_debuginfo = true;
18851885
if (source_lines_before > 0 || source_lines_after > 0) {
1886+
uint32_t start_line = m_sc.line_entry.line;
1887+
if (!start_line && m_sc.function) {
1888+
FileSpec source_file;
1889+
m_sc.function->GetStartLineSourceInfo(source_file, start_line);
1890+
}
1891+
18861892
size_t num_lines =
18871893
target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
1888-
m_sc.line_entry.file, m_sc.line_entry.line,
1889-
m_sc.line_entry.column, source_lines_before,
1890-
source_lines_after, "->", &strm);
1894+
m_sc.line_entry.file, start_line, m_sc.line_entry.column,
1895+
source_lines_before, source_lines_after, "->", &strm);
18911896
if (num_lines != 0)
18921897
have_source = true;
18931898
// TODO: Give here a one time warning if source file is missing.
1899+
if (!m_sc.line_entry.line) {
1900+
ConstString fn_name = m_sc.GetFunctionName();
1901+
1902+
if (!fn_name.IsEmpty())
1903+
strm.Printf("Warning: the current PC is an artificial location "
1904+
"in function %s.",
1905+
fn_name.AsCString());
1906+
else
1907+
strm.Printf(
1908+
"Warning: the current PC is an artificial location "
1909+
"but lldb couldn't associate it with a function in %s.",
1910+
m_sc.line_entry.file.GetFilename().GetCString());
1911+
strm.EOL();
1912+
}
18941913
}
18951914
}
18961915
switch (disasm_display) {

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

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

202-
203202
# The '-b' option shows the line table locations from the debug information
204203
# that indicates valid places to set source level breakpoints.
205204

@@ -265,3 +264,19 @@ def test_set_breakpoint_with_absolute_path(self):
265264
substrs=['stopped',
266265
'main-copy.c:%d' % self.line,
267266
'stop reason = breakpoint'])
267+
268+
def test_artificial_source_location(self):
269+
src_file = 'artificial_location.c'
270+
d = {'C_SOURCES': src_file }
271+
self.build(dictionary=d)
272+
273+
lldbutil.run_to_source_breakpoint(
274+
self, 'main',
275+
lldb.SBFileSpec(src_file, False))
276+
277+
self.expect("run", RUN_SUCCEEDED,
278+
substrs=['stop reason = breakpoint', '%s:%d' % (src_file,0),
279+
'Warning: the current PC is an artificial ',
280+
'location in function '
281+
])
282+
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)