lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I managed to find a small(-ish) reproducing case.

Run the following in lua 5.4.3 compiled with assertions and a lua_assert will trigger.

local f0 = function ()
  local c0 = {233}
  local c100 = 100
  local c101 = 101
  local c102 = 102
  local c103 = 103
  local c104 = 104
  local c105 = 105
  local c106 = 106
  local c107 = 107
  local c108 = 108
  local c109 = 109
  local c110 = 110
  local c111 = 111
  local c112 = 112
  local c113 = 113
  local c114 = 114
  local c115 = 115
  local c116 = 116
  local c117 = 117
  local c118 = 118
  local c119 = 119
  local c120 = 120
  local c121 = 121
  local c122 = 122
  local c123 = 123
  local c124 = 124
  local c125 = 125
  local c126 = 126
  local c127 = 127
  local c128 = 128
  local c129 = 129
  local c130 = 130
  local c131 = 131
  local c132 = 132
  local c133 = 133
  local c134 = 134
  local c135 = 135
  local c136 = 136
  local c137 = 137
  local c138 = 138
  local c139 = 139
  local c140 = 140
  local c141 = 141
  local c142 = 142
  local c143 = 143
  local c144 = 144
  local c145 = 145
  local c146 = 146
  local c147 = 147
  local c148 = 148
  local c149 = 149
  local c150 = 150
  local c151 = 151
  local c152 = 152
  local c153 = 153
  local c154 = 154
  local c155 = 155
  local c156 = 156
  local c157 = 157
  local c158 = 158
  local c159 = 159
  local c160 = 160
  local c161 = 161
  local c162 = 162
  local c163 = 163
  local c164 = 164
  local c165 = 165
  local c166 = 166
  c0[1234567] = c166
  c166 = c0
end

a29 = f0()

-Alex Light

On Fri, Feb 11, 2022 at 4:44 PM Alex Light <allight@google.com> wrote:
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