Crash on GC callback

Issue #2 resolved
juan_batovi
created an issue

Given the following hierarchy:

class Foo {

};

class Base {
public:
    const Foo& getFoo() const {
        return mFoo;
    }

private:
    Foo mFoo;
};

class Derived: public Base {
public:
    virtual ~Derived(){};
};

OOLUA_PROXY(Foo)
OOLUA_PROXY_END
OOLUA_EXPORT_FUNCTIONS(Foo)
OOLUA_EXPORT_FUNCTIONS_CONST(Foo)

OOLUA_PROXY(Base)
    OOLUA_MEM_FUNC_CONST(const Foo&, getFoo)
OOLUA_PROXY_END
OOLUA_EXPORT_FUNCTIONS(Base)
OOLUA_EXPORT_FUNCTIONS_CONST(Base, getFoo)

OOLUA_PROXY(Derived, Base)
OOLUA_PROXY_END
OOLUA_EXPORT_FUNCTIONS(Derived)
OOLUA_EXPORT_FUNCTIONS_CONST(Derived)

The next Lua code creates a crash on OOLua GC callback when trying to delete the Foo instance:

local derived = Derived.new()
local foo = derived:getFoo()

It doesn't happen if a public virtual destructor is added to the base class Base (that's the workaround I found). Furthermore, the next Lua code with the the hierarchy above, doesn't have any issues:

local base = Base.new()
local foo = base:getFoo()

The deletion I mentioned occurs in oolua_registration.h:

template<typename T>
struct garbage_collect
{
    static int gc(lua_State * vm)
    {
        Lua_ud *ud = static_cast<Lua_ud*>(lua_touserdata(vm, 1));
        if( ud->flags & GC_FLAG )delete static_cast<T*>(ud->void_class_ptr);
        return 0;
    }
};

OOLua 2.0.0.beta3 Lua 5.2.3 Xcode 5.0.2 - Apple LLVM 5.0

Comments (5)

  1. Liam Devine repo owner

    Thank you for the bug report and the minimal example. I know the reason for the error but do not yet know how to best handle the situation. Making the base virtual, adding padding to the base class or rearranging base class members will solve it but are intrusive solutions.

    My current thinking is to implement chaining as you would do with hash table collisions.

    So that I do not forget the standard section numbers which are relevant to this I have added them here: C++ 03 9.0.4 ... A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor. Similarly, a POD-union is an aggregate union that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user- defined copy assignment operator and no user-defined destructor. A POD class is a class that is either a POD-struct or a POD-union.

    C++ 03 9.2.17 A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [Note: There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment. ]

  2. Log in to comment