Never Panic - An Elegant Solution

2025-01-06

In Rust, a panic is an irrecoverable error + unwinding (in most cases). It's possible to define a custom panic_handler for a no_std rust program.

In many business use cases - extreme fault tolerance is required. Since panics in Rust are explicit (compared to implicit exceptions in most languages) - proving a program can't panic should be feasible in polynomial time.

What would a program verifying a binary is "panic-less" look like? Turns out - such verifier can be elegantly, and simply designed using a clever linker trick.

#![deny(missing_docs)]
#![deny(rust_2018_compatibility)]
#![deny(rust_2018_idioms)]
#![deny(warnings)]
#![no_std]

use core::panic::PanicInfo;

#[panic_handler]
fn panic(_: &PanicInfo<'_>) -> ! {
    extern "Rust" {
        #[link_name = "\nerror(panic-never): your program contains at least one panicking branch"]
        fn undefined() -> !;
    }

    unsafe { undefined() }
}

That's it, ~10 lines, can now prove a Rust program doesn't, ever - panic. There are some exceptions, mainly - it (kind of) only works in release mode, and it obviously can't verify compile-time-halting programs are panic-less (as far as we know, but that's a much bigger CS problem).

The code is very short, nice, but what does it actually... do?
The underlying work is pretty straight forward.

  1. Sets a custom panic_handler (will be called when (and if) a program panics)
  2. The handler tells the linker to link an undefined symbol (impossible, linker will fail and exit)
  3. If the underlying program doesn't panic - the custom panic_handler will be optimized out and linking wouldn't fail (wouldn't fail for the intentional undefined symbol).