-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Probably related to the libunwind upgrade and/or LLVM upgrade in Zig 15.
https://ziglang.org/download/0.15.1/release-notes.html#LLVM-20
Change notes for libunwind should be researched:
https://github.com/libunwind/libunwind/releases/tag/v1.8.0
I don't see any other meaningful mentions of changed behavior. I saw that .unwind_tables has been moved around a bit and now lives in the Zig Module system, I've tried adding various combinations of flags for .unwind_tables to the relevant sections of build.zig but not able to get the test passing again on linux.
Attaching GDB to an exe reproducing the test cast, I can see that we are exiting the process at the bottom of this call stack in LuaJIT. It definitely seems like something changed around the unwind tables behavior in Zig 15, need to find out what and how to replace it with the old behavior.
LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
{
if (!lua_checkstack(L, size))
lj_err_callerv(L, LJ_ERR_STKOVM, msg);
}
LJ_NOINLINE void lj_err_callerv(lua_State *L, ErrMsg em, ...)
{
const char *msg;
va_list argp;
va_start(argp, em);
msg = lj_strfmt_pushvf(L, err2msg(em), argp);
va_end(argp);
lj_err_callermsg(L, msg);
}
LJ_NOINLINE void lj_err_callermsg(lua_State *L, const char *msg)
{
TValue *frame = NULL, *pframe = NULL;
if (!(LJ_HASJIT && tvref(G(L)->jit_base))) {
frame = L->base-1;
if (frame_islua(frame)) {
pframe = frame_prevl(frame);
} else if (frame_iscont(frame)) {
if (frame_iscont_fficb(frame)) {
pframe = frame;
frame = NULL;
} else {
pframe = frame_prevd(frame);
#if LJ_HASFFI
/* Remove frame for FFI metamethods. */
if (frame_func(frame)->c.ffid >= FF_ffi_meta___index &&
frame_func(frame)->c.ffid <= FF_ffi_meta___tostring) {
L->base = pframe+1;
L->top = frame;
setcframe_pc(cframe_raw(L->cframe), frame_contpc(frame));
}
#endif
}
}
}
lj_debug_addloc(L, msg, pframe, frame);
lj_err_run(L);
}
LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L)
{
ptrdiff_t ef = (LJ_HASJIT && tvref(G(L)->jit_base)) ? 0 : finderrfunc(L);
if (ef) {
TValue *errfunc, *top;
lj_state_checkstack(L, LUA_MINSTACK * 2); /* Might raise new error. */
lj_trace_abort(G(L));
errfunc = restorestack(L, ef);
top = L->top;
if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) {
setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR));
lj_err_throw(L, LUA_ERRERR);
}
L->status = LUA_ERRERR;
copyTV(L, top+LJ_FR2, top-1);
copyTV(L, top-1, errfunc);
if (LJ_FR2) setnilV(top++);
L->top = top+1;
lj_vm_call(L, top, 1+1); /* Stack: |errfunc|msg| -> |msg| */
}
lj_err_throw(L, LUA_ERRRUN);
}
LJ_NOINLINE void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode)
{
global_State *g = G(L);
lj_trace_abort(g);
L->status = LUA_OK;
#if LJ_UNWIND_EXT
err_raise_ext(g, errcode);
/*
** A return from this function signals a corrupt C stack that cannot be
** unwound. We have no choice but to call the panic function and exit.
**
** Usually this is caused by a C function without unwind information.
** This may happen if you've manually enabled LUAJIT_UNWIND_EXTERNAL
** and forgot to recompile *every* non-C++ file with -funwind-tables.
*/
if (G(L)->panic)
G(L)->panic(L);
#else
#if LJ_HASJIT
setmref(g->jit_base, NULL);
#endif
{
void *cf = err_unwind(L, NULL, errcode);
if (cframe_unwind_ff(cf))
lj_vm_unwind_ff(cframe_raw(cf));
else
lj_vm_unwind_c(cframe_raw(cf), errcode);
}
#endif
exit(EXIT_FAILURE);
}