[Lldb-commits] [PATCH] D136207: [lldb] Fix breakpoint setting so it always works when there is a line entry in a compile unit's line table.

Greg Clayton via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Tue Oct 18 16:24:26 PDT 2022


clayborg updated this revision to Diff 468737.
clayborg added a comment.

Added missing test case file and clarified comments to be more consistent.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D136207/new/

https://reviews.llvm.org/D136207

Files:
  lldb/source/Symbol/CompileUnit.cpp
  lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py


Index: lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
===================================================================
--- lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
+++ lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
@@ -106,6 +106,44 @@
                 'Incorrectly resolved a breakpoint using full path "%s" with '
                 'debug info that has relative path with matching suffix' % (path))
 
+    @skipIf(oslist=["windows"])
+    @no_debug_info_test
+    def test_breakpoints_with_bad_aranges(self):
+        """
+            Test that we can set breakpoints in a file that has an invalid
+            .debug_aranges. Older versions of LLDB would find a line entry
+            in the line table and then would use the start address of the line
+            entry to do an address lookup on the entry from the line table. If
+            this address to symbol context lookup would fail, due to a bad
+            .debug_aranges, it would cause the breakpoint to not get resolved.
+            Verify that even in these conditions we are able to resolve a
+            breakpoint.
+
+            The "bad_aranges.yaml" contains a line table that is:
+
+            Line table for /tmp/ab/main.cpp in `a.out
+            0x0000000100003f94: /tmp/ab/main.cpp:1
+            0x0000000100003fb0: /tmp/ab/main.cpp:2:3
+            0x0000000100003fb8: /tmp/ab/main.cpp:2:3
+
+            The .debug_aranges has one range for this compile unit that is
+            invalid: [0x0000000200003f94-0x0000000200003fb8). This will cause
+            the resolving of the addresses to fail.
+        """
+        src_dir = self.getSourceDir()
+        yaml_path = os.path.join(src_dir, "bad_aranges.yaml")
+        yaml_base, ext = os.path.splitext(yaml_path)
+        obj_path = self.getBuildArtifact("a.out")
+        self.yaml2obj(yaml_path, obj_path)
+
+        # Create a target with the object file we just created from YAML
+        target = self.dbg.CreateTarget(obj_path)
+        src_path = '/tmp/ab/main.cpp'
+        bkpt = target.BreakpointCreateByLocation(src_path, 2)
+        self.assertTrue(bkpt.GetNumLocations() > 0,
+            'Couldn\'t resolve breakpoint using "%s" in executate "%s" with '
+            'debug info that has a bad .debug_aranges section' % (src_path, self.getBuildArtifact("a.out")))
+
 
     def setUp(self):
         # Call super's setUp().
Index: lldb/source/Symbol/CompileUnit.cpp
===================================================================
--- lldb/source/Symbol/CompileUnit.cpp
+++ lldb/source/Symbol/CompileUnit.cpp
@@ -335,6 +335,37 @@
     } else {
       line_entry.range.GetBaseAddress().CalculateSymbolContext(&sc,
                                                                resolve_scope);
+      // Sometimes debug info is bad and isn't able to resolve the line entry's
+      // address back to the same compile unit and/or line entry. If the compile
+      // unit changed, then revert back to just the compile unit and line entry.
+      // Prior to this fix, the above code might end up not being able to lookup
+      // the address, and then it would clear compile unit and the line entry in
+      // the symbol context and the breakpoint would fail to get set even though
+      // we have a valid line table entry in this compile unit. The address
+      // lookup can also end up finding another function in another compiler
+      // unit if the DWARF has overlappging address ranges. So if we end up with
+      // no compile unit or a different one after the above function call,
+      // revert back to the same results as if resolve_scope was set exactly to
+      // eSymbolContextLineEntry.
+      if (sc.comp_unit != this) {
+        if (sc.comp_unit == nullptr && sc.module_sp) {
+          // Only report an error if we don't map back to any compile unit. With
+          // link time optimizations, the debug info might have many compile
+          // units that have the same address range due to function outlining
+          // or other link time optimizations. If the compile unit is NULL, then
+          // address resolving is completely failing and more deserving of an
+          // error message the user can see.
+          sc.module_sp->ReportError(
+              "unable to resolve a line table file address 0x%" PRIx64 " back "
+              "to a compile unit, please file a bug and attach the address "
+              "and file.", line_entry.range.GetBaseAddress().GetFileAddress());
+        }
+        // Revert to equivalent of resolve_scope == eSymbolContextLineEntry.
+        sc.comp_unit = this;
+        sc.function = nullptr;
+        sc.block = nullptr;
+        sc.line_entry = line_entry;
+      }
     }
 
     sc_list.Append(sc);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D136207.468737.patch
Type: text/x-patch
Size: 4870 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20221018/b68b22f3/attachment-0001.bin>


More information about the lldb-commits mailing list