There are several asserts that compare against
L->stack_last in different parts of lua.
In luaV_execute there is this assert on line 1162
lua_assert(base <= L->top && L->top < L->stack_last);
In the 'Protect' macro done before the vmbreak we sometimes set L->top = ci->top.
When we set up ci in luaD_precall and other places we only ensure that
lua_assert(ci->top <= L->stack_last);
It's also possible for ci->top == L->stack_last depending on the exact sequence of input stack-frames. (Unfortunately, I can't share the only repro case I found).
I believe the assert in luaV_execute should be `lua_assert(base <= L->top && L->top <= L->stack_last);`
<set watchpoint on L->stack_last to catch realloc>
(lldb) bt
* thread #1, name = 'interpreter', stop reason = watchpoint 1
* frame #0: 0x000055555588093f interpreter`luaD_reallocstack(L=0x000056f67fc22a28, newsize=189, raiseerror=1) at ldo.c:211:23
frame #1: 0x00005555558813c4 interpreter`luaD_growstack(L=0x000056f67fc22a28, n=168, raiseerror=1) at ldo.c:241:14
frame #2: 0x00005555558873e1 interpreter`luaD_precall(L=0x000056f67fc22a28, func=0x000056f67fc584e0, nresults=1) at ldo.c:547:7
frame #3: 0x0000555555939454 interpreter`luaV_execute(L=0x000056f67fc22a28, ci=0x000056f67fc63920) at lvm.c:1626:22
frame #4: 0x0000555555887d1d interpreter`ccall(L=0x000056f67fc22a28, func=0x000056f67fc583f0, nResults=0, inc=65537) at ldo.c:580:5
frame #5: 0x0000555555887d98 interpreter`luaD_callnoyield(L=0x000056f67fc22a28, func=0x000056f67fc583f0, nResults=0) at ldo.c:598:3
frame #6: 0x0000555555868b3a interpreter`f_call(L=0x000056f67fc22a28, ud=0x00007fffffffc368) at lapi.c:1031:3
frame #7: 0x0000555555880456 interpreter`luaD_rawrunprotected(L=0x000056f67fc22a28, f=(interpreter`f_call at lapi.c:1029), ud=0x00007fffffffc368) at ldo.c:144:3
frame #8: 0x0000555555889fda interpreter`luaD_pcall(L=0x000056f67fc22a28, func=(interpreter`f_call at lapi.c:1029), u=0x00007fffffffc368, old_top=80, ef=64) at ldo.c:895:12
frame #9: 0x00005555558682eb interpreter`lua_pcallk(L=0x000056f67fc22a28, nargs=0, nresults=0, errfunc=3, ctx=0, k=0x0000000000000000) at lapi.c:1057:14
frame #10: 0x000055555584c9da interpreter`docall(L=0x000056f67fc22a28, narg=0, nres=0) at lua.c:159:12
frame #11: 0x000055555584c946 interpreter`dochunk(L=0x000056f67fc22a28, status=0) at lua.c:194:34
frame #12: 0x000055555584c919 interpreter`dostring(L=0x000056f67fc22a28, s="loadfile(\"/tmp/md5.luac\")()", name="=(command line)") at lua.c:205:10
frame #13: 0x000055555584c651 interpreter`runargs(L=0x000056f67fc22a28, argv=0x00007fffffffd2e8, n=7) at lua.c:334:20
frame #14: 0x000055555584bac0 interpreter`pmain(L=0x000056f67fc22a28) at lua.c:624:8
frame #15: 0x0000555555886d5d interpreter`luaD_precall(L=0x000056f67fc22a28, func=0x000056f67fc583b0, nresults=1) at ldo.c:535:11
frame #16: 0x0000555555887cc7 interpreter`ccall(L=0x000056f67fc22a28, func=0x000056f67fc583b0, nResults=1, inc=65537) at ldo.c:578:13
frame #17: 0x0000555555887d98 interpreter`luaD_callnoyield(L=0x000056f67fc22a28, func=0x000056f67fc583b0, nResults=1) at ldo.c:598:3
frame #18: 0x0000555555868b3a interpreter`f_call(L=0x000056f67fc22a28, ud=0x00007fffffffd188) at lapi.c:1031:3
frame #19: 0x0000555555880456 interpreter`luaD_rawrunprotected(L=0x000056f67fc22a28, f=(interpreter`f_call at lapi.c:1029), ud=0x00007fffffffd188) at ldo.c:144:3
frame #20: 0x0000555555889fda interpreter`luaD_pcall(L=0x000056f67fc22a28, func=(interpreter`f_call at lapi.c:1029), u=0x00007fffffffd188, old_top=16, ef=0) at ldo.c:895:12
frame #21: 0x00005555558682eb interpreter`lua_pcallk(L=0x000056f67fc22a28, nargs=2, nresults=1, errfunc=0, ctx=0, k=0x0000000000000000) at lapi.c:1057:14
frame #22: 0x000055555584b7f9 interpreter`main(argc=7, argv=0x00007fffffffd2e8) at lua.c:653:12
frame #23: 0x00007ffff7d088d3 libc.so.6`__libc_start_main + 243
frame #24: 0x000055555584b6ea interpreter`_start at start.S:120
(lldb) finish
... (steps + finishes)
Process 3610010 stopped
* thread #1, name = 'interpreter', stop reason = step in
frame #0: 0x000055555588774c interpreter`luaD_precall(L=0x000056f67fc22a28, func=0x000056f67fcc2160, nresults=1) at ldo.c:552:18
549 ci->nresults = nresults;
550 ci->u.l.savedpc = p->code; /* starting point */
551 ci->top = func + 1 + fsize;
-> 552 ci->func = func;
553 L->ci = ci;
554 for (; narg < nfixparams; narg++)
555 setnilvalue(s2v(L->top++)); /* complete missing arguments */
(lldb) p ci->top
(StkId) $4 = 0x000056f67fcc2bf0
(lldb) p L->stack_last
(StkId) $5 = 0x000056f67fcc2bf0
(lldb)
-Alex Light