Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HardFault trampoline makes it difficult for probe-rs debugger to unwind past the exception handler. #514

Open
noppej opened this issue Mar 12, 2024 · 3 comments

Comments

@noppej
Copy link

noppej commented Mar 12, 2024

The HardFault trampoline overwrites the EXC_RETURN magic values when it writes to the lr register.

Currently, the probe-rs debugger relies on those magic values during stack unwinding, to identify exception handlers, and unwind the stack that caused the exception. For instance, it used to be possible to get a stack like this:

__cortex_m_rt_HardFault (/Users/jn/dev/debug/probe-rs-debugger-test/src/thumbv7em-none-eabihf/nRF52833_xxAA.rs:43)
"HardFault handler. Cause: Escalated BusFault (Precise data access error) at location: 0x3ffffffc." (Unknown Source:0)
div_half_u128 (/rustc/0ecbd0605770f45c9151715e66ba2b3cae367fcb/library/core/src/ptr/mod.rs:1636)
__cortex_m_rt_SysTick (/Users/jn/dev/debug/probe-rs-debugger-test/src/thumbv7em-none-eabihf/nRF52833_xxAA.rs:32)
__cortex_m_rt_SysTick_trampoline (/Users/jn/dev/debug/probe-rs-debugger-test/src/thumbv7em-none-eabihf/nRF52833_xxAA.rs:17)
"Systick handler." (Unknown Source:0)
__delay #[inline] (/Users/jn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cortex-m-0.7.7/asm/inline.rs:62)
delay (/Users/jn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cortex-m-0.7.7/src/asm.rs:29)
__cortex_m_rt_main (/Users/jn/dev/debug/probe-rs-debugger-test/src/thumbv7em-none-eabihf/nRF52833_xxAA.rs:85)
__cortex_m_rt_main (/Users/jn/dev/debug/probe-rs-debugger-test/src/thumbv7em-none-eabihf/nRF52833_xxAA.rs:62)

With the trampoline, the debugger has no way of knowing that it is an exception handler that needs register substitutions before the calling frames can be identified, and it stops unwinding at the first frame.

I've notice in the unreleased code, that users can bypass the trampoline, with#[exception(trampoline = false)], and this restores the previous behaviour of the stack unwind.

Unfortunately, this means that the users have to modify their code before they can use the debugger in these situations.

Is there any way we can make the default to be trampoline = false?

@adamgreig
Copy link
Member

I think there's fairly broad support for removing the trampline from cortex-m-rt, but we can't do it in the 0.7 series as it's a breaking change, and we're reluctant to release 0.8 because it massively fractures the ecosystem (every cortex-m PAC depends on cortex-m-rt 0.7, so the PACs have to update, and then the HALs on top of those have to update, etc).

I think the best option we have at the moment is to get the "trampolines are optional" change out in 0.7, then plan for 0.8 (or more likely 1.0) without the trampoline and with our other planned changes, including decoupling PACs from this crate a bit to make it easier to update later.

@noppej
Copy link
Author

noppej commented Mar 12, 2024

That seems like a sensible approach. In the mean time, I will add some docs for probe-rs to help users use the opt-out of trampoline. Thanks for the quick response.

@jonathanpallant
Copy link
Contributor

Disabling the trampoline means you no longer get the ef: &ExceptionFrame argument passed to the hard fault handler, right? Or I might be confused about how this works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants