Hello, I've been recently looking into panic behavior in pyo3, with a draft PR (https://github.com/PyO3/pyo3/pull/797) using
catch_unwind to guard against current UB (as I understand it) of unwinding through CPython stack frames. (For Rust functions called by the Python interpreter.)
If I'm reading the ffi-unwind group materials correctly, it sounds like the "C unwind" ABI would also make panics well-defined without needing to introduce
catch_unwind. Is that correct?
If you're interested in any details of pyo3 that would be relevant to this group's work, I'd be happy to deliver them. Thanks.
Note that the FFI code you are unwinding into also needs to support unwinding by performing the proper cleanups on unwind. So this only really works for C++ code, not C.
...unless your C code doesn't need any sort of "cleanup"; I think it's correct to think of it as being semantically identical to
longjmp over the unwound frames.
Your C code does need to be compiled with
But in the pyo3 case, the cpython frames are the Python interpreter itself, right? It seems unlikely that any Python user would want that.
...and of course it's unlikely that the Python interpreter's stack frames are "clean-up free".
catch_unwind seems very preferable.
Great, that makes sense, thanks. The model we're heading toward is to use
catch_unwind convert a Rust panic into a Python exception at the language boundary, and let the interpreter bubble it up through the "Python" stack frames.
It then seems reasonable that if that Python exception gets returned to Rust code in some higher stack frame we should then restart Rust's unwinding with
If we did this
catch / resume unwind dance, would "C unwind" simply offer no benefit here then? Or would it actually be actively harmful if the Python interpreter is not compiled with
"C unwind" is probably not useful for your case. You want to turn a Rust panic into a Python exception, but "C unwind" turns a Rust panic into a C++ exception.
Ok great. Thanks! :thumbs_up: