Longjmp failure with emscripten-fastcomp

231 Views Asked by At

I was trying to use setjmp/longjmp on a C++ project compiled with emscripten (version 1.39.16-fastcomp, can't use WebAssembly), and I came across instances of the program crashing after longjmp. I tried compiling in WebAssembly just for reference and the crash went away, so it looks like a bug on emscripten side. Maybe someone can provide a workaround.

Here's a snippet that reproduces the bug:

#include <cstdlib>
#include <cstdio>
#include <csetjmp>
#include <emscripten.h>

jmp_buf buffer;
int iterations;

void check() {
  emscripten_sleep(100);
  if (iterations < 10) {
    printf("~ jump attempt ~\n");
    longjmp(buffer, 1);
  }
}

void run() {
  printf("%d\n", iterations);
  check();
}

int main() {
  if (setjmp(buffer) == 0) {
    iterations = 0;
  } else {
    iterations++;
  }
  run();
  return 0;
}

And here are the flags used for compilation: emcc -O0 -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 -s WASM=0 c.cpp -o c.js

In essence, longjmp() is used to increment the counter, and the program should enumerate the numbers from 0 to 10 with "~ jump attempt ~" mixed in between.

However, when running c.js with node, I get the following output:

0
~ jump attempt ~
1
undefined
undefined

/Users/tsr/dev/c.js:89
   throw ex;
   ^
abort(undefined) at Error
    at jsStackTrace
    at stackTrace
    at abort
    at emterpAssert
    at emterpret
    at emterpret
    at _setThrew
    at asm._setThrew
    at _longjmp
    at emterpret
This error happened during an emterpreter-async operation. Was there non-emterpreted code
on the stack during save (which is unallowed)? If so, you may want to adjust
EMTERPRETIFY_BLACKLIST, EMTERPRETIFY_WHITELIST. For reference, this is what the stack
looked like when we tried to save it: 2,Error
    at Object.handle
    at _emscripten_sleep
    at emterpret
    at emterpret
    at emterpret
    at Array.__Z3runv
    at dynCall_v
    at invoke_v
    at emterpret
    at Object.asm.emterpret
make: *** [c.js_run] Error 7

The first call to longjmp() seems to have worked, since the number "1" was printed, but then the program crashes somewhere in the emscripten_sleep (adding prints around the call makes it certain).

I'm quite puzzled as to why this does not work, especially since there are other setjmp/longjmp constructs that EMTERPRETER is capable of handling perfectly well.

0

There are 0 best solutions below