4

What happens if the function I passed to std::panic::set_hook panics?

I can imagine many ways of reacting to this: consider this UB, abort the program like C++ does, invoke the panic handler again for the new panic, simply abort the execution of the hook... What exactly does Rust promise here?

Context. I'm writing a web app with Rust/WASM backend and I would like to make a panic hook that sends any errors to the server for debugging. This involves a network operation, which can itself fail. So I'm trying to figure out how I can ensure some reasonable behavior in this double-failure scenario.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
Andrei Matveiakin
  • 1,558
  • 1
  • 13
  • 17
  • 3
    looking through the [source code](https://doc.rust-lang.org/src/std/panicking.rs.html#658), if the hook panick the process is aborted. There is a panick_count that is incremented after a panic, if it is incremented again you will get an error message stating that the hook panicked and the process will be aborted. – Bamontan Aug 24 '22 at 04:33
  • 1
    @Bamontan I just found that as well and came back here to draft an answer. :) – cdhowie Aug 24 '22 at 04:37
  • @cdhowie make it an answer, I'm too lazy to do it. – Bamontan Aug 24 '22 at 04:38

1 Answers1

6

It's not documented outside of the source code.

The source code for the panic entry point in std has this comment:

// If this is the third nested call (e.g., panics == 2, this is 0-indexed),
// the panic hook probably triggered the last panic, otherwise the
// double-panic check would have aborted the process. In this case abort the
// process real quickly as we don't want to try calling it again as it'll
// probably just panic again.

So the answer to your question is either "invoke the panic handler again for the new panic" or "abort the program" depending on how many times the hook already panicked.


This all assumes you aren't using #![no_std]. If you are then you're either disabling panicking altogether or you are implementing your own panic handler with #[panic_handler], in which case you get to decide what happens yourself.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • One can argue that this is double panic that is documented (I think? The only source I could fine is https://rust-lang.github.io/rfcs/1328-global-panic-handler.html, but I remember seeing it documented) to abort. – Chayim Friedman Aug 24 '22 at 10:40
  • @ChayimFriedman I'm not sure the terms in the RFC line up exactly with what OP is asking. The RFC talks about the panic handler, but OP is asking about the panic hook. The panic hook is a facility provided by `std`, not the language, and it's called from the panic handler. The RFC says that any double panic causes an abort, but the panic handler in `std` has logic to explicitly handle a double panic, which implies that either `std` suppresses the auto-abort part of the panic runtime somehow, the panic runtime doesn't actually auto-abort, or `std` unnecessarily guards against double panics. – cdhowie Aug 24 '22 at 14:27
  • @ChayimFriedman (Or that I'm misunderstanding something, which wouldn't be the first time.) – cdhowie Aug 24 '22 at 14:28
  • I am referring to the sentence "If a thread panics while panicking (a "double panic"), the panic handler will not be invoked and the process will abort". The only question is whether is thread is considered panicking while running the panic hook, and I think the answer is true. – Chayim Friedman Aug 25 '22 at 01:56
  • @ChayimFriedman So that then requires us to ask why the standard library's panic handler accounts for a double panic when it sounds like the panic runtime does that. – cdhowie Aug 25 '22 at 04:16
  • The RFC doesn't say this will be the panic runtime that will handle this. – Chayim Friedman Aug 25 '22 at 04:37