cargo-call-stack icon indicating copy to clipboard operation
cargo-call-stack copied to clipboard

Panic!() Function in Analyzed Code causes Assertion Errors in Cargo-Call-Stack

Open DrTobe opened this issue 4 years ago • 2 comments

When I was trying Cargo-Call-Stack in my project, it failed with the following error message:

...
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `56`,
 right: `52`: BUG: LLVM reported that `_ZN50_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$9write_fmt17h0763000cb7e29fb5E` uses 52 bytes of stack but this doesn't match our analysis', .../.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.4/src/main.rs:1001:29

I could narrow down this problem and found that it seems to be related to the panic-handler implementations that several crates offer for embedded development. Comparing the four options listed in the Embedded Rust Book, I got the results that I documented in the following example code:

#![no_main]
#![no_std]

use cortex_m_rt::entry;
extern crate nucleo_f401re;

use panic_semihosting as _; // cargo-call-stack assertion error
//use panic_itm as _;       // cargo-call-stack assertion error
//use panic_halt as _;      // OK
//use panic_abort as _;     // OK

#[entry]
fn main() -> ! {
    panic!("Test panic behavior.");
}

I do not know if there is a simple explanation why this has to fail there or if that is a bug, I just wanted to let you know. If you need further information, please let me know. If it is of any help, my current setup is:

  • rustc 1.45.0-nightly (769d12eec 2020-05-12) OR rustc 1.43.1 (8d69840ab 2020-05-04)
  • cargo 1.45.0-nightly (cb06cb269 2020-05-08) OR cargo 1.43.0 (2cbe9048e 2020-05-03)
  • cargo-call-stack 0.1.4

DrTobe avatar May 13 '20 08:05 DrTobe

This issue persists in the following setup:

  • rustc 1.46.0-nightly (0c03aee8b 2020-07-05)
  • cargo 1.46.0-nightly (fede83ccf 2020-07-02)
  • cargo-call-stack 0.1.5
  • build target: thumbv7em-none-eabihf.

JOE1994 avatar Jul 09 '20 20:07 JOE1994

Can confirm with

  • rustc 1.60.0-nightly (9ad5d82f8 2022-01-18)
  • cargo 1.60.0-nightly (358e79fe5 2022-01-04)
  • cargo-call-stack 0.1.6
  • build target: thumbv7em-none-eabihf
[2022-01-19T23:43:28Z WARN  cargo_call_stack] assuming that asm!("push {r4, lr}\0Asub sp, sp, #16\0Aadd r4, sp, #8\0Astr r4, [sp]\0Abl __udivmoddi4\0Aldr r2, [sp, #8]\0Aldr r3, [sp, #12]\0Aadd sp, sp, #16\0Apop {r4, pc}") does *not* use the stack in `__aeabi_uldivmod`
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `16`,
 right: `8`: BUG: LLVM reported that `_ZN4core9panicking9panic_str17hda8969b1b2a19f41E` uses 16 bytes of stack but this doesn't match our analysis', /home/jhbruhn/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.6/src/main.rs:851:29
stack backtrace:
   0: rust_begin_unwind
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/std/src/panicking.rs:515:5
   1: core::panicking::panic_fmt
             at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/panicking.rs:92:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
   4: cargo_call_stack::run
   5: cargo_call_stack::main

This happens in a setup similar to the one demonstrated in this issues description.

The panic handler:

#[inline(never)]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    static PANICKED: AtomicBool = AtomicBool::new(false);

    cortex_m::interrupt::disable();

    // Guard against infinite recursion, just in case.
    if PANICKED.load(Ordering::Relaxed) {
        loop {
            cortex_m::asm::bkpt();
        }
    }

    PANICKED.store(true, Ordering::Relaxed);

    // Trigger a `HardFault` via `udf` instruction.

    // If `UsageFault` is enabled, we disable that first, since otherwise `udf` will cause that
    // exception instead of `HardFault`.
    const SHCSR: *mut u32 = 0xE000ED24usize as _;
    const USGFAULTENA: usize = 18;

    unsafe {
        let mut shcsr = core::ptr::read_volatile(SHCSR);
        shcsr &= !(1 << USGFAULTENA);
        core::ptr::write_volatile(SHCSR, shcsr);
    }

    cortex_m::asm::udf();
}

jhbruhn avatar Jan 19 '22 23:01 jhbruhn

this report is pretty old but I cannot reproduce the problem with the given instructions. if you run into issues with the latest version of cargo-call-stack please open a new issue.

$ cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart --name app
$ cd app

$ rg '^target' .cargo/config.toml
37:target = "thumbv7em-none-eabihf"

$ cat src/main.rs
#![no_std]
#![no_main]

use panic_semihosting as _;

use cortex_m_rt::entry;
use nucleo_f401re as _;

#[entry]
fn main() -> ! {
    panic!("Test panic behavior.");
}
$ rg -A1 '^name = "panic-semihosting"' Cargo.lock
198:name = "panic-semihosting"
199-version = "0.6.0"

$ rg -A1 '^name = "nucleo-f401re"' Cargo.lock
180:name = "nucleo-f401re"
181-version = "0.4.1"

$ cargo call-stack --bin app > /tmp/cg.dot && echo OK
(..)
OK

$ cargo call-stack --version
cargo-call-stack 0.1.12

$ rustc -V
rustc 1.67.0-nightly (96ddd32c4 2022-11-14)

(image intentionally scaled down) out

japaric avatar Nov 15 '22 18:11 japaric