Find a panic location from catch_unwind()

How to find panic location from catch_unwind ? Problem:

let res = catch_unwind(|| some_arbitrary_code());
if res.is_err() {
    println!("Panic occured at {file}:{line}:{col}", file = ?, line = ?, col = ?);
}

Stuff I tried that failed:

  1. Store this info in panic hook into a thread local variable and later restore it after catch_unwind(). Doesn’t actually work with case like this:
catch_unwind(|| {
    let res = thread::spawn(|| {
        // hook gets called in this thread, so uses a different thread local
        panic!()
    }).join();
    if let Err(err) = res {
        resume_unwind(err);
    }
});
  1. Store this info in panic hook into a HashMap<usize, ...>, keyed with address of the payload. This doesn’t work, because StrPanicPayload gives an address of unboxed payload to the panic hook, so it’s different in Box<_> returned by catch_unwind().

Related thread: Return value from catch_unwind is a useless "Any"

1 Like

It’s possible to work around the StrPanicPayload issue by trying to downcast both payloads to &str and comparing resulting addresses, but this is strongly relying on details of internal implementation.

No it’s not, since static strings have a single address in the binary, so if two panics have the same message, they’ll probably have the same message address.

It was unclear to me from the docs if this would work or not, but it does seem to. Sadly you lose the original payload. (You could try to copy/clone the common cases.)

    panic::set_hook(Box::new(|info| {
        panic::resume_unwind(Box::new(
            info.location().map(|loc| PanicData {
                file: loc.file().into(),
                line: loc.line(),
                column: loc.column(),
            })
        ))
    }));
1 Like

That’s a fun workaround, thanks. Original payload could be restored for known types, but not for panic_any. It looks kinda scary though. I wonder if this behaviour is guaranteed.

I, too, wonder where/if this is better documented, but I don't have the time to dig right now. Please update the thread if you find something :slight_smile:

No, that’s unfortunately an accident.

https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/.60resume_unwind.28.29.60.20from.20panic.20hook/near/361273611

1 Like

Dang. Really does seem underspecified too :frowning:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.