[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: __gc metamethod bug
- From: Michael Welsh Duggan <mwd@...>
- Date: Thu, 06 Nov 2014 15:29:22 -0500
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)