Open BatmanAoD opened 1 month ago
Cc @rust-lang/opsem
Itanium specifies this cross-language mechanism this way:
(It's exception_cleanup
, not unwind_cleanup
.)
We currently set exception_cleanup to this function
So, we actually do something well-defined, though the error message one gets is probably a bit confusing.
In fact we even have a comment saying that this message is confusing :joy:
So we except "foreign Rust runtimes" from the confusion, but if the unwind gets caught by a foreign non-Rust runtime we continue to show the confusing error.
Okay, so we should document that we expect foreign runtimes to call this if they catch a panic, and that the effect is currently to abort but may change in the future?
Any suggestions for a less confusing panic message?
Probably not great, but better than nothing: Rust panic caught by foreign runtime; cannot continue. aborting.
The message could also benefit from a short explanation of why the program cannot continue, even if it's just cannot continue safely
/cannot continue soundly
.
I think it's possible to implement it properly so a foreign runtime to catch Rust exception and resume normal execution, so I'd avoid "safely" or "soundly". It's just that it's not yet implemented.
"caught" is the wrong term here I think; this is called when a Rust panic is discarded by a foreign runtime.
discarding Rust panic in a foreign runtime is currently not supported; aborting
"Caught" is used in (Itanium ABI](https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html), e.g. _URC_FOREIGN_EXCEPTION_CAUGHT
is the reason code given to cleanup function.
"Discarding" is also confusing IMO because it's not immediate clear how Rust panic is discarded when somebody writes try { ... } catch(...) {}
.
Would Rust panics caught by a foreign runtime and not rethrown. This is not currently supported, aborting.
be a more accurate way of describing? After all, only legal operations for a caught foreign exception is (1) rethrow (2) cleanup and (0) diverge.
"Caught" is used in (Itanium ABI](https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html), e.g. _URC_FOREIGN_EXCEPTION_CAUGHT is the reason code given to cleanup function.
Ah okay, I thought that term only applied in the "rethrow" case. Never mind then.
IMO we should just allow Rust panics to be caught and discarded by foreign code. The only thing we need to do is decrement the panic count in the cleanup function and everything should just work. Note that the panic count specifically only counts the number of active Rust panics (for the current Rust runtime, in case there are multiple in the address space).
Nothing needs to be done for foreign code re-throwing a Rust panic since that just acts like the catch never happened in the first place.
It is currently undefined behavior for a "foreign" language (such as C++) to catch a Rust panic, regardless of what the "foreign" code then does with the exception. That is, either disposing of or rethrowing the panic are both unconditional undefined behavior.
Permitting other languages to rethrow the panic, and permitting them to dispose of the panic, are separate "features" Rust could provide. This issue is only for safe disposal.
Note that Rust can document a function that a different runtime must call in order to safely dispose of a Rust panic. Per @chorman0773, Itanium specifies this cross-language mechanism this way:
Currently, the main thing that the Rust runtime would need to do when notified that a panic has been disposed of by a foreign runtime is to decrement the panic count. @bjorn3, @nbdd0121, @workingjubilee, and @Amanieu may have additional context on what would be required for foreign languages to safely dispose of Rust panics.
Original discussion: https://github.com/rust-lang/reference/pull/1226#discussion_r1739926327
CC @rust-lang/libs-api ; CC @rust-lang/lang