From 792093950dbdc5a3b9e93ef465d61a0600716684 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 12 Apr 2023 10:55:33 -0700 Subject: [PATCH] Fix lto0.test_exceptions_allowed_uncaught failure This test started failing after #16627. Prior to that change the exceptions destructors were called via the following code in JS: ``` // In Wasm, destructors return 'this' as in ARM {{{ makeDynCall('pp', 'destructor') }}}(info.excPtr); ``` For some reason the LTO build produces the following for for the call to `exception_header->exceptionDestructor(thrown_object)` in `__cxa_decrement_exception_refcount`: ``` call_indirect 0 (type 0) ``` Where as the normal non-LTO build produces: ``` call 13 ``` Because invoke_ii goes via JS it uses the sloppy type checking and doesn't trap, but `call_indirect` has strict type checking and so does trap. --- .circleci/config.yml | 1 + system/lib/libcxxabi/src/cxa_exception.h | 3 ++- .../lib/libcxxabi/src/cxa_exception_emscripten.cpp | 13 +++++++------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f964b520d2973..ffd8a4ce41e27 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -492,6 +492,7 @@ jobs: title: "core3+extras" test_targets: " lto2.test_dylink_syslibs_all + lto0.test_exceptions_allowed_uncaught core3 core2g.test_externref corez.test_dylink_iostream diff --git a/system/lib/libcxxabi/src/cxa_exception.h b/system/lib/libcxxabi/src/cxa_exception.h index dd20ba1e8891a..96f828d003239 100644 --- a/system/lib/libcxxabi/src/cxa_exception.h +++ b/system/lib/libcxxabi/src/cxa_exception.h @@ -24,7 +24,8 @@ namespace __cxxabiv1 { struct _LIBCXXABI_HIDDEN __cxa_exception { size_t referenceCount; std::type_info *exceptionType; - void (*exceptionDestructor)(void *); + // In wasm, destructors return 'this' as in ARM + void* (*exceptionDestructor)(void *); uint8_t caught; uint8_t rethrown; void *adjustedPtr; diff --git a/system/lib/libcxxabi/src/cxa_exception_emscripten.cpp b/system/lib/libcxxabi/src/cxa_exception_emscripten.cpp index af7ec0c0452f0..195dcdae8ac23 100644 --- a/system/lib/libcxxabi/src/cxa_exception_emscripten.cpp +++ b/system/lib/libcxxabi/src/cxa_exception_emscripten.cpp @@ -20,7 +20,8 @@ // Define to enable extra debugging on stderr. #if EXCEPTIONS_DEBUG -#define DEBUG printf +#include "emscripten/console.h" +#define DEBUG _emscripten_errf #else #define DEBUG(...) #endif @@ -48,7 +49,7 @@ inline __cxa_exception* cxa_exception_from_thrown_object(void* thrown_object) { - DEBUG("cxa_exception_from_thrown_object %p -> %p\n", + DEBUG("cxa_exception_from_thrown_object %p -> %p", thrown_object, static_cast<__cxa_exception*>(thrown_object) - 1); return static_cast<__cxa_exception*>(thrown_object) - 1; } @@ -60,7 +61,7 @@ inline void* thrown_object_from_cxa_exception(__cxa_exception* exception_header) { - DEBUG("thrown_object_from_cxa_exception %p -> %p\n", + DEBUG("thrown_object_from_cxa_exception %p -> %p", exception_header, static_cast(exception_header + 1)); return static_cast(exception_header + 1); } @@ -118,7 +119,7 @@ __cxa_increment_exception_refcount(void *thrown_object) _NOEXCEPT { if (thrown_object != NULL ) { __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); - DEBUG("INC: %p refcnt=%zu\n", thrown_object, exception_header->referenceCount); + DEBUG("INC: %p refcnt=%zu", thrown_object, exception_header->referenceCount); std::__libcpp_atomic_add(&exception_header->referenceCount, size_t(1)); } } @@ -136,12 +137,12 @@ void __cxa_decrement_exception_refcount(void *thrown_object) _NOEXCEPT { if (thrown_object != NULL ) { __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); - DEBUG("DEC: %p refcnt=%zu rethrown=%d\n", thrown_object, + DEBUG("DEC: %p refcnt=%zu rethrown=%d", thrown_object, exception_header->referenceCount, exception_header->rethrown); assert(exception_header->referenceCount > 0); if (std::__libcpp_atomic_add(&exception_header->referenceCount, size_t(-1)) == 0 && !exception_header->rethrown) { - DEBUG("DEL: %p\n", thrown_object); + DEBUG("DEL: %p (dtor=%p)", thrown_object, exception_header->exceptionDestructor); if (NULL != exception_header->exceptionDestructor) exception_header->exceptionDestructor(thrown_object); __cxa_free_exception(thrown_object);