Skip to content

Commit b23f943

Browse files
Mike Pallmkokryashkin
authored andcommitted
Avoid assertion in case of stack overflow from stitched trace.
Reported by Sergey Bronnikov. Fixed by Sergey Kaplun. (cherry-picked from commit 1d75cd4) When we exit from a stitched trace due to the Lua stack overflow error, the Lua and JIT stacks are not synchronized, and they won't be as long as the mentioned error is raised. Because of that, we get the incorrect bytecode instruction in `debug_framepc`. This patch fixes this behavior, so the `debug_framepc` now returns `NO_BCPOS` for this case. Maxim Kokryashkin: * added the description and the test for the problem Part of tarantool/tarantool#9145
1 parent 2ab0419 commit b23f943

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

src/lj_debug.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,12 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
101101
pos = proto_bcpos(pt, ins) - 1;
102102
#if LJ_HASJIT
103103
if (pos > pt->sizebc) { /* Undo the effects of lj_trace_exit for JLOOP. */
104-
GCtrace *T = (GCtrace *)((char *)(ins-1) - offsetof(GCtrace, startins));
105-
lj_assertL(bc_isret(bc_op(ins[-1])), "return bytecode expected");
106-
pos = proto_bcpos(pt, mref(T->startpc, const BCIns));
104+
if (bc_isret(bc_op(ins[-1]))) {
105+
GCtrace *T = (GCtrace *)((char *)(ins-1) - offsetof(GCtrace, startins));
106+
pos = proto_bcpos(pt, mref(T->startpc, const BCIns));
107+
} else {
108+
pos = NO_BCPOS; /* Punt in case of stack overflow for stitched trace. */
109+
}
107110
}
108111
#endif
109112
return pos;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
local tap = require('tap')
2+
-- Test to demonstrate the incorrect LuaJIT behavior when exiting
3+
-- from a snapshot for stitched trace.
4+
local test = tap.test('lj-913-stackoverflow-stitched-trace'):skipcond({
5+
['Test requires JIT enabled'] = not jit.status(),
6+
})
7+
8+
test:plan(3)
9+
10+
-- Recursion to cause stack overflow.
11+
local function callee()
12+
-- `math.fmod()` is NYI, so trace will be stitched here.
13+
local _ = math.fmod(42, 42)
14+
callee()
15+
end
16+
17+
local st, err = pcall(callee)
18+
19+
test:ok(true, 'assertion is not triggered')
20+
test:ok(not st, 'error happened')
21+
test:like(err, 'stack overflow', 'stack overflow happened')
22+
23+
test:done(true)

0 commit comments

Comments
 (0)