Re: Crash in wrapper_base.cpp

Nigel Atkinson <[email protected]> Fri, 08 Jul 2011 16:36:03 +1000
Newsgroups gmane.comp.lang.lua.bind.user
Message-ID <1310106963.1605.15.camel@virNatty>
On Fri, 2011-07-08 at 09:44 +1000, Nigel Atkinson wrote:
> On Thu, 2011-07-07 at 11:44 -0700, Drew McLean wrote:
> > I don't think that's the case since I'm printing at the point where I
> > unregister an object (in a common function).  And there is no loop
> > where I release a bunch at once, they each complete in their own time.
> > My global table uses the object as the key and the value.  Is there
> > something wrong with that?  I can't see why.
> > 
> >    Drew
> I can not think of any reason why using the object as a key would not
> work either.


I made a test program and it worked as expected until I added using the
objects as keys in a table. :-/

Next question is 'why?'.  However it's Friday and nearly time to go to
the pub.

Attached is my test program - it requires changing line 66 in
wrapper_base.hpp from private to protected, so it can print an error
rather than asserting.

Nigel

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2

_______________________________________________
luabind-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/luabind-user
smash.cpp (text/x-c++src, 2.7 KB)
#include <luabind/luabind.hpp>
#include <iostream>
#include <lua.hpp>
#include <vector>
#include <algorithm>

using namespace luabind;
using namespace std;

class Item;

vector<Item*> storage;

class Item
{
    public:

    int _i;

    Item( int i )
    {
        _i = i;
        cout << "Item::constructor() ";
        cout << storage.size() << endl;
        storage.push_back(this);
    }
    ~Item()
    {
        cout << "Item::destructor() ";
        storage.erase( find( storage.begin(), storage.end(), this ) );
        cout << storage.size() << endl;
    }

    virtual void overide()
    {
        cout << "Item::overide() " << _i << endl;
    }
};

class ItemWrapper: public Item, public wrap_base
{
    public:

    ItemWrapper( int i ) : Item(i) {}

    virtual void overide()
    {
        cout << "Wrapper::overide()" << endl;
        lua_State *L = m_self.state();
        m_self.get(L);

        if( !lua_isnil(L,-1))
            call<void>("overide");
        else
            cout << "Lua instance is nil" << endl;

        lua_pop(L,1);
    }
    static void default_overide( Item* ptr )
    {
        cout << "Wrapper::default_overide()" << endl;
        ptr->Item::overide();
    }
};

void run( lua_State *L, const char *script )
{
    cout << "**** Script ****" << endl << script << endl << "**** Results ****" << endl;

    if( luaL_dostring( L, script ) )
    {
        cout << lua_tostring( L, -1 ) << endl;
    }

    cout << "**** End Results ****" << endl;
}

int main()
{
    lua_State* L = lua_open();

    luaL_openlibs( L );
    luabind::open(L);

    module(L)
    [
        class_<Item, ItemWrapper>( "Item" )
        .def( constructor<int>() )
        .def_readwrite( "i", &Item::_i )
        .def( "overide", &Item::overide, &ItemWrapper::default_overide )
    ];

    run( L,
            "function Item:__finalize()\n"
            "--  print 'Item:__finalize()'\n"
            "end\n"
            "function Item:overide()\n"
            "  print( 'Item:overide() - Lua implementation', self.i)\n"
            "end\n"
       );

    run( L,
            "v = {}\n"
            "a = {}\n"
            "for i = 1,1000 do\n"
            "  obj = Item(i)\n"
            "  v[obj] = obj\n"
            "  a[i] = obj\n"
            "end\n"
       );

    run( L,
            "for i = 1,1000,5 do\n"
            "  v[a[i]] = nil\n"
            "  a[i] = nil\n"
            "end\n"
       );

    for( vector<Item*>::iterator iter = storage.begin(); iter != storage.end(); iter++ )
        (*iter)->overide();

    run( L,
            "collectgarbage()\n"
       );

    for( vector<Item*>::iterator iter = storage.begin(); iter != storage.end(); iter++ )
        (*iter)->overide();

    cout << "**** Shutdown VM ****" << endl;

    lua_close( L );

    return 0;
}