lua-users home
lua-l archive

Re: Lua 5.4.0-rc5 segfault in low memory conditions

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


>>>>> "Andrew" == Andrew Gierth <andrew@tao11.riddles.org.uk> writes:
 Andrew> So my question is this:
 Andrew> The (original) test case basically does a ton of parsing in
 Andrew> which a whole lot of prototypes get generated and added to
 Andrew> other prototypes, in the context of building up one single
 Andrew> return statement.
 Andrew> Where in this are those prototypes supposed to be reached from
 Andrew> the GC? i.e. what's the intended path by which the GC is
 Andrew> supposed to find them?
Answering my own question: the top-level closure is supposed to be on
the stack (and indeed it is), and everything else should be reached
recursively from that.
But (this is while stopped in a deeply nested part of the parser, but
examining the state of the luaY_parser frame):
(gdb) print funcstate.f
27ドル = (Proto *) 0x801614200
(gdb) print *((LClosure*)L->stack[5].val.value_.p)
30ドル = {next = 0x80162e170, tt = 6 '006円', marked = 36 '$', nupvalues = 1 '001円', gclist = 0x0, p = 0x801614200, upvals = {0x0}}
So here's the closure on the stack whose prototype (p) points to the
top-level prototype created by luaY_parser. Notice that marked=36, which
is BLACK | G_OLD.
But:
(gdb) print *((LClosure*)L->stack[5].val.value_.p)->p
31ドル = {next = 0x801621d00, tt = 10 '\n', marked = 16 '020円', numparams = 0 '000円', is_vararg = 1 '001円', maxstacksize = 2 '002円', 
 sizeupvalues = 4, sizek = 0, sizecode = 4, sizelineinfo = 4, sizep = 4, sizelocvars = 0, sizeabslineinfo = 0, linedefined = 0, 
 lastlinedefined = 0, k = 0x0, code = 0x801667020, p = 0x801651b40, upvalues = 0x801621d80, 
 lineinfo = 0x801668020 "001円", '245円' <repeats 39 times>, "001円&", abslineinfo = 0x0, locvars = 0x0, source = 0x80162e170, 
 gclist = 0xa5a5a5a5a5a5a5a5}
Here's the Proto that the closure points to, and it has marked = 16
(i.e. WHITE1). So here we have a classic black->white pointer scenario,
and none of the prototypes nested under this one will be scanned because
everything stops at the black closure.
So the bug is here in luaY_parser:
 funcstate.f = cl->p = luaF_newproto(L);
 /* needs another barrier here */
 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
 luaC_objbarrier(L, funcstate.f, funcstate.f->source);
The GC forced by the memory failure happened inside luaF_newproto, and
resulted in the closure "cl" being marked both BLACK and OLD. Without a
barrier at the marked location, we have cl (black) pointing at the new
proto (white) and everything blows up later as a result.
-- 
Andrew.

AltStyle によって変換されたページ (->オリジナル) /