knurling-rs / probe-run

Run embedded programs just like native ones
Apache License 2.0
645 stars 75 forks source link

unwind: skip FDEs with initial address of 0 #287

Closed jonas-schievink closed 2 years ago

jonas-schievink commented 2 years ago

The panic example in the app-template can cause a broken backtrace like this:

stack backtrace:
   0: 0x00001450 @ HardFaultTrampoline
      <exception entry>
   1: 0x000008d4 @ lib::inline::__udf
        at ./asm/inline.rs:172:5
   2: 0x000008d4 @ __udf
        at ./asm/lib.rs:49:17
   3: 0x000001ba @ cortex_m::asm::udf
        at [...]/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.7.3/src/asm.rs:43:5
   4: 0x000001c4 @ _defmt_panic
        at [...]/src/lib.rs:13:5
   5: 0x000001b0 @ defmt::export::panic
        at [...]/.cargo/registry/src/github.com-1ecc6299db9ec823/defmt-0.3.0/src/export/mod.rs:125:14
   6: 0x000001b0 @ panic::__cortex_m_rt_main
        at [...]/src/bin/panic.rs:10:5
   7: 0x00000168 @ main
        at [...]/src/bin/panic.rs:6:1
   8: 0x00000144 @ Reset
   9: 0x00000100 @ Reset
  10: 0x52205244 @ __sheap

This appeared to have a different cause from https://github.com/knurling-rs/probe-run/issues/277, since the fix for that didn't fix the backtrace here.

After a lot of investigation, it turned out that what was going on is that there are multiple frame description entries (FDEs) in the debuginfo that claim to apply to some addresses, and we happened to pick the wrong one while unwinding from Reset in frame 8, causing us to restore registers incorrectly and then attempting to jump to a nonsense address.

This seems to be limited to FDEs describing presumably dead code, whose base address gets reset to 0 when they're included in the final ELF, so this PR fixes it by ignoring any FDEs that claim to apply to address 0.

jonathanpallant commented 2 years ago

bors r+

bors[bot] commented 2 years ago

Build succeeded: