Traps are not catchable by Wasm's try-catch or try_table. If you are going to catch them in JS that calls Wasm functions, you can (because traps surface as WebAssembly.RuntimeError), but I don't think you can 'reenter' the Wasm code that trapped. I'm not sure if I understand your plans correctly though.
On Monday, September 15, 2025 at 1:41:28 AM UTC-7 [email protected] wrote: > > While writing this mail,I realised a possible short-cut to let me get > the test harness > > running more quickly, without having to generate a wrapper for hundreds > of different > > functions, with thousands of associated data types and constants. It > goes like this: > > > > The calls to the library from the test harness are generated by C > macros, and I can > > add code to those for the WebAssembly build. So it appears I could use > EM_ASM() > > to create JavaScript error handlers at each of those call sites, as part > of the test > > harness source. I could then statically link the library and the test > harness for running > > tests. Is that plausible? > > Over the weekend I realised the difficulty with that: I'd have to get all > the arguments into JavaScript variables, pass them into the calls inside > the try/catch blocks, and then get them back into Emscripten C/C++ > variables. Since they contain loads of arrays, C struts and strings, this > amounts to generating a wrapper anyway. > > Alternatively, will catching exceptions with -fwasm-exceptions allow me > to catch out-of-bounds exceptions in Emscripten-compiled C++? > > Thanks in advance, > > John > > On Fri, Sep 12, 2025 at 4:02 PM John Dallman <[email protected]> wrote: > >> > OK, what I want to do isn't possible in Emscripten. >> >> It looks like it is, actually, but it's a bit complicated. Here's the >> scheme: am I requiring anything that doesn't exist? >> >> I have a great big math library that I want to make available in >> WebAssembly form, as a commercial product. It is written in C and C++, and >> runs on Android, iOS, Linux, macOS and Windows. Its heritage is from 1980s >> and 1990s technical computing, but it is still going strong as a commercial >> product. The immediate customers for it want to call it from C/C++ code >> that they already use on other platforms (mostly Linux and Windows), rather >> than from JavaScript. >> >> This math library has a test harness, also written in C and C++. The test >> cases are *not* written in C/C++, but in interpreted LISP, >> because that's quite suitable for handling the data that the library >> works with, plus it was easy to write our own portable implementation of >> the language. >> >> When you run the test harness, it looks for a LISP file to run and starts >> interpreting it, which usually starts by reading a lot more LISP files to >> set up a working environment. It then starts reading test scripts and >> making the calls to the math library that they request. The test harness >> does not exit until it has finished running everything it was given, or it >> hits an unrecoverable error. On its existing platforms, it can recover from >> SIGSEGV, SIGPFE, and other run-time errors, aborting the test that caused >> them and continuing with the subsequent test(s). >> >> That last part is the problem with a naive WebAssembly implementation, >> where the library and the test harness are statically linked together. That >> means there's no opportunity for a JavaScript error handler to get involved >> before exceptions caused by access violations come flying out of the top of >> the test harness. By then, the call stack is gone, and there's no way to >> recover from the exception and continue with the next test. >> >> That's where I'd got to when I wrote " . . . what I want to do isn't >> possible in Emscripten." I've had what seem like better ideas since then. >> >> WebAssembly "modules" are, as far as I understand, kind of like Windows >> DLLs or Linux shared libraries. There's a difference in that you can't link >> a module against other modules: inter-module calls have to go via >> JavaScript. Is that correct? >> >> I was slow to realise that I can put JavaScript error handlers into any >> JavaScript layer. To take advantage of that, I would link my math library >> as a module, and its test harness as the main program. The test harness >> would call JavaScript code, which would call the library from within a >> try/catch block, catch exceptions, call the library's "tidy up" functions, >> and return an error code to the test harness. That lets the test harness >> recover from exceptions and move on to the next test. It also means I need >> to create a JavaScript wrapper for the whole of the library's API, which is >> a bit of a big job, but makes the library more generally usable in >> WebAssembly code. >> >> While writing this mail,I realised a possible short-cut to let me get the >> test harness running more quickly, without having to generate a wrapper for >> hundreds of different functions, with thousands of associated data types >> and constants. It goes like this: >> >> The calls to the library from the test harness are generated by C macros, >> and I can add code to those for the WebAssembly build. So it appears I >> could use EM_ASM() to create JavaScript error handlers at each of those >> call sites, as part of the test harness source. I could then statically >> link the library and the test harness for running tests. Is that plausible? >> >> Thanks in advance, >> >> John >> >> >> >> >> On Thu, Sep 11, 2025 at 3:00 PM John Dallman <[email protected]> wrote: >> >>> OK, what I want to do isn't possible in Emscripten. >>> >>> Thanks, everyone. >>> >>> John >>> >>> On Tue, Sep 9, 2025 at 7:37 AM Heejin Ahn <[email protected]> wrote: >>> >>>> Correct. Both Emscripten and Wasm SjLj handling requires the setjmp >>>> point to be "lower" than the longjmp point, because both use exceptions to >>>> simulate setjmp-longjmp. >>>> So this works: >>>> ``` >>>> static jmp_buf buf; >>>> >>>> void bar() { >>>> } >>>> >>>> int main() { >>>> int jmpval = setjmp(buf); >>>> if (jmpval == 0) { >>>> printf("first call\n"); >>>> } else { >>>> printf("second call\n"); >>>> exit(0); >>>> } >>>> bar(); >>>> return 0; >>>> } >>>> ``` >>>> >>>> But this does NOT work: >>>> ``` >>>> static jmp_buf buf; >>>> >>>> void foo() { >>>> int jmpval = setjmp(buf); >>>> if (jmpval == 0) { >>>> printf("first call\n"); >>>> } else { >>>> printf("second call\n"); >>>> exit(0); >>>> } >>>> } >>>> >>>> void bar() { >>>> longjmp(buf, 1); >>>> } >>>> >>>> int main() { >>>> foo(); >>>> bar(); >>>> return 0; >>>> } >>>> ``` >>>> >>>> Because by the time longjmp is called, foo's call stack has been >>>> destroyed. >>>> >>>> On Mon, Sep 8, 2025 at 4:31 PM 'Sam Clegg' via emscripten-discuss < >>>> [email protected]> wrote: >>>> >>>>> If you want to use `longjmp` in emscripten to get back to start of the >>>>> failing test, we have two setjmp/longjmp mechanism. (1) The old >>>>> emscripten >>>>> method (2) The method using wasm exception handling. >>>>> >>>>> However, I believe that in both cases the target of the long jump has >>>>> to be above the caller on the stack. That is, once you unwind the stack >>>>> all of the way it will no longer be possible to `longjmp` to the target >>>>> in >>>>> question since its no longer on the stack. @Heejin Ahn can you >>>>> confirm this? >>>>> >>>>> If that is correct then you will need to some kind of alternative >>>>> mechanism when running in emscrpten. Something like this maybe: >>>>> >>>>> ``` >>>>> void run_death_test(death_test_fn_t fn) { >>>>> #ifdef __EMSCRIPTEN__ >>>>> EM_ASM({ >>>>> try { >>>>> ...call_fn_from_js.. >>>>> report_failure_to_die() >>>>> } catch (e) { >>>>> report_success_if_e_looks_good(e) >>>>> } >>>>> }) >>>>> #else >>>>> setup_longjmp_target(): >>>>> fn(); >>>>> #endif >>>>> } >>>>> ``` >>>>> >>>>> On Mon, Sep 8, 2025 at 4:17 PM Sam Clegg <[email protected]> wrote: >>>>> >>>>>> >>>>>> >>>>>> On Mon, Sep 8, 2025 at 3:40 AM John Dallman <[email protected]> >>>>>> wrote: >>>>>> >>>>>>> > Is the test harness and the library-under-test designed to be >>>>>>> compiled into the >>>>>>> > same executable? >>>>>>> >>>>>>> Yes. We prefer to have the library-under-test be a shared object or >>>>>>> Windows DLL, on platforms where that's possible, but we can have the >>>>>>> harness and the library linked together, and that's what I'm planning >>>>>>> to do >>>>>>> for WebAssembly. I'm trying to avoid producing a JS wrapper for an API >>>>>>> with >>>>>>> hundreds of functions, hundreds of structs, and thousands of constants. >>>>>>> It >>>>>>> also passes lots of pointers to code and data through the interface. My >>>>>>> customers who want a WebAssembly version of the library already have >>>>>>> C/C++ >>>>>>> or Swift code that calls it and want to use it that way. >>>>>>> >>>>>>> > i.e. on other platforms does it somehow catch and recover from >>>>>>> sefaults? >>>>>>> >>>>>>> Yes.On platforms with signals, those are turned on for segmentation >>>>>>> faults (and for some other signals, depending on the platform). The >>>>>>> code is >>>>>>> C, which sets regular checkpoints with setjmp() and the signal handling >>>>>>> function longjmp()s to the latest checkpoint with a "test aborted" >>>>>>> value. >>>>>>> That's the basic idea, though it's rather more complicated in practice. >>>>>>> >>>>>> >>>>>> Oh wow, `longjmp` out of your signal handler sounds pretty gnarly. >>>>>> It's going to be even more gnarly trying to make that work with >>>>>> emscripten-generated code, but maybe not impossible? >>>>>> >>>>>> Are there segfault tests limited in number? i.e. would it be >>>>>> possible to choose a different approach when running on the web (just >>>>>> for >>>>>> these few tests)? >>>>>> >>>>>>> >>>>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "emscripten-discuss" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to [email protected]. >>>>> To view this discussion visit >>>>> https://groups.google.com/d/msgid/emscripten-discuss/CAL_va29WgYahkgoafxhXGs%2BPhfpP-o6GzQSgaTA3xRGhdPKRNg%40mail.gmail.com >>>>> >>>>> <https://groups.google.com/d/msgid/emscripten-discuss/CAL_va29WgYahkgoafxhXGs%2BPhfpP-o6GzQSgaTA3xRGhdPKRNg%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>> . >>>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "emscripten-discuss" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> To view this discussion visit >>>> https://groups.google.com/d/msgid/emscripten-discuss/CALJpS1Nzcxx0mzS%2BxHTxrETvyGiuppeOcz68PNdjwNtYaG0YcA%40mail.gmail.com >>>> >>>> <https://groups.google.com/d/msgid/emscripten-discuss/CALJpS1Nzcxx0mzS%2BxHTxrETvyGiuppeOcz68PNdjwNtYaG0YcA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> -- You received this message because you are subscribed to the Google Groups "emscripten-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/emscripten-discuss/d915fa8d-6e78-4353-b082-39463517eba9n%40googlegroups.com.
