[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Heap overflow in luaH_get
- From: Roberto Ierusalimschy <roberto@...>
- Date: Thu, 9 Jul 2020 11:01:20 -0300
> OK. I think I see some of what's going on with this one.
>
> The generational GC code seems to be assuming that a G_OLD1 object must
> be somewhere between g->survival and g->reallyold, or between g->finobj
> and g->finobjrold.
>
> But what happens in this case is that some table with an age of OLD1 has
> a metatable with a __gc metamethod, and when GCTM is being called for
> it, it gets moved back to the allgc list _at the front_, while remaining
> G_OLD1 (this is in udata2finalize).
>
> But since the table is not between g->survival and g->reallyold, and
> nevertheless is only OLD1 (and its metatable is at this point only
> SURVIVAL and white), it's not being processed by markold. Also, at some
> point in correctgraylist, the table was changed from grey to black while
> its metatable remained white. This results in the metatable being freed
> before the object that references it, hence the later crash.
Exactly! I guess the correction is moving its age back to OLD0, but
I have to check that. Similar problems should occurr with other ages.
Usually, an object's metatable is set right after its creation,
so the object is still new and everything works fine. In the
crashing code, the «setmetatable({}, ...)» looks like the metable
is being set right after the «{}», but the code to create the
metatable is long and slow, aging the table.
-- Roberto