diff --git a/site/source/docs/porting/exceptions.rst b/site/source/docs/porting/exceptions.rst index 07f003b9328bf..4dffc6fe76264 100644 --- a/site/source/docs/porting/exceptions.rst +++ b/site/source/docs/porting/exceptions.rst @@ -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 + `_ 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 + `_, which neither + supports. So the following program does NOT print ``my set_terminate``: + + .. code-block:: cpp + + #include + #include + + 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 + #include + + 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; + } + + This can possibly be supported in the future.