Closed as not planned
Description
std::current_exception
is nullptr when called from a termination handler.
Steps to reproduce
- Create
main.cpp
with the following contents:
#include <exception>
#include <iostream>
#include <stdexcept>
#include <utility>
static void printCurrentException() {
auto exPtr = std::current_exception();
std::cerr << "exception_ptr = ";
if (exPtr)
try {
std::rethrow_exception(std::move(exPtr));
} catch (const std::runtime_error &ex) {
std::cerr << "runtime_error: " << ex.what() << '\n';
} catch (...) {
std::cerr << "non-runtime_error\n";
}
else std::cerr << "NULL\n";
}
void noThrow() noexcept {
try {
throw std::runtime_error("error1");
} catch (...) {
printCurrentException();
}
std::set_terminate([] {
printCurrentException();
std::abort();
});
throw std::runtime_error("error2");
}
int main() {
noThrow();
}
- Now compile with exceptions (optionally with debug symbols):
em++ -fexceptions main.cpp -o hello.js
- Now run the file (e.g. with Node.js, or use
-o hello.html
and open with a browser), and observe output:
$ node hello.js
exception_ptr = runtime_error: error1
exception_ptr = NULL
Aborted(native code called abort())
- Note that
std::current_exception()
was properly set in thecatch
block, but the termination handler got anullptr
, while it should've been a pointer wrappingstd::runtime_error("error2")
.
The same happens with -fwasm-exceptions
and -fwasm-exceptions -sNO_WASM_LEGACY_EXCEPTIONS
(run with --experimental-wasm-exnref
as first parameter to node
).
Details
The standard says the following
constexpr exception_ptr current_exception() noexcept;
- Returns: An exception_ptr object that refers to the currently handled exception or a copy of the currently handled exception, or a null exception_ptr object if no exception is being handled.
[...]
and:
- If no matching handler is found, the function std::terminate is invoked; whether or not the stack is unwound before this invocation of std::terminate is implementation-defined ([except.terminate]).
- A handler is considered active when initialization is complete for the parameter (if any) of the catch clause.
[Note 4: The stack will have been unwound at that point.
— end note]
Also, an implicit handler is considered active when the function std::terminate is entered due to a throw.
A handler is no longer considered active when the catch clause exits.- The exception with the most recently activated handler that is still active is called the currently handled exception.
So, as I understand it, the "implicit handler" should be active at this point. Besides, it works fine when compiled for x86 using Clang or GCC.
Version of emscripten/emsdk
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 4.0.3 (a9651ff57165f5710bb09a5fe52590fd6ddb72df)
clang version 21.0.0git (https:/github.com/llvm/llvm-project 6dc41a639334b913e762f65410fcd14a722b137f)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/swdv/emsdk/upstream/bin
Metadata
Metadata
Assignees
Labels
No labels