aboutsummaryrefslogtreecommitdiff
path: root/src/lj_gc.c
diff options
context:
space:
mode:
authorMike Pall <mike>2023-04-16 18:13:48 +0200
committerMike Pall <mike>2023-04-16 18:13:48 +0200
commit1c279127050e86e99970100e9c42e0f09cd54ab7 (patch)
treeefdc67dab9c461e3122b8bf99a13157be5daf02e /src/lj_gc.c
parent8bbd58e534522a7e1ab9ee2c0d7fb723741dd089 (diff)
downloadluajit-1c279127050e86e99970100e9c42e0f09cd54ab7.tar.gz
luajit-1c279127050e86e99970100e9c42e0f09cd54ab7.tar.bz2
luajit-1c279127050e86e99970100e9c42e0f09cd54ab7.zip
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")
Diffstat (limited to 'src/lj_gc.c')
-rw-r--r--src/lj_gc.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/lj_gc.c b/src/lj_gc.c
index 2fc52ec1..6c3187c3 100644
--- a/src/lj_gc.c
+++ b/src/lj_gc.c
@@ -27,6 +27,7 @@
27#include "lj_trace.h" 27#include "lj_trace.h"
28#include "lj_dispatch.h" 28#include "lj_dispatch.h"
29#include "lj_vm.h" 29#include "lj_vm.h"
30#include "lj_vmevent.h"
30 31
31#define GCSTEPSIZE 1024u 32#define GCSTEPSIZE 1024u
32#define GCSWEEPMAX 40 33#define GCSWEEPMAX 40
@@ -521,8 +522,13 @@ static void gc_call_finalizer(global_State *g, lua_State *L,
521 hook_restore(g, oldh); 522 hook_restore(g, oldh);
522 if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g); 523 if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g);
523 g->gc.threshold = oldt; /* Restore GC threshold. */ 524 g->gc.threshold = oldt; /* Restore GC threshold. */
524 if (errcode) 525 if (errcode) {
525 lj_err_throw(L, errcode); /* Propagate errors. */ 526 ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
527 lj_vmevent_send(L, ERRFIN,
528 copyTV(L, L->top++, restorestack(L, errobj));
529 );
530 L->top--;
531 }
526} 532}
527 533
528/* Finalize one userdata or cdata object from the mmudata list. */ 534/* Finalize one userdata or cdata object from the mmudata list. */