| # #[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`). | |
| `panic-semihosting` crate -- log panic messages to the host stderr using semihosting: | |
| <!-- ignore: simplified code --> | |
| ```rust,ignore | |
| #![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 {} | |
| } | |
| ``` | |
| `panic-halt` crate -- halt the thread on panic; messages are discarded: | |
| <!-- ignore: simplified code --> | |
| ```rust,ignore | |
| #![no_std] | |
| use core::panic::PanicInfo; | |
| #[panic_handler] | |
| fn panic(_info: &PanicInfo) -> ! { | |
| loop {} | |
| } | |
| ``` | |
| `app` crate: | |
| <!-- ignore: requires the above crates --> | |
| ```rust,ignore | |
| #![no_std] | |
| // dev profile | |
| #[cfg(debug_assertions)] | |
| extern crate panic_semihosting; | |
| // release profile | |
| #[cfg(not(debug_assertions))] | |
| extern crate panic_halt; | |
| fn main() { | |
| // .. | |
| } | |
| ``` |