mention resume_panic entry point
authorRalf Jung <post@ralfj.de>
Tue, 26 Nov 2019 09:23:45 +0000 (10:23 +0100)
committerRalf Jung <post@ralfj.de>
Tue, 26 Nov 2019 09:23:45 +0000 (10:23 +0100)
personal/_posts/2019-11-25-how-to-panic-in-rust.md

index 0a9d2ba21b7bba82c4ba7cf740acde09360788a6..3aa147ae3c9ff7e0768484b0de2514ff441d1489 100644 (file)
@@ -71,7 +71,7 @@ On top of the panic *runtime* interface, libstd implements the default Rust pani
 
 #### `rust_panic_with_hook`
 
-The key function that everything passes through is [`rust_panic_with_hook`](https://github.com/rust-lang/rust/blob/7d761fe0462ba0f671a237d0bb35e3579b8ba0e8/src/libstd/panicking.rs#L435-L437):
+The key function that almost everything passes through is [`rust_panic_with_hook`](https://github.com/rust-lang/rust/blob/7d761fe0462ba0f671a237d0bb35e3579b8ba0e8/src/libstd/panicking.rs#L435-L437):
 {% highlight rust %}
 fn rust_panic_with_hook(
     payload: &mut dyn BoxMeUp,
@@ -96,7 +96,7 @@ The `'static` bound is quite well hidden there, but after a while I realized tha
 
 #### libstd panicking entry points
 
-`rust_panic_with_hook` is a private function to `std::panicking`; the module provides three separate entry points on top of this central function:
+`rust_panic_with_hook` is a private function to `std::panicking`; the module provides three entry points on top of this central function, and one that circumvents it:
 
 * the [default panic handler implementation](https://github.com/rust-lang/rust/blob/7d761fe0462ba0f671a237d0bb35e3579b8ba0e8/src/libstd/panicking.rs#L301), backing (as we will see) panics from `core::panic!` and built-in panics (from arithmetic overflow or out-of-bounds array/slice indexing).
   This obtains as input a [`PanicInfo` ](https://doc.rust-lang.org/core/panic/struct.PanicInfo.html), and it has to turn that into arguments for `rust_panic_with_hook`.
@@ -119,6 +119,11 @@ The `'static` bound is quite well hidden there, but after a while I realized tha
     In particular, a panic hook that looks at the `message` field of the `PanicData` it is passed will *not* be able to see the message in a `std::panic!("do panic")`, but it *will* see the message in a `std::panic!("panic with data: {}", data)` as the latter passes through `begin_panic_fmt` instead.
   That seems quite surprising. (But also note that `PanicData::message()` is not stable yet.)
 
+* [`update_count_then_panic`](https://github.com/rust-lang/rust/blob/7d761fe0462ba0f671a237d0bb35e3579b8ba0e8/src/libstd/panicking.rs#L488) is the odd one out: this entry point backs [`resume_unwind`](https://doc.rust-lang.org/nightly/std/panic/fn.resume_unwind.html), and it actually does *not* call the panic hook.
+  Instead, it dispatches to the panic runtime immediately.
+  Like, `begin_panic`, it lets the caller pick an arbitrary payload.
+  Unlike `begin_panic`, the caller is responsible for boxing and unsizing the payload; `update_count_then_panic` just forwards that pretty much verbatim to the panic runtime.
+
 ## Panic Handler
 
 All of the `std::panic!` machinery is really useful, but it relies on heap allocations through `Box` which is not always available.