-
Notifications
You must be signed in to change notification settings - Fork 931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
0007 CRASH detected in debug_framepc due to a fault at or near 0x000000000000004e leading to SIGSEGV #1196
Comments
Simpler POC: function bisect(f, a, b, fa, fb)
local c = tonumber("", nil, nil)
local d, e, g, h
solve(f, a, b)
local i, j, k, l, m, n
end
function solve(f, a, b)
bisect(f, a, b, f(a), f(b))
end
function f() end
solve(f) Key points seem to be a stack overflow, combined with a trace stitch (for the dubious-looking I've not yet properly analysed the cause, but a temporary triage is: diff --git a/src/lj_debug.c b/src/lj_debug.c
index 8d8b9eb5..bfae7615 100644
--- a/src/lj_debug.c
+++ b/src/lj_debug.c
@@ -64,7 +64,7 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf))
return NO_BCPOS;
ins = cframe_pc(cf); /* Only happens during error/hook handling. */
- if (!ins) return NO_BCPOS;
+ if (!ins || ((ptrdiff_t)ins & FRAME_TYPE) != FRAME_LUA) return NO_BCPOS;
} else {
if (frame_islua(nextframe)) {
ins = frame_pc(nextframe);
@@ -95,7 +95,7 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
}
}
ins = cframe_pc(cf);
- if (!ins) return NO_BCPOS;
+ if (!ins || ((ptrdiff_t)ins & FRAME_TYPE) != FRAME_LUA) return NO_BCPOS;
}
}
pt = funcproto(fn); |
IMHO that workaround is covering up the real issue. It shouldn't end up there with a non-Lua frame and NULL nextframe -- I should probably add an assert. There's a first silent stack overflow in It have run out of time to dissect the frames in both cases. My gut feeling says to check the order of operations in |
Indeed, the first interesting event is
The error is caught by the
pc = exd.pc;
cf = cframe_raw(L->cframe);
setcframe_pc(cf, pc); Instead, all return -errcode; The logic in
We proceed to segfault in The logic to restore the outer cframe's pc could be moved from diff --git a/src/lj_snap.c b/src/lj_snap.c
index 6fda08ba..27f9c8e5 100644
--- a/src/lj_snap.c
+++ b/src/lj_snap.c
@@ -957,7 +957,8 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
lua_State *L = J->L;
/* Set interpreter PC to the next PC to get correct error messages. */
- setcframe_pc(cframe_raw(L->cframe), pc+1);
+ setcframe_pc(L->cframe, pc+1);
+ setcframe_pc(cframe_raw(cframe_prev(L->cframe)), pc);
/* Make sure the stack is big enough for the slots from the snapshot. */
if (LJ_UNLIKELY(L->base + snap->topslot >= tvref(L->maxstack))) { Alternatively, diff --git a/src/lj_trace.c b/src/lj_trace.c
index a5e316e1..f2a69cc5 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -905,8 +905,10 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
exd.J = J;
exd.exptr = exptr;
errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp);
- if (errcode)
+ if (errcode) {
+ setcframe_pc(cframe_raw(L->cframe), L);
return -errcode; /* Return negated error code. */
+ }
if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */ |
poc.txt
The text was updated successfully, but these errors were encountered: