diff --git a/src/lib/libexceptions.js b/src/lib/libexceptions.js index 6d7dc784ff2ff..f7256fcf32f01 100644 --- a/src/lib/libexceptions.js +++ b/src/lib/libexceptions.js @@ -257,6 +257,7 @@ var LibraryExceptions = { }, #endif + #if WASM_EXCEPTIONS || !DISABLE_EXCEPTION_CATCHING $getExceptionMessageCommon__deps: ['__get_exception_message', 'free', '$stackSave', '$stackRestore', '$stackAlloc'], $getExceptionMessageCommon: (ptr) => { @@ -277,17 +278,23 @@ var LibraryExceptions = { return [type, message]; }, #endif + #if WASM_EXCEPTIONS +#if ASSERTIONS + // Try to give a more useful error message than simply `Undefined reference to `emscripten_longjmp` + emscripten_longjmp__deps: [() => error('undefined reference to `emscripten_longjmp`. One or more object files was not compiled with `-fwasm-exceptions`. Build with `-sASSERTIONS=0` to have wasm-ld report which one.')], + emscripten_longjmp: () => {}, +#endif + $getCppExceptionTag: () => // In static linking, tags are defined within the wasm module and are // exported, whereas in dynamic linking, tags are defined in library.js in // JS code and wasm modules import them. #if RELOCATABLE - ___cpp_exception // defined in library.js + ___cpp_exception, // defined in library.js #else - wasmExports['__cpp_exception'] + wasmExports['__cpp_exception'], #endif - , #if EXCEPTION_STACK_TRACES // Throw a WebAssembly.Exception object with the C++ tag with a stack trace diff --git a/src/lib/libexceptions_stub.js b/src/lib/libexceptions_stub.js index 60f4a9c072999..f2f49dff45ee9 100644 --- a/src/lib/libexceptions_stub.js +++ b/src/lib/libexceptions_stub.js @@ -23,7 +23,7 @@ var LibraryExceptions = {}; LibraryExceptions[name] = function() { abort(); }; #if !INCLUDE_FULL_LIBRARY // This method of link-time error generation is not compatible with INCLUDE_FULL_LIBRARY - LibraryExceptions[name + '__deps'] = [function() { + LibraryExceptions[name + '__deps'] = [() => { error(`DISABLE_EXCEPTION_THROWING was set (likely due to -fno-exceptions), which means no C++ exception throwing support code is linked in, but such support is required by symbol '${name}'. Either do not set DISABLE_EXCEPTION_THROWING (if you do want exception throwing) or compile all source files with -fno-except (so that no exceptions support code is required); also make sure DISABLE_EXCEPTION_CATCHING is set to the right value - if you want exceptions, it should be off, and vice versa.`); }]; #endif diff --git a/test/test_other.py b/test/test_other.py index 318af8bea965e..eb72d3a8ece79 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -9438,6 +9438,22 @@ def test_exceptions_c_linker(self): stderr = self.expect_fail([EMCC, '-sSTRICT', test_file('other/test_exceptions_c_linker.c')]) self.assertContained('error: undefined symbol: __cxa_find_matching_catch_1', stderr) + def test_exceptions_mismatch(self): + create_file('main.c', ''' + #include + int main() { + jmp_buf buf; + longjmp(buf, 8); + } + ''') + self.emcc('main.c', ['-c']) + err = self.expect_fail([EMCC, 'main.o', '-fwasm-exceptions']) + self.assertContained('error: undefined reference to `emscripten_longjmp`. One or more object files was not compiled with `-fwasm-exceptions`. Build with `-sASSERTIONS=0` to have wasm-ld report which one.', err) + + err = self.expect_fail([EMCC, 'main.o', '-fwasm-exceptions', '-sASSERTIONS=0']) + self.assertContained('wasm-ld: error: main.o: undefined symbol: emscripten_longjmp', err) + + @with_all_eh_sjlj def test_exceptions_stack_trace_and_message(self): src = r'''