[Lldb-commits] [lldb] edf410e - [lldb/Target] Slide source display for artificial locations at function start

Med Ismail Bennani via lldb-commits lldb-commits at lists.llvm.org
Wed Dec 8 15:28:12 PST 2021


Author: Med Ismail Bennani
Date: 2021-12-08T15:25:29-08:00
New Revision: edf410e48f5b5ec8e5f7b4cb6c9b578c1e0a067f

URL: https://github.com/llvm/llvm-project/commit/edf410e48f5b5ec8e5f7b4cb6c9b578c1e0a067f
DIFF: https://github.com/llvm/llvm-project/commit/edf410e48f5b5ec8e5f7b4cb6c9b578c1e0a067f.diff

LOG: [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 <medismail.bennani at gmail.com>

Added: 
    lldb/test/API/source-manager/artificial_location.c

Modified: 
    lldb/source/Target/StackFrame.cpp
    lldb/test/API/source-manager/TestSourceManager.py

Removed: 
    


################################################################################
diff  --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index cba51d266c5ba..8208288e15ef7 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1883,14 +1883,33 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
       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
index ba26e0e058ce6..15af2e46c29af 100644
--- a/lldb/test/API/source-manager/TestSourceManager.py
+++ b/lldb/test/API/source-manager/TestSourceManager.py
@@ -199,7 +199,6 @@ def test_modify_source_file_while_debugging(self):
             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 @@ def test_set_breakpoint_with_absolute_path(self):
                     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
index 0000000000000..e1edd8d56b1aa
--- /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();
+}


        


More information about the lldb-commits mailing list