lua-users home
lua-l archive

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


Chris Cummings <chrisc@mediamolecule.com> writes:

> I've searched on the bugs list but can't find this anywhere. Was
> wondering if somebody could advise if my interpretation of this issue
> is correct.
>
> I spent the past day or so trying to track down weird memory trampling in our LUA integration. As you might expect, the __gc function for one of our object types wasn't being called, and as a result various areas of the game still held a pointer to it, which eventually led to them attempting to access dodgy data.
>
> As far as I can see, whether an object is added for finalisation
>depends on the result of the function luaC_checkfinalizer getting
>called, which checks for an __gc metafunction and if so, adds it to the
>finobj list. However, this is only done at the point at which you set
>the metatable, inside lua_setmetatable:

[...]

> As a result, if you set the metatable of an object, then later modify
> that table, the __gc metamethod is never detected, and the object will
> not be marked for finalization.
>
> The fix from my side is obviously just to set the meta table after
> filling it in, but it seems like a bit of an issue, as there's nothing
> anywhere to stop you modifying the meta table after it's been set.
>
> Or have I totally missed something :)

I think you have most everything there.  The only thing you are missing
is the fact that this behavior is documented.  Section 2.5.1 of the
reference manual:

   For an object (table or userdata) to be finalized when collected, you
   must /mark/ it for finalization. You mark an object for finalization
   when you set its metatable and the metatable has a field indexed by
   the string "__gc". Note that if you set a metatable without a __gc
   field and later create that field in the metatable, the object will
   not be marked for finalization. However, after an object has been
   marked, you can freely change the __gc field of its metatable.

-- 
Michael Welsh Duggan
(mwd@cert.org)