-
Notifications
You must be signed in to change notification settings - Fork 3.4k
[docs] Document limitation on std::set_terminate and __cxa_begin_catch #23728
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Due to the lack of two-phase EH, we, both in Emscripten EH and Wasm EH, do not support `std::set_terminate`. This documents the limitation. Closes emscripten-core#23720.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can/should we have calls to set_terminate
trap (or warn in debug builds)?
Co-authored-by: Alon Zakai <alonzakai@gmail.com>
Added documentation on another problem described in #23779. |
Turns out EDIT: This comment seems misleading; I clarified in #23728 (comment). |
Do you mean that it is support when the program exits normally? i.e. it acts like |
No it runs only when
Because of |
@sbc100 Do you have any other comments? |
stack and crashes the program. This applies to both Emscripten-style and | ||
WebAssembly exceptions. That functionality requires `two-phase exception | ||
handling <https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html>`_, which | ||
neither supports. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to say that set_terminate
will not work.. but in the example below you show it working (although without a valid current_exception
). These two things seems to be in contradiction with each other.
I guess maybe the noexcept
thing on main
is important here and that meas that there is maybe some kind of handler implicitly added to main
? but that isn't obvious to me at least ..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to say that
set_terminate
will not work.. but in the example below you show it working (although without a validcurrent_exception
). These two things seems to be in contradiction with each other.
So there's a condition written in the sentence:
... is NOT supported when a thrown exception does not have a matching handler and unwinds all the stack and crashes the program.
When we call std::terminate
is not when all stack is unwound due to an exception.
I guess maybe the
noexcept
thing onmain
is important here and that means that there is maybe some kind of handler implicitly added tomain
? but that isn't obvious to me at least ..
If a function is marked noexcept
, the code catches an exception within the function and calls std::terminate
(or __clang_call_terminate
, which calls std::terminate
), and it does not throw the exception to the caller. So the stack unwinding does not happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think its a little confusing though since the main function you wrote looks like it doesn't catch anything (since it contains no catches).
Understanding the noexcept
injects a invisible catch-all handler is required in order to understand what is going on there. That seems pretty non-obvious to me.
Maybe add comment right above main saying somthing like "The use of noexcept
here means that the throw 3
will turn into a termination condition".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added "The use of noexcept
here means that the throw 3
will turn into a termination condition" as you suggested in the second bullet point, and also added a little more clarifying words in the first bullet point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also added an example program to the first bullet point to make the situation clearer.
See :ref:`using-exceptions-and-setjmp-longjmp-together`. | ||
|
||
|
||
Limitations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since both of these limitation are regarding std::set_terminate
should we call this section Limitations regarding std::terminate
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
std::cerr << "exception_ptr is null" << std::endl; | ||
std::abort(); | ||
}); | ||
throw 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would writing std::terminate()
here have the same effect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case there's no exception so __cxa_begin_catch
is (correctly) not called and the program (correctly) prints exception_ptr is null
, so it does not show the bug (or limitation) here.
This documents the problems reported in #23720.
std::set_terminate
. This documents the limitation.__cxa_begin_catch
is not called before when EH handling callsstd::terminate
. This is documented more in detail in EH termination does not call __cxa_begin_catch #23779.