Print errors from __gc finalizers instead of rethrowing them.
Finalizers are not supposed to throw errors -- this is undefined behavior. Lua 5.1 - 5.3 and (previously) LuaJIT rethrow the error. This randomly breaks some unrelated code that just happens to do an allocation. Bad. Lua 5.4 catches the error and emits a warning instead. But warnings are not enabled by default, so it fails silently. Even worse. LuaJIT (now) catches the error and emits a VM event. The default event handler function prints "ERROR in finalizer: ...". Set a custom handler function with: jit.attach(handler, "errfin")
This commit is contained in:
10
src/lj_gc.c
10
src/lj_gc.c
@@ -27,6 +27,7 @@
|
||||
#include "lj_trace.h"
|
||||
#include "lj_dispatch.h"
|
||||
#include "lj_vm.h"
|
||||
#include "lj_vmevent.h"
|
||||
|
||||
#define GCSTEPSIZE 1024u
|
||||
#define GCSWEEPMAX 40
|
||||
@@ -521,8 +522,13 @@ static void gc_call_finalizer(global_State *g, lua_State *L,
|
||||
hook_restore(g, oldh);
|
||||
if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g);
|
||||
g->gc.threshold = oldt; /* Restore GC threshold. */
|
||||
if (errcode)
|
||||
lj_err_throw(L, errcode); /* Propagate errors. */
|
||||
if (errcode) {
|
||||
ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
|
||||
lj_vmevent_send(L, ERRFIN,
|
||||
copyTV(L, L->top++, restorestack(L, errobj));
|
||||
);
|
||||
L->top--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finalize one userdata or cdata object from the mmudata list. */
|
||||
|
||||
Reference in New Issue
Block a user