diff --git a/emcc.py b/emcc.py index 556dbf4ccfcc3..b2726ee10436f 100755 --- a/emcc.py +++ b/emcc.py @@ -2136,7 +2136,7 @@ def phase_linker_setup(options, state, newargs, user_settings): # TODO: Move this into the library JS file once it becomes possible. # See https://github.com/emscripten-core/emscripten/pull/15982 if settings.INCLUDE_FULL_LIBRARY and not settings.DISABLE_EXCEPTION_CATCHING: - settings.EXPORTED_FUNCTIONS += ['_emscripten_format_exception', '_free'] + settings.EXPORTED_FUNCTIONS += ['___get_exception_message', '_free'] if settings.WASM_WORKERS: # TODO: After #15982 is resolved, these dependencies can be declared in library_wasm_worker.js diff --git a/src/library_exceptions.js b/src/library_exceptions.js index e87599f9caaf4..91cbc669bbd21 100644 --- a/src/library_exceptions.js +++ b/src/library_exceptions.js @@ -392,9 +392,9 @@ var LibraryExceptions = { }, #if !DISABLE_EXCEPTION_CATCHING - $formatException__deps: ['emscripten_format_exception', 'free'], - $formatException: function(excPtr) { - var utf8_addr = _emscripten_format_exception(excPtr); + $getExceptionMessage__deps: ['__get_exception_message', 'free'], + $getExceptionMessage: function(excPtr) { + var utf8_addr = ___get_exception_message(excPtr); var result = UTF8ToString(utf8_addr); _free(utf8_addr); return result; diff --git a/system/lib/libcxxabi/src/cxa_exception_emscripten.cpp b/system/lib/libcxxabi/src/cxa_exception_emscripten.cpp index e740d0fec97a0..b60a57178a6d0 100644 --- a/system/lib/libcxxabi/src/cxa_exception_emscripten.cpp +++ b/system/lib/libcxxabi/src/cxa_exception_emscripten.cpp @@ -24,7 +24,7 @@ cxa_exception_from_thrown_object(void* thrown_object) { extern "C" { -char* emscripten_format_exception(void* thrown_object) { +char* __get_exception_message(void* thrown_object, bool terminate=false) { __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); const __shim_type_info* thrown_type = @@ -45,12 +45,15 @@ char* emscripten_format_exception(void* thrown_object) { const char* what = static_cast(thrown_object)->what(); asprintf(&result, - "terminating with uncaught exception of type %s: %s", + (terminate ? "terminating with uncaught exception of type %s: %s" + : "exception of type %s: %s"), type_name, what); } else { - asprintf( - &result, "terminating with uncaught exception of type %s", type_name); + asprintf(&result, + (terminate ? "terminating with uncaught exception of type %s" + : "exception of type %s"), + type_name); } if (demangled_buf) { @@ -58,6 +61,11 @@ char* emscripten_format_exception(void* thrown_object) { } return result; } + +char* __get_exception_terminate_message(void *thrown_object) { + return __get_exception_message(thrown_object, true); +} + } #endif // __USING_EMSCRIPTEN_EXCEPTIONS__ diff --git a/tests/test_core.py b/tests/test_core.py index 3d6c17e26ce96..fa30d779c346e 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1608,10 +1608,10 @@ def test_exceptions_rethrow_missing(self): self.do_runf('main.cpp', None, assert_returncode=NON_ZERO) @no_wasm64('MEMORY64 does not yet support exceptions') - def test_format_exception(self): + def test_exception_message(self): self.set_setting('DISABLE_EXCEPTION_CATCHING', 0) - self.set_setting('DEFAULT_LIBRARY_FUNCS_TO_INCLUDE', ['$formatException', '__cxa_decrement_exception_refcount', '__cxa_increment_exception_refcount']) - self.set_setting('EXPORTED_FUNCTIONS', ['_main', 'formatException', '_emscripten_format_exception', '_free']) + self.set_setting('DEFAULT_LIBRARY_FUNCS_TO_INCLUDE', ['$getExceptionMessage', '__cxa_decrement_exception_refcount', '__cxa_increment_exception_refcount']) + self.set_setting('EXPORTED_FUNCTIONS', ['_main', 'getExceptionMessage', '___get_exception_message', '_free']) self.maybe_closure() src = ''' #include @@ -1645,14 +1645,14 @@ class myexception : public exception { EM_ASM({ for (let i = 1; i < 6; i++){ try { - Module["_throw_exc"](i); + _throw_exc(i); } catch(p) { // Because we are catching and handling the exception in JS, the normal // exception catching C++ code doesn't kick in, so we need to make sure we free // the exception, if necessary. By incrementing and decrementing the refcount // we trigger the free'ing of the exception if its refcount was zero. ___cxa_increment_exception_refcount(p); - console.log(Module["formatException"](p).replace(/0x[0-9a-f]*/, "xxx")); + console.log(getExceptionMessage(p)); ___cxa_decrement_exception_refcount(p); } } @@ -1660,11 +1660,11 @@ class myexception : public exception { } ''' expected = '''\ -terminating with uncaught exception of type int -terminating with uncaught exception of type char -terminating with uncaught exception of type std::runtime_error: abc -terminating with uncaught exception of type myexception: My exception happened -terminating with uncaught exception of type char const* +exception of type int +exception of type char +exception of type std::runtime_error: abc +exception of type myexception: My exception happened +exception of type char const* ''' self.do_run(src, expected)