lua-users home
lua-l archive

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


Adam D. Moss wrote:
> >I'm occasionally seeing one of these in 5.1w5:
> >
> >run: lvm.c:427: luaV_execute: Assertion `!(((o1)->tt) >= 4) || 
> >((((o1)->tt) == (o1)->value.gc-> && 
> >!(((o1)->value.gc)->gch.marked & ((L->l_G)->currentwhite ^ ((1<<(0)) | 
> >(1<<(1)))) & ((1<<(0)) | (1<<(1)))))' failed.
> Hmm, sometimes it's this:
> run: lgc.c:86: reallymarkobject: Assertion `!(((uv->v)->tt) >= 4) || 
> (((uv->v)->tt) == (uv->v)->value.gc->' failed.

This indicates that the TValue a Lua function upvalue points to
has gotten out of sync with the GC object it points to (the types
don't match). This usually means that the memory of the object has
been freed, but the upvalue is still live and pointing to garbage
(probably reused by some other object).

Guessing from previous GC bugs this suggests taking a closer look
at the write barriers for upvalues. There are only a handful of
places where upvalues are written. All of them do have barrier
functions, though.

But I found something suspicious: luaF_close() is the only place
where luaC_linkupval() is ever called. And both functions take care
of the same write barrier (huh?). I think the isgray() part of
luaC_linkupval() is never executed, since the upvalue can only be
either black or white after the isgray() check in luaF_close.

[The duplicate write barrier was added to luaF_close() between
5.1w4 and 5.1w5. Was there a related bug report on the list?]

However I'm not entirely sure my analysis is correct. Maybe I
missed a subtle point (upvalues cannot form cycles, right?).

The interesting things to know for any further analysis would be
whether the upvalue in question is closed or open before the
assertion and whether the upvalue originally pointed to a stack
entry in a different coroutine (remarkupval() should take care
of the dead coroutine case, though).