Description
I've been working on updating the WebAssembly version of an app I develop to the latest release, and I've run into an odd bug after updating to Emscripten 2.0.11. When calling longjmp
to yield a coroutine in Lua, the execution appears to resume not at the setjmp
as expected, but instead after the function (chain) the longjmp
was triggered in. Here's the code that's getting run (with a bunch of print
statements for debugging):
void luaD_throw (lua_State *L, int errcode) {
struct lua_longjmp *lj = L->errorJmp;
if ((errcode >= LUA_ERRRUN && errcode <= LUA_ERREXC) && L->hookmask & LUA_MASKERROR)
luaD_callhook(L, LUA_HOOKERROR, -1);
if (lj) {
if (errcode == LUA_ERRRUN)
errcode = call_errfunc(L);
printf("throw %d %p\n", errcode, lj);
showStackTrace();
lj->status = errcode;
LUAI_THROW(L, lj); // macro for longjmp(lj->b, 1)
}
else {
L->status = cast_byte(errcode);
if (G(L)->panic) {
resetstack(L, errcode);
lua_unlock(L);
G(L)->panic(L);
}
exit(EXIT_FAILURE);
}
}
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
struct lua_longjmp lj;
lj.status = 0;
lj.previous = L->errorJmp; /* chain new error handler */
L->errorJmp = &lj;
int status = setjmp((&lj)->b);
printf("rawrunprotected_setjmp %d\n", status);
if (status == 0) {
printf("rawrunprotected starting\n");
lj.status = (*f)(L, ud);
// after longjmp, execution resumes here
printf("rawrunprotected ok\n");
} else printf("longjmp triggered\n");
showStackTrace();
printf("rawrunprotected %d %p\n", lj.status, &lj);
L->errorJmp = lj.previous; /* restore old error handler */
return lj.status;
}
When this runs, I get output in the console similar to this:
throw 1 0xab9e60
rawrunprotected ok
rawrunprotected 0 0xab9e60
I'd expect the execution to restart at the setjmp
call (double-returning, with a value of 1 in this case), but instead it continues from after the function's called.
I'm not sure why this is happening at all. The last version I tested this with was 1.40.1, which worked just fine (it's currently in production as well). I don't really have much time to try to bisect this issue right now, but I might be able to check later.
The code I'm using (minus the print statements) is available at MCJack123/craftos2-lua. It's based on Lua 5.1.5, with a number of patches including a fix for yielding across C-calls. I've also attached the built Lua library (with prints) if desired: liblua.a.gz
I'm running Emscripten 2.0.11 on macOS 11.0 x64, using emsdk to download the tools.