-
Notifications
You must be signed in to change notification settings - Fork 84
Allow GDB to unwind HardFault callstacks #131
Allow GDB to unwind HardFault callstacks #131
Conversation
When I currently request GDB to dump a hard fault stack, I see something like this: (gdb) bt #0 UserHardFault_ (ef=0x10001fb8) at /depots/cortex-m-rt/src/lib.rs:537 #1 0x08003fe6 in HardFault () Backtrace stopped: previous frame identical to this frame (corrupt stack?) GDB can't unwind past HardFault since the current implementation of this function overwrites the Link Register (LR) value. This change pushes LR and R0 (to maintain 8-byte stack alignment) to the stack before transferring execution to UserHardFault(). After this change, I see a callstack like this from GDB: (gdb) bt #0 UserHardFault_ (ef=0x10001fb0) at /depots/cortex-m-rt/src/lib.rs:537 #1 0x08003fe8 in HardFault () #2 <signal handler called> #3 0x08002820 in core::ptr::read_volatile (src=0x48001800) at libcore/ptr.rs:472 #4 0x080001a2 in main () at src/07-registers/src/main.rs:14 Notes: * This code uses 8 more stack bytes. * Increases the size of the HardFault handler by 2 narrow instructions or 4 bytes. This could be decreased to 2 bytes by removing the pop since UserHardFault() doesn't currently return but it just looks too odd for me to do as an initial attempt.
Oooh, having spent today doing a Rust workshop and regularly having to work out why I was in the fault handler, I approve of this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, too.
bors r+ |
131: Allow GDB to unwind HardFault callstacks r=therealprof a=adamgreen When I currently request GDB to dump a hard fault stack, I see something like this: ``` (gdb) bt #0 UserHardFault_ (ef=0x10001fb8) at /depots/cortex-m-rt/src/lib.rs:537 #1 0x08003fe6 in HardFault () Backtrace stopped: previous frame identical to this frame (corrupt stack?) ``` GDB can't unwind past HardFault since the current implementation of this function overwrites the Link Register (LR) value. This change pushes LR and R0 (to maintain 8-byte stack alignment) to the stack before transferring execution to UserHardFault(). After this change, I see a callstack like this from GDB: ``` (gdb) bt #0 UserHardFault_ (ef=0x10001fb0) at /depots/cortex-m-rt/src/lib.rs:537 #1 0x08003fe8 in HardFault () #2 <signal handler called> #3 0x08002820 in core::ptr::read_volatile (src=0x48001800) at libcore/ptr.rs:472 #4 0x080001a2 in main () at src/07-registers/src/main.rs:14 ``` Notes: * This code uses 8 more stack bytes. * Increases the size of the HardFault handler by 2 narrow instructions or 4 bytes. This could be decreased to 2 bytes by removing the pop since UserHardFault() doesn't currently return but it just looks too odd for me to do as an initial attempt. Co-authored-by: Adam Green <adamgreen@users.noreply.github.com>
Build succeeded |
This is great but I really don't think we need the |
When is the next release scheduled? I'd love to be able to tell my Rust embedded training workshop when they can get backtraces in fault handlers. |
I'd like to do one soon to get |
Thanks for reviewing and merging! Much appreciated! Some of my notes on debugging faults on Cortex-M devices with GDB:
|
@adamgreen I haven't had a chance to test yet but a couple of thoughts..
|
|
@adamgreen Thanks for fixing this! I was about to file an issue about this today :-).
Indeed that's the case. We had linker failures with
The Directly using If you directly use #[no_mangle]
fn UserHardFault(i_like_boxes: Box<i32>, and_vectors: Vec<i32>) -> ! { .. } and generate invalid references, types, etc. |
Cool! I will submit a PR today to remove the extraneous pop. Thanks again all for the feedback. |
132: Remove extraneous POP from my prev commit r=therealprof a=adamgreen Based on the great feedback to PR #131, I have removed the POP instruction that I added in my previous commit since UserHardFault never returns. Co-authored-by: Adam Green <adamgreen@users.noreply.github.com>
When I currently request GDB to dump a hard fault stack, I see
something like this:
GDB can't unwind past HardFault since the current implementation of
this function overwrites the Link Register (LR) value. This change
pushes LR and R0 (to maintain 8-byte stack alignment) to the stack
before transferring execution to UserHardFault().
After this change, I see a callstack like this from GDB:
Notes:
or 4 bytes. This could be decreased to 2 bytes by removing the pop
since UserHardFault() doesn't currently return but it just looks too
odd for me to do as an initial attempt.