55import typing as t
66
77import drgn
8+ from drgn import Architecture
89from drgn import FaultError
910from drgn import Object
1011from drgn import Program
@@ -159,6 +160,10 @@ def expand_traces(trace: drgn.StackTrace) -> t.List[drgn.StackTrace]:
159160 # We should continue appending traces so long as (a) we can find a pt_regs,
160161 # and (b) the stack pointer for that pt_regs is different than the stack
161162 # pointer for the current stack.
163+ #
164+ # NOTE: aarch64 does not guarantee having SP if we're unwinding with frame
165+ # pointers. However, trace[0] always has SP, because we generally have a
166+ # full register set to start the trace. Thus, this should be safe to test.
162167 while pt_regs is not None and pt_regs .sp .value_ () != trace [0 ].sp :
163168 # Interrupted user address.
164169 if (
@@ -288,9 +293,28 @@ def print_frames(
288293 :param start_idx: Where to start counting the frame indices from
289294 :param indent: How many spaces to indent the output
290295 """
296+ # On aarch64 without DWARF, it seems we're not guaranteed to have the stack
297+ # pointer, or the frame pointer. Fallback to FP, then NULL, here so we don't
298+ # crash during unwinds.
299+ if prog .platform .arch == Architecture .AARCH64 :
300+
301+ def get_sp (frame : drgn .StackFrame ) -> int :
302+ try :
303+ return frame .sp
304+ except LookupError :
305+ try :
306+ return frame .register ("fp" )
307+ except LookupError :
308+ return 0
309+
310+ else :
311+
312+ def get_sp (frame : drgn .StackFrame ) -> int :
313+ return frame .sp
314+
291315 pfx = " " * indent
292316 for i , frame in enumerate (trace ):
293- sp = frame . sp # drgn 0.0.22
317+ sp = get_sp ( frame )
294318 intr = "!" if frame .interrupted else " "
295319 try :
296320 pc = hex (frame .pc )
@@ -313,7 +337,7 @@ def print_frames(
313337 # with a different stack pointer than the previous. That is: only
314338 # when we reach the frame for a non-inline function. Also, only
315339 # output registers when we have show_vars=True.
316- if i == len (trace ) - 1 or trace [ i ]. sp != trace [i + 1 ]. sp :
340+ if i == len (trace ) - 1 or sp != get_sp ( trace [i + 1 ]) :
317341 registers = frame .registers ()
318342 regnames = list (registers .keys ())
319343 # This formats the registers in three columns.
0 commit comments