#[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).

  1. // crate: panic-semihosting -- log panic messages to the host stderr using semihosting
  2. #![no_std]
  3. use core::fmt::{Write, self};
  4. use core::panic::PanicInfo;
  5. struct HStderr {
  6. // ..
  7. # _0: (),
  8. }
  9. #
  10. # impl HStderr {
  11. # fn new() -> HStderr { HStderr { _0: () } }
  12. # }
  13. #
  14. # impl fmt::Write for HStderr {
  15. # fn write_str(&mut self, _: &str) -> fmt::Result { Ok(()) }
  16. # }
  17. #[panic_handler]
  18. fn panic(info: &PanicInfo) -> ! {
  19. let mut host_stderr = HStderr::new();
  20. // logs "panicked at '$reason', src/main.rs:27:4" to the host stderr
  21. writeln!(host_stderr, "{}", info).ok();
  22. loop {}
  23. }
  1. // crate: panic-halt -- halt the thread on panic; messages are discarded
  2. #![no_std]
  3. use core::panic::PanicInfo;
  4. #[panic_handler]
  5. fn panic(_info: &PanicInfo) -> ! {
  6. loop {}
  7. }
  1. // crate: app
  2. #![no_std]
  3. // dev profile
  4. #[cfg(debug_assertions)]
  5. extern crate panic_semihosting;
  6. // release profile
  7. #[cfg(not(debug_assertions))]
  8. extern crate panic_halt;
  9. // omitted: other `extern crate`s
  10. fn main() {
  11. // ..
  12. }