Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions site/source/docs/porting/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,57 @@ Using Exceptions and setjmp-longjmp Together
============================================

See :ref:`using-exceptions-and-setjmp-longjmp-together`.


Limitations regarding std::terminate()
======================================

* Currently `std::set_terminate
<https://en.cppreference.com/w/cpp/error/set_terminate>`_ is NOT supported
when a thrown exception does not have a matching handler and unwinds all the
stack up to the topmost caller and crashes the program, i.e., there is no
``catch`` that catches it and the callers are not marked as ``noexcept``.
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. So the following program does NOT print ``my set_terminate``:

.. code-block:: cpp

#include <iostream>
#include <exception>

int main() {
std::set_terminate([] {
std::cerr << "my set_terminate" << std::endl;
std::abort();
});
throw 3;
}

* When the exception handling encounters a termination condition, libc++abi
spec says we call `__cxa_begin_catch()` to mark the exception as handled and
then call `std::terminate()`. But currently Wasm EH does not support calling
`__cxa_begin_catch()`. So the following program prints ``exception_ptr is
null``, where it is supposed to print ``exception_ptr is NOT null``; note
that the use of ``noexcept`` here means that the ``throw 3`` will turn into
a termination condition.

.. code-block:: cpp

#include <iostream>
#include <exception>

int main() noexcept {
std::set_terminate([] {
auto ptr = std::current_exception();
if (ptr)
std::cerr << "exception_ptr is NOT null" << std::endl;
else
std::cerr << "exception_ptr is null" << std::endl;
std::abort();
});
throw 3;
Copy link
Collaborator

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?

Copy link
Member Author

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 can possibly be supported in the future.