[Lldb-commits] [PATCH] D125042: have crashlog.py insert a stack frame with $lr when stack frame 0 is address 0

Jason Molenda via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Thu May 5 14:11:36 PDT 2022


jasonmolenda created this revision.
jasonmolenda added a reviewer: kastiglione.
jasonmolenda added a project: LLDB.
Herald added subscribers: JDevlieghere, kristof.beyls.
Herald added a project: All.
jasonmolenda requested review of this revision.
Herald added a subscriber: lldb-commits.

A common crash is calling through a null function pointer and trying to execute an instruction at address 0.  lldb's backtracer special cases this, but the macOS crash tracer algorithm does not; crash reports will have a stack frame at 0 and then skip the calling stack frame, assuming a stack frame was set up.  On arm64, the caller function is likely available in $lr, so let's insert a stack frame with that return pc value.

Also fix a little bug where register names without a "prefix" would get "None" prepended, so "Nonepc", "Nonelr" etc.

rdar://92631787


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125042

Files:
  lldb/examples/python/crashlog.py


Index: lldb/examples/python/crashlog.py
===================================================================
--- lldb/examples/python/crashlog.py
+++ lldb/examples/python/crashlog.py
@@ -516,6 +516,22 @@
             image_addr = self.get_used_image(image_id)['base']
             pc = image_addr + frame_offset
             thread.frames.append(self.crashlog.Frame(idx, pc, frame_offset))
+
+            # on arm64 systems, if jump through a null function pointer,
+            # we end up at address 0 and the crash reporter unwinder 
+            # misses the frame that actually faulted.  
+            # But $lr can tell us where the last BL/BLR instruction used 
+            # was at, so insert that address as the caller stack frame.  
+            if idx == 0 and pc == 0 and "lr" in thread.registers:
+                pc = thread.registers["lr"]
+                for image in self.data['usedImages']:
+                    text_lo = image['base']
+                    text_hi = text_lo + image['size']
+                    if text_lo <= pc < text_hi:
+                      idx += 1
+                      frame_offset = pc - text_lo
+                      thread.frames.append(self.crashlog.Frame(idx, pc, frame_offset))
+
             idx += 1
 
     def parse_threads(self, json_threads):
@@ -551,7 +567,7 @@
                 continue
             try:
                 value = int(state['value'])
-                registers["{}{}".format(prefix,key)] = value
+                registers["{}{}".format(prefix or '',key)] = value
             except (KeyError, ValueError, TypeError):
                 pass
         return registers


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D125042.427445.patch
Type: text/x-patch
Size: 1642 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220505/dde71dbf/attachment.bin>


More information about the lldb-commits mailing list