You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Concerning just the level 1 base [ABI-EH]. I haven't consulted the [psABI] directly, and perhaps it offers clarifications when interpreted together with [ABI-EH], but [ABI-EH] should ideally be sufficient on its own to use the unwinding runtime.
§1.2 Data Structures; Exception Header; exception_cleanup
_URC_FOREIGN_EXCEPTION_CAUGHT = 1: This indicates that a different runtime caught this exception. Nested foreign exceptions, or rethrowing a foreign exception, result in undefined behaviour. [source; emphasis mine]
§1.6.4 Rules for Correct Inter-Language Operation
The behavior is undefined in the following cases:
A __foreign_exception is active at the same time as another exception (either there is a nested exception while catching the foreign exception, or the foreign exception was itself nested). [source; emphasis mine]
This is unfortunately insufficiently clear at defining when an exception is considered nested, and at which operation behavior becomes undefined. There are at least three different scenarios:
A personality routine is running for an exception of class $A$ and an exception of class $B$ is raised.
A _URC_CONTINUE_UNWIND frame landing pad is running for an exception of class $A$ and an exception of class $B$ is raised.
A _URC_HANDLER_FOUND frame landing pad is running for an exception of class $A$ and an exception of class $B$ is raised.
All three cases have the additional variable of if any intervening frame would register a handler for the newly raised exception, as well as if that handler is native or foreign to exception class $B$.
Case (1) of a personality routine raising an exception itself is likely problematic for other reasons.
In C++, case (2) results from a throw within a destructor where that destructor is run by a cleanup landing pad for the prior exception, and case (3) results from a throw within a catch clause where $A$ is foreign to the C++ runtime (and thus not yet handled).
In Rust, case (2) results from a panic! within a Drop::drop run by a cleanup landing pad where $A$ is not a Rust panic (that case would abort). Case (3) is impossible by construction; the catch equivalent does not run user code inside the handler landing pad.
I have one concrete ask for the specification: directly define when _Unwind_RaiseException is sound to call. By my reading, I think the answer is that _Unwind_RaiseException causes undefined behavior when
some exception $e$ of class $E$ has previously been raised; where
$e$ has not been passed to e->exception_cleanup or otherwise cleaned up by the defining runtime; and
the newly raised exception is not of class $E$.
_Unwind_RaiseException is sound to call when
The _Unwind_Exception fields have been initialized as described; and
the above is not the case.
This operationally defines the nesting of foreign exceptions which produces undefined behavior in a way such that the undefined behavior can be prevented.
The text was updated successfully, but these errors were encountered:
Concerning just the level 1 base [ABI-EH]. I haven't consulted the [psABI] directly, and perhaps it offers clarifications when interpreted together with [ABI-EH], but [ABI-EH] should ideally be sufficient on its own to use the unwinding runtime.
§1.2 Data Structures; Exception Header;
exception_cleanup
§1.6.4 Rules for Correct Inter-Language Operation
This is unfortunately insufficiently clear at defining when an exception is considered nested, and at which operation behavior becomes undefined. There are at least three different scenarios:
_URC_CONTINUE_UNWIND
frame landing pad is running for an exception of class_URC_HANDLER_FOUND
frame landing pad is running for an exception of classAll three cases have the additional variable of if any intervening frame would register a handler for the newly raised exception, as well as if that handler is native or foreign to exception class$B$ .
Case (1) of a personality routine raising an exception itself is likely problematic for other reasons.$A$ is foreign to the C++ runtime (and thus not yet handled).$A$ is not a Rust panic (that case would abort). Case (3) is impossible by construction; the
In C++, case (2) results from a
throw
within a destructor where that destructor is run by a cleanup landing pad for the prior exception, and case (3) results from athrow
within acatch
clause whereIn Rust, case (2) results from a
panic!
within aDrop::drop
run by a cleanup landing pad wherecatch
equivalent does not run user code inside the handler landing pad.I have one concrete ask for the specification: directly define when
_Unwind_RaiseException
is sound to call. By my reading, I think the answer is that_Unwind_RaiseException
causes undefined behavior whene->exception_cleanup
or otherwise cleaned up by the defining runtime; and_Unwind_RaiseException
is sound to call when_Unwind_Exception
fields have been initialized as described; andThis operationally defines the nesting of foreign exceptions which produces undefined behavior in a way such that the undefined behavior can be prevented.
The text was updated successfully, but these errors were encountered: