Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Unset metatable when destroying C++-objects.
When using Lua 5.2's __gc or luabinds __finalize metamethods, it is possible to access userdata after its __gc metamethod has been called. Unsetting its metatable turns undefined behavior in an ordinary Lua error (LUA_ERRGCMM). Assuming CppClass is a C++-class exported by luabind, the following code triggers undefined behavior (needs Lua 5.2 for __gc support for tables): t = { } setmetatable(t, {__gc = function(t) t.cppClass:method() end}) t.cppClass = CppClass() Since "the finalizers for objects are called in the reverse order that they were marked for collection" [1], this will try to call the __index metamethod of t.cppClass after the object_rep for it (and itself) has been destroyed. The call to t.cppClass:method() results in undefined behavior (in the particular case where I noticed the bug (on VS11, Win 7 x64) it was a pure virtual function call to luabind::detail::instance_holder::get()). With this patch applied, Lua will instead issue a runtime error because of indexing an userdata without __index metamethod. See also [1]: http://www.lua.org/manual/5.2/manual.html#2.5.1 http://lua.2524044.n2.nabble.com/userdata-access-after-gc-td7643253.html
- Loading branch information