## #[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]. [API docs]: ../core/panic/struct.PanicInfo.html 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`). ``` rust // crate: panic-semihosting -- log panic message to the host stderr using semihosting #![no_std] #[panic_handler] fn panic(info: &PanicInfo) -> ! { let host_stderr = /* .. */; // logs "panicked at '$reason', src/main.rs:27:4" to the host stderr writeln!(host_stderr, "{}", info).ok(); loop {} } ``` ``` rust // crate: panic-halt -- halt the thread on panic; messages are discarded #![no_std] #[panic_handler] fn panic(info: &PanicInfo) -> ! { loop {} } ``` ``` rust // 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() { // .. } ```