diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -1883,14 +1883,33 @@ if (m_sc.comp_unit && m_sc.line_entry.IsValid()) { have_debuginfo = true; if (source_lines_before > 0 || source_lines_after > 0) { + uint32_t start_line = m_sc.line_entry.line; + if (!start_line && m_sc.function) { + FileSpec source_file; + m_sc.function->GetStartLineSourceInfo(source_file, start_line); + } + size_t num_lines = target->GetSourceManager().DisplaySourceLinesWithLineNumbers( - m_sc.line_entry.file, m_sc.line_entry.line, - m_sc.line_entry.column, source_lines_before, - source_lines_after, "->", &strm); + m_sc.line_entry.file, start_line, m_sc.line_entry.column, + source_lines_before, source_lines_after, "->", &strm); if (num_lines != 0) have_source = true; // TODO: Give here a one time warning if source file is missing. + if (!m_sc.line_entry.line) { + ConstString fn_name = m_sc.GetFunctionName(); + + if (!fn_name.IsEmpty()) + strm.Printf("Warning: the current PC is an artificial location " + "in function %s.", + fn_name.AsCString()); + else + strm.Printf( + "Warning: the current PC is an artificial location " + "but lldb couldn't associate it with a function in %s.", + m_sc.line_entry.file.GetFilename().GetCString()); + strm.EOL(); + } } } switch (disasm_display) { diff --git a/lldb/test/API/source-manager/TestSourceManager.py b/lldb/test/API/source-manager/TestSourceManager.py --- a/lldb/test/API/source-manager/TestSourceManager.py +++ b/lldb/test/API/source-manager/TestSourceManager.py @@ -199,7 +199,6 @@ SOURCE_DISPLAYED_CORRECTLY, substrs=['Hello world']) - # The '-b' option shows the line table locations from the debug information # that indicates valid places to set source level breakpoints. @@ -265,3 +264,19 @@ substrs=['stopped', 'main-copy.c:%d' % self.line, 'stop reason = breakpoint']) + + def test_artificial_source_location(self): + src_file = 'artificial_location.c' + d = {'C_SOURCES': src_file } + self.build(dictionary=d) + + lldbutil.run_to_source_breakpoint( + self, 'main', + lldb.SBFileSpec(src_file, False)) + + self.expect("run", RUN_SUCCEEDED, + substrs=['stop reason = breakpoint', '%s:%d' % (src_file,0), + 'Warning: the current PC is an artificial ', + 'location in function ' + ]) + diff --git a/lldb/test/API/source-manager/artificial_location.c b/lldb/test/API/source-manager/artificial_location.c new file mode 100644 --- /dev/null +++ b/lldb/test/API/source-manager/artificial_location.c @@ -0,0 +1,6 @@ +int foo() { return 42; } + +int main() { +#line 0 + return foo(); +}