## #[panic_handler]

`#[panic_handler]` is used to define the behavior of `panic!` in `#![no_std]` applications. The `#[panic_handler]` attribute must be applied to a function with signature `fn(&PanicInfo) -> !` and such function must appear once in the dependency graph of a binary / dylib / cdylib crate. The API of `PanicInfo` can be found in the API docs.

Given that `#![no_std]` applications have no standard output and that some `#![no_std]` applications, e.g. embedded applications, need different panicking behaviors for development and for release it can be helpful to have panic crates, crate that only contain a `#[panic_handler]`. This way applications can easily swap the panicking behavior by simply linking to a different panic crate.

Below is shown an example where an application has a different panicking behavior depending on whether is compiled using the dev profile (`cargo build`) or using the release profile (`cargo build --release`).

    // crate: panic-semihosting -- log panic messages to the host stderr using semihosting

    #![no_std]

    use core::fmt::{Write, self};
    use core::panic::PanicInfo;

    struct HStderr {
        // ..
        _0: (),
    }

    impl HStderr {
        fn new() -> HStderr { HStderr { _0: () } }
    }

    impl fmt::Write for HStderr {
        fn write_str(&mut self, _: &str) -> fmt::Result { Ok(()) }
    }

    #[panic_handler]
    fn panic(info: &PanicInfo) -> ! {
        let mut host_stderr = HStderr::new();

        // logs "panicked at '$reason', src/main.rs:27:4" to the host stderr
        writeln!(host_stderr, "{}", info).ok();

        loop {}
    }

    // crate: panic-halt -- halt the thread on panic; messages are discarded

    #![no_std]

    use core::panic::PanicInfo;

    #[panic_handler]
    fn panic(_info: &PanicInfo) -> ! {
        loop {}
    }

    // crate: app

    #![no_std]

    // dev profile
    #[cfg(debug_assertions)]
    extern crate panic_semihosting;

    // release profile
    #[cfg(not(debug_assertions))]
    extern crate panic_halt;

    // omitted: other `extern crate`s

    fn main() {
        // ..
    }