Page MenuHomeFreeBSD

Allow the kernel to unwind past the stack frame
Needs ReviewPublic

Authored by andrew on Mar 30 2022, 1:49 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Apr 22, 6:48 AM
Unknown Object (File)
Feb 19 2024, 3:00 PM
Unknown Object (File)
Jan 10 2024, 8:13 PM
Unknown Object (File)
Dec 20 2023, 6:48 AM
Unknown Object (File)
Dec 13 2023, 8:06 AM
Unknown Object (File)
Nov 7 2023, 1:40 AM
Unknown Object (File)
Sep 15 2023, 11:32 AM
Unknown Object (File)
Aug 16 2023, 7:03 AM
Subscribers

Details

Reviewers
jrtc27
manu
Group Reviewers
arm64
Summary

In 05985a7 we stopped creating a stack frame in the exception handler.
This breaks the kernel unwinder for consumers other than ddb as they
now need special handling of the exception handlers.

Alternatively we could leave the frame pointer (x29) alone, however
that means we can't find the trap frame.

Re-add saving the frame pointer an link registers (return address)
until a better solution can be found.

As the stack frame is only needed while unwinding the stack check one
of the consumers of the unwinding code is enabled.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 44981
Build 41869: arc lint + arc unit

Event Timeline

We can find the trapframe, just find it from SP like riscv? Saving LR is wrong anyway, it's ELR you should be saving, but you also have no clue if they're in sync, it's just a mess. Better to do what amd64 and riscv do, i.e. delete the instruction and make a one-line change to DDB.

We don't have as you removed it because the logic to find it was incorrect in the general case.

I know lr is wrong, however if the exception occurs in a leaf function we are unable to unwind past it when using elr.

sys/arm64/arm64/exception.S
39

DDB itself doesn't need it (and doesn't want it, so we can be more precise)

58

Save xzr then instead of a bogus lr, maybe?

And maybe #if/#else it to do the full subtract in the stp so we don't pick up an extra instruction (which is particularly annoying in save_registers_head due to the 28 instruction limit), like you did downstream in CheriBSD (due to immediate issues?)?

FWIW, Linux saves xzr, xzr when coming from EL0 and x29, elr when coming from EL1.

I'm also not sure what you mean about not being able to unwind past leaf functions. Leaf functions are always problematic, but what PC you save doesn't affect how many frames you get, it just affects whether you miss the leaf function or its caller in the backtrace. For non-leaf functions LR is definitely wrong. ELR should be more useful as it is the right thing for non-leaf functions and for leaf functions gets the leaf function itself (but not its immediate caller) in the backtrace, rather than the caller of the leaf function.

  • Limit when EXTRA_FRAME_SPACE is non-zero
  • Store elr_el1 when entering from EL1
  • Store xzr for fp & lr when entering from EL0

I might be mis-remembering which unwinder didn't work when using the exception location rather than caller. One caused broke when it was wrong, possibly 32-bit arm.