From eaaa8d1dc7f57b9a916ebec6c23a42580d3a0f0e Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 23 Oct 2019 15:18:35 -0700 Subject: [PATCH 1/5] Add extra text for main modules incorrectly compiled without exceptions. If a side module wants exceptions, the main module must be built to support that. Helps #9691 --- src/parseTools.js | 10 +++++---- tests/test_other.py | 53 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/parseTools.js b/src/parseTools.js index 7630913696db8..1923634db5e94 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1320,11 +1320,13 @@ function makeStructuralReturn(values, inAsm) { } function makeThrow(what) { - if (ASSERTIONS) { - return 'throw ' + what + (DISABLE_EXCEPTION_CATCHING == 1 ? ' + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."' : '') + ';'; - } else { - return 'throw ' + what + ';'; + if (ASSERTIONS && DISABLE_EXCEPTION_CATCHING) { + what += ' + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."'; + if (MAIN_MODULE) { + what += ' + " (note: in dynamic linking, if a side module wants exceptions, the main module must be built with that support)"'; + } } + return 'throw ' + what + ';'; } function makeSignOp(value, type, op, force, ignore) { diff --git a/tests/test_other.py b/tests/test_other.py index 2e60a44b57e53..2f8553fa31719 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -6488,11 +6488,11 @@ def test_ld_library_path(self): self.assertContained('Ok', out) def test_dlopen_rtld_global(self): - # TODO: wasm support. this test checks RTLD_GLOBAL where a module is loaded - # before the module providing a global it needs is. in asm.js we use JS - # to create a redirection function. In wasm we just have wasm, so we - # need to introspect the wasm module. Browsers may add that eventually, - # or we could ship a little library that does it. + # This test checks RTLD_GLOBAL where a module is loaded + # before the module providing a global it needs is. in asm.js we use JS + # to create a redirection function. In wasm we just have wasm, so we + # need to introspect the wasm module. Browsers may add that eventually, + # or we could ship a little library that does it. create_test_file('hello1.c', r''' #include @@ -6556,6 +6556,49 @@ def test_dlopen_rtld_global(self): self.assertContained('hello1_val by hello1:3', out) self.assertContained('hello1_val by hello2:3', out) + def test_main_module_without_exceptions_message(self): + # A side module that needs exceptions needs a main module with that + # support enabled; show a clear message in that case. + create_test_file('side.cpp', r''' + #include + #include + + extern "C" void test_throw() { + try { + throw 42; + } catch(int x) { + printf("catch %d.\n", x); + return; + } + puts("bad location"); + } + ''') + create_test_file('main.cpp', r''' + #include + #include + #include + #include + #include + + typedef void (*voidf)(); + + int main() { + void* h = dlopen ("libside.wasm", RTLD_NOW|RTLD_GLOBAL); + assert(h); + voidf f = (voidf)dlsym(h, "test_throw"); + assert(f); + f(); + return 0; + } + ''') + run_process([PYTHON, EMCC, '-o', 'libside.wasm', 'side.cpp', '-s', 'SIDE_MODULE=1']) + with env_modify({'EMCC_FORCE_STDLIBS': 'libc++'}): + run_process([PYTHON, EMCC, 'main.cpp', '-s', 'MAIN_MODULE=1', '-s', 'EXPORT_ALL', + '--embed-file', 'libside.wasm']) + out = run_js('a.out.js', assert_returncode=None, stderr=STDOUT) + self.assertContained('Exception catching is disabled, this exception cannot be caught.', out) + self.assertContained('note: in dynamic linking, if a side module wants exceptions, the main module must be built with that support', out) + def test_debug_asmLastOpts(self): create_test_file('src.c', r''' #include From 6e6e680b73a0bc4887f34f9f0133afcfa3e4bd08 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 23 Oct 2019 15:39:47 -0700 Subject: [PATCH 2/5] fix --- src/parseTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parseTools.js b/src/parseTools.js index 1923634db5e94..8b1e44f8be5a6 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1320,7 +1320,7 @@ function makeStructuralReturn(values, inAsm) { } function makeThrow(what) { - if (ASSERTIONS && DISABLE_EXCEPTION_CATCHING) { + if (ASSERTIONS && DISABLE_EXCEPTION_CATCHING == 1) { what += ' + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."'; if (MAIN_MODULE) { what += ' + " (note: in dynamic linking, if a side module wants exceptions, the main module must be built with that support)"'; From 44ea7003702391b1ec81edd61abff8cefaf39592 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 23 Oct 2019 16:22:59 -0700 Subject: [PATCH 3/5] no fastcomp --- tests/test_other.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_other.py b/tests/test_other.py index 2f8553fa31719..db222519cdad8 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -6556,6 +6556,7 @@ def test_dlopen_rtld_global(self): self.assertContained('hello1_val by hello1:3', out) self.assertContained('hello1_val by hello2:3', out) + @no_fastcomp def test_main_module_without_exceptions_message(self): # A side module that needs exceptions needs a main module with that # support enabled; show a clear message in that case. From 473d2c8a7b2ac54b53a406e9c26c93fc43068a16 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 23 Oct 2019 16:34:33 -0700 Subject: [PATCH 4/5] fix --- tests/test_other.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_other.py b/tests/test_other.py index db222519cdad8..c8392e2106300 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -6556,7 +6556,7 @@ def test_dlopen_rtld_global(self): self.assertContained('hello1_val by hello1:3', out) self.assertContained('hello1_val by hello2:3', out) - @no_fastcomp + @no_fastcomp() def test_main_module_without_exceptions_message(self): # A side module that needs exceptions needs a main module with that # support enabled; show a clear message in that case. From a54cabc620278f4a9f53912ea8f1e9268f3622e9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 24 Oct 2019 10:17:23 -0700 Subject: [PATCH 5/5] better --- tests/test_other.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/test_other.py b/tests/test_other.py index c8392e2106300..badeba7714560 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -6592,14 +6592,23 @@ def test_main_module_without_exceptions_message(self): return 0; } ''') - run_process([PYTHON, EMCC, '-o', 'libside.wasm', 'side.cpp', '-s', 'SIDE_MODULE=1']) - with env_modify({'EMCC_FORCE_STDLIBS': 'libc++'}): - run_process([PYTHON, EMCC, 'main.cpp', '-s', 'MAIN_MODULE=1', '-s', 'EXPORT_ALL', - '--embed-file', 'libside.wasm']) + run_process([PYTHON, EMCC, '-o', 'libside.wasm', 'side.cpp', '-s', 'SIDE_MODULE=1', '-fexceptions']) + + def build_main(args): + print(args) + with env_modify({'EMCC_FORCE_STDLIBS': 'libc++abi'}): + run_process([PYTHON, EMCC, 'main.cpp', '-s', 'MAIN_MODULE=1', '-s', 'EXPORT_ALL', + '--embed-file', 'libside.wasm'] + args) + + build_main([]) out = run_js('a.out.js', assert_returncode=None, stderr=STDOUT) self.assertContained('Exception catching is disabled, this exception cannot be caught.', out) self.assertContained('note: in dynamic linking, if a side module wants exceptions, the main module must be built with that support', out) + build_main(['-fexceptions']) + out = run_js('a.out.js') + self.assertContained('catch 42', out) + def test_debug_asmLastOpts(self): create_test_file('src.c', r''' #include