Skip to content

Conversation

@aheejin
Copy link
Member

@aheejin aheejin commented Dec 20, 2025

This fixes inconsistency of incrementing/decrementing refcounts between Wasm EH and Emscripten EH.

Previously, in Emscripten EH, we incremented the refcount in __cxa_begin_catch, while Wasm EH incremented it in __cxa_throw. This PR moves the incrementing call from __cxa_begin_catch to __cxa_throw as well. This also increments the refcount in __cxa_rethrow.

These incrementing calls are guarded with
+#if !DISABLE_EXCEPTION_CATCHING, because without that, std::terminate will run:

void
__cxa_increment_exception_refcount(void *thrown_object) throw() {
if (thrown_object != nullptr)
std::terminate();
}
void
__cxa_decrement_exception_refcount(void *thrown_object) throw() {
if (thrown_object != nullptr)
std::terminate();
}

Fixes #17115.

This fixes inconsistency of incrementing/decrementing refcounts between
Wasm EH and Emscripten EH.

Previously, in Emscripten EH, we incremented the refcount in
`__cxa_begin_catch`, while Wasm EH incremented it in `__cxa_throw`. This
PR moves the incrementing call from `__cxa_begin_catch` to `__cxa_throw`
as well. This also increments the refcount in `__cxa_rethrow`.

These incrementing calls are guarded with
`+#if !DISABLE_EXCEPTION_CATCHING`, because without that,
`std::terminate` will run:
https://github.com/emscripten-core/emscripten/blob/d1251798144df813c52934768964a1223504c440/system/lib/libcxxabi/src/cxa_noexception.cpp#L25-L35

Fixes emscripten-core#17115.
@kleisauke
Copy link
Collaborator

Great! It looks like these mentions can also be removed from the docs now:
https://github.com/emscripten-core/emscripten/blob/d1251798144df813c52934768964a1223504c440/src/settings.js#L764C45-L766C65
https://github.com/emscripten-core/emscripten/blob/d1251798144df813c52934768964a1223504c440/site/source/docs/porting/exceptions.rst?plain=1#L159C60-L167C52

emscripten/tools/link.py

Lines 1837 to 1838 in d125179

# What you need to do is different depending on the kind of EH you use
# (https://github.com/emscripten-core/emscripten/issues/17115).

@aheejin
Copy link
Member Author

aheejin commented Dec 22, 2025

Great! It looks like these mentions can also be removed from the docs now: https://github.com/emscripten-core/emscripten/blob/d1251798144df813c52934768964a1223504c440/src/settings.js#L764C45-L766C65 https://github.com/emscripten-core/emscripten/blob/d1251798144df813c52934768964a1223504c440/site/source/docs/porting/exceptions.rst?plain=1#L159C60-L167C52

emscripten/tools/link.py

Lines 1837 to 1838 in d125179

# What you need to do is different depending on the kind of EH you use
# (https://github.com/emscripten-core/emscripten/issues/17115).

Thanks! Removed: 9fee482

@aheejin
Copy link
Member Author

aheejin commented Dec 22, 2025

This fails LTO tests due to llvm/llvm-project#173235. Before, __cxa_increment_exception_refcount was a dependency for both __cxa_begin_catch and __cxa_current_primary_exception, and __cxa_begin_catch was (in the default Emscripten EH throwing-only mode) a JS function that was not used, so __cxa_current_primary_exception was preserved and exported anyway. But now __cxa_increment_exception_refcount is only dependent on __cxa_current_primary_exception, which is a JS function but in the throwing-only mode it is also defined in cxa_noexception.cpp, LTO tests fail. (See llvm/llvm-project#173235 for more explanation)

We have two choices:

  1. Wait until [lld][WebAssembly] Preserve LTO stub deps for bitcode symbols llvm/llvm-project#173235 lands
  2. Guard every usage of __cxa_in/decrement_exception_refcount with #if !DISABLE_EXCEPTION_CATCHING (Now I guarded only the ones in the function that can be used in throwing-only mode)

Maybe 2 is better for safety anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[EH] Fix inconsistency of refcounting in Emscripten EH vs. Wasm EH

3 participants