lua-users home
lua-l archive

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


On Fri, 10 Jul 2020 at 08:51, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote:
>
> On Fri, 10 Jul 2020 at 05:53, 云风 Cloud Wu <cloudwu@gmail.com> wrote:
> >
> > Roberto Ierusalimschy <roberto@inf.puc-rio.br> 于2020年7月9日周四 下午10:02写道:
> > >
> > > 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.
> >
> > I make a simpler test case to reveal this bug. It always crashs when I
> > define a especial allocater for lua .
> > It may be helpful.
> >
> > setmetatable ({}, { __gc = function(a) -- 1st finalizer
> >    setmetatable(a, { __gc = function (b) -- 2nd finalizer
> >      print(getmetatable(b))
> >      print(getmetatable(b).x) -- should be 42
> >      collectgarbage "step"
> >      collectgarbage "step"
> >      print(getmetatable(b))
> >      print(getmetatable(b).x) -- may crash !! use 2nd metatable after free
> >    end,
> >    x = 42,
> >    })
> >    a = nil
> >    collectgarbage "step" -- trigger 2nd finalizer
> > end })
> >
> > collectgarbage "step" -- trigger 1st finalizer
> >
>
> Nice.
> Did you try building Lua with ltests/debug support?

There is a utility in ltests called lua_checkmemory().
I tried adding this at various points in lgc.c to see if this fails.
Seems like in atomic() if I do this:

lua_checkmemory(L);
g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
lua_checkmemory(L);

The second checkmemory fails at this line:

static void checkobject (global_State *g, GCObject *o, int maybedead,
                         int listage) {
  if (isdead(g, o))
    lua_assert(maybedead);

called from:

/* check 'allgc' list */
maybedead = (GCSatomic < g->gcstate && g->gcstate <= GCSswpallgc);
checklist(g, maybedead, 0, g->allgc, g->survival, g->old, g->reallyold);