|
| 1 | +# Panic |
| 2 | + |
| 3 | +Rust provides the ability to "panic" upon encountering a runtime error that is |
| 4 | +not part of a function's signature; such an error is typically not expected to |
| 5 | +be recoverable within the context in which the error is encountered. |
| 6 | + |
| 7 | +> The Standard Library provides this capability via the [`panic!` macro][macro-panic]. |
| 8 | +
|
| 9 | +Although it is not part of the core language, panics interact with several core |
| 10 | +language features; for instance, out-of-bounds array indexing using the |
| 11 | +`array[index]` syntax will automatically panic. |
| 12 | + |
| 13 | +[macro-panic]: ../std/macro.panic.html |
| 14 | +[fn-catch-unwind]: ../std/panic/fn.catch_unwind.html |
| 15 | +[join]: ../std/thread/struct.JoinHandle.html#method.join |
| 16 | + |
| 17 | +## Unwinding |
| 18 | + |
| 19 | +By default, the `panic!` macro unwinds Rust frames, just as C++'s `throw` |
| 20 | +unwinds C++ frames. This means that as the panic traverses Rust frames, live |
| 21 | +objects in those frames that implement `Drop` will have their `drop` methods |
| 22 | +called. It also enables the runtime to recover from the panic rather than |
| 23 | +terminating execution. |
| 24 | + |
| 25 | +> The Standard Library provides two mechanisms for recovering from a panic, |
| 26 | +> [`catch_unwind`][fn-catch-unwind] (which enables a thread to recover) and |
| 27 | +> [`JoinHandle::join`][join] (which enables a process to recover without |
| 28 | +> recovering the thread state). |
| 29 | +
|
| 30 | +## Panic runtimes |
| 31 | +[top]: #panic-runtimes |
| 32 | + |
| 33 | +The actual behavior of `panic!` is controlled by the _panic runtime_. The Rust |
| 34 | +standard library provides two panic runtimes: `panic_unwind` (the default) and |
| 35 | +`panic_abort`, which immediately aborts the process. When compiling code that |
| 36 | +is guaranteed (via a [compiler option][rustc-codegen]), the optimizer may |
| 37 | +assume that unwinding across Rust frames is impossible, which can result in |
| 38 | +both code-size and runtime speed improvements. |
| 39 | + |
| 40 | +### `rustc` codegen and linking |
| 41 | +[rustc-codegen]: #rustc-codegen |
| 42 | + |
| 43 | +`rustc` provides two supported runtime strategies: |
| 44 | + |
| 45 | +* `-C panic=unwind` - this links against `panic_unwind` and ensures that |
| 46 | + unwinding across the compiled frames will perform all appropriate clean-up. |
| 47 | + In particular, `drop` will be called for live `Drop` objects. |
| 48 | +* `-C panic=abort` - this links against `panic_abort`, and optimizes with the |
| 49 | + assumption that frames cannot be unwound. Since unwinding does not occur with |
| 50 | + this runtime, it is impossible to catch a `panic!` using `catch_unwind`. |
| 51 | + |
| 52 | +This codegen option will default to `unwind` if not specified, and the value is |
| 53 | +encoded into the crate metadata. |
| 54 | + |
| 55 | +Linking against the actual panic runtime is performed lazily, so that if |
| 56 | +different crates specify different runtimes, the `panic_abort` runtime is |
| 57 | +preferred. This ensures that `panic!` cannot cause a soundness hole by |
| 58 | +unwinding across Rust frames compiled with `panic=abort`. |
0 commit comments