Skip to content

Nested panics lead to infinite recursion in panic-rtt-target #60

@wisp3rwind

Description

@wisp3rwind

If a nested panic occurs while formatting a panic message, panic-rtt-target will be invoked recursively until it eventually overflows the stack. Consequently, it won't succeed to send any logging information over either defmt or other channels.

It would be great if the library could detect recursion and avoid the format call in that case, similar to how std does: https://doc.rust-lang.org/1.88.0/src/std/panicking.rs.html#806

Reproducer that panics on division by zero (tested on ESP32C3):

#![no_std]
#![no_main]

use defmt::info;
use esp_hal::{
    clock::CpuClock,
    delay::Delay,
};
use panic_rtt_target as _;

struct PanicsOnFormat {
    a: u32,
    b: u32,
}

impl core::fmt::Display for PanicsOnFormat {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "PanicsOnFormat({})", self.a / self.b)
    }
}

impl defmt::Format for PanicsOnFormat {
    fn format(&self, fmt: defmt::Formatter<'_>) {
        defmt::write!(fmt, "PanicsOnFormat({})", self.a / self.b);
    }
}

#[esp_hal::main]
fn main() -> ! {
    rtt_target::rtt_init_defmt!();

    let cpu_clock = CpuClock::max();
    let config = esp_hal::Config::default().with_cpu_clock(cpu_clock);
    let peripherals = esp_hal::init(config);

    let delay = Delay::new();

    loop {
        info!("Test");

        delay.delay_millis(500);

        // This will panic, but not succeed in printing any panic info via defmt
        info!("{}", PanicsOnFormat { a: 42, b: 0 });

        delay.delay_millis(500);
    }
}

EDIT: Actually, I think the nesting is not quite what I thought it was: This seems to end up recursing on the panic at

panic!("defmt logger taken reentrantly")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions