Skip to content

[EH] Fix __get_exception_message for multiple virtual inheritance#26946

Merged
aheejin merged 3 commits into
emscripten-core:mainfrom
aheejin:multi_inheritance_fix
May 14, 2026
Merged

[EH] Fix __get_exception_message for multiple virtual inheritance#26946
aheejin merged 3 commits into
emscripten-core:mainfrom
aheejin:multi_inheritance_fix

Conversation

@aheejin
Copy link
Copy Markdown
Member

@aheejin aheejin commented May 14, 2026

This fixes __get_exception_message so it works with multiple virtual inheritance. #24008 tried to fix this, but the test case there didn't virtual in the line where the inheritance happens.

In case of dependent exceptions (= the exceptions thrown by std::rethrow_exception), we should not even dereference thrown_object, because it doesn't contain anything. #24008 ran can_catch on the currect primary exception but before that it called can_catch on the dependent exception first, which caused the memory error. #24008's test case was fine because it didn't have virtual, we didn't have to dereference thrown_object (adjustedPtr in this method) directly:

if (info->have_object) {
/* We have an object to inspect, we can look through its vtables to
find the layout. */
offset_to_base = __offset_flags >> __offset_shift;
if (is_virtual) {
const char* vtable = strip_vtable(*static_cast<const char* const*>(adjustedPtr));
offset_to_base = update_offset_to_base(vtable, offset_to_base);
}

This computes the primary exception pointer first and then call can_catch.

Fixes #26771.

This fixes `__get_exception_message` so it works with multiple virtual
inheritance. emscripten-core#24008 tried to fix this, but the test case there didn't
`virtual` in the line where the inheritance happens.

In case of dependent exceptions (= the exceptions thrown by
`std::rethrow_exception`), we should not even dereference
`thrown_object`, because it doesn't contain anything. emscripten-core#24008 ran
`can_catch` on the currect primary exception but before that it called
`can_catch` on the dependent exception first, which caused the memory
error. emscripten-core#24008's test case was fine because it didn't have `virtual`, we
didn't have to dereference `thrown_object` (`adjustedPtr` in this
method) directly:
https://github.com/emscripten-core/emscripten/blob/b2e19a341ac53b33de3aae7b4ea7bf7168ebace7/system/lib/libcxxabi/src/private_typeinfo.cpp#L572-L579

This computes the primary exception pointer first and then call
`can_catch`.

Fixes emscripten-core#26771.
@aheejin aheejin requested a review from sbc100 May 14, 2026 01:54
Copy link
Copy Markdown
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need test_multi_inheritance_exception_message and test_multi_inheritance_exception_message2 both? Or can we adapt the first one maybe?

Otherwise lgtm

@aheejin
Copy link
Copy Markdown
Member Author

aheejin commented May 14, 2026

We can probably just delete the first one I think. Multiple inheritance seems almost always paired with virtual anyway.

@aheejin aheejin merged commit d124ba1 into emscripten-core:main May 14, 2026
30 checks passed
@aheejin aheejin deleted the multi_inheritance_fix branch May 14, 2026 06:14
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.

Memory access out of bounds in __get_exception_message for virtually-derived exceptions rethrown via std::exception_ptr (wasm EH, debug)

2 participants