mib created this revision.
mib requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

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

Signed-off-by: Med Ismail Bennani <medismail.benn...@gmail.com>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115313

Files:
  lldb/source/Target/StackFrame.cpp
  lldb/test/API/source-manager/TestSourceManager.py
  lldb/test/API/source-manager/artificial_location.c


Index: lldb/test/API/source-manager/artificial_location.c
===================================================================
--- /dev/null
+++ lldb/test/API/source-manager/artificial_location.c
@@ -0,0 +1,8 @@
+int foo() {
+  return 42;
+}
+
+int main() {
+#line 0
+  return foo();
+}
Index: lldb/test/API/source-manager/TestSourceManager.py
===================================================================
--- lldb/test/API/source-manager/TestSourceManager.py
+++ 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,22 @@
                     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.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("run", RUN_SUCCEEDED,
+                    substrs=['stop reason = breakpoint', '%s:%d' % 
(src_file,0),
+                             'Warning: the current PC is an artificial',
+                             'location unassociated with a particular line in 
',
+                             src_file])
+
Index: lldb/source/Target/StackFrame.cpp
===================================================================
--- lldb/source/Target/StackFrame.cpp
+++ lldb/source/Target/StackFrame.cpp
@@ -1883,14 +1883,26 @@
       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.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 (!num_lines || !m_sc.line_entry.line ||
+              m_sc.line_entry.line == LLDB_INVALID_LINE_NUMBER) {
+            strm.Printf("Warning: the current PC is an artificial location "
+                        "unassociated with a particular line in %s.",
+                        m_sc.line_entry.file.GetFilename().GetCString());
+            strm.EOL();
+          }
         }
       }
       switch (disasm_display) {


Index: lldb/test/API/source-manager/artificial_location.c
===================================================================
--- /dev/null
+++ lldb/test/API/source-manager/artificial_location.c
@@ -0,0 +1,8 @@
+int foo() {
+  return 42;
+}
+
+int main() {
+#line 0
+  return foo();
+}
Index: lldb/test/API/source-manager/TestSourceManager.py
===================================================================
--- lldb/test/API/source-manager/TestSourceManager.py
+++ 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,22 @@
                     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.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("run", RUN_SUCCEEDED,
+                    substrs=['stop reason = breakpoint', '%s:%d' % (src_file,0),
+                             'Warning: the current PC is an artificial',
+                             'location unassociated with a particular line in ',
+                             src_file])
+
Index: lldb/source/Target/StackFrame.cpp
===================================================================
--- lldb/source/Target/StackFrame.cpp
+++ lldb/source/Target/StackFrame.cpp
@@ -1883,14 +1883,26 @@
       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.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 (!num_lines || !m_sc.line_entry.line ||
+              m_sc.line_entry.line == LLDB_INVALID_LINE_NUMBER) {
+            strm.Printf("Warning: the current PC is an artificial location "
+                        "unassociated with a particular line in %s.",
+                        m_sc.line_entry.file.GetFilename().GetCString());
+            strm.EOL();
+          }
         }
       }
       switch (disasm_display) {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to