Re: Crash in wrapper_base.cpp

Drew McLean <[email protected]> Wed, 6 Jul 2011 11:41:56 -0700
Newsgroups gmane.comp.lang.lua.bind.user
Message-ID <CAGo0s8Psr_Q1DzLiZMiga=+Q8DqFAVq1V1s7dvs+HFoD4yMcRQ@mail.gmail.com>
Hey all,

It doesn't seem like my posting was sent out since it's not showing up in
the mail archives on sourceforge.  Here it is again below.  If anyone can
shed some light on this it would be really appreciated.  Thanks.

    Drew


On Sun, Jul 3, 2011 at 6:25 PM, Drew McLean <[email protected]> wrote:

> Hello,
>
> I am using Lua 0.9.1 in a custom game engine and am using the feature of
> extending C++ objects using Lua via luabind::wrap_base.  My C++ base class
> is called Agent and contains a virtual function called Update().  I have
> created a class called ScriptableAgent which extends Agent and
> luabind::wrap_base.  Lua instances of derived classes are stored in a global
> table in Lua to avoid garbage collection occurring before the object should
> be destroyed.  Once created in Lua they are passed to a C++ container which
> updates the instances each frame.  Whenever I am done with an instance it is
> removed from the container in C++ and is then removed from the global Lua
> table so that it can be garbage collected.
>
> I have come across a problem when continuously creating many instances with
> a short lifetime (this exposes the problem quickly and consistently
> anyway).  After a while, garbage collection occurs and cleans a bunch of
> them up.  Immediately after the collection, a crash occurs in the container
> update loop when updating an instance that *wasn't* garbage collected.  I
> can tell that it wasn't collected because each Agent has a unique ID and I
> print it when adding/removing it from the global Lua table, when
> adding/removing from the C++ container, when in the Lua __finalize() method
> and inside the destructor in C++.
>
> The crash occurs in wrapper_base.cpp on line 39 because obj is NULL.  The
> code around the crash:
>
>     LUABIND_API void do_call_member_selection(lua_State* L, char const*
> name)
>     {
>         object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, -1));
>         lua_pop(L, 1); // pop self
>
>         obj->crep()->get_table(L); // push the crep table    <<<<< Crash
> here because obj is NULL
>         lua_pushstring(L, name);
>         lua_gettable(L, -2);
>         lua_remove(L, -2); // remove the crep table
>
>         if (!is_luabind_function(L, -1))
>             return;
>
>         // this (usually) means the function has not been
>         // overridden by lua, call the default implementation
>         lua_pop(L, 1);
>         obj->crep()->get_default_table(L); // push the crep table
>         lua_pushstring(L, name);
>         lua_gettable(L, -2);
>         lua_remove(L, -2); // remove the crep table
>     }
>
>
>
> Here is the relevant callstack:
>
> game.exe!luabind::detail::object_rep::crep()  Line 48 + 0x26 bytes    C++
> game.exe!luabind::detail::do_call_member_selection(lua_State *
> L=0x0dc68f78, const char * name=0x0239750c)  Line 39 + 0xc bytes    C++
> game.exe!luabind::wrap_base::call<void>(const char * name=0x0239750c,
> luabind::detail::type_<void> * __formal=0x00000000)  Line 125 + 0xd bytes
> C++
> game.exe!ScriptableAgent_luabind::Update()  Line 57 + 0x16 bytes    C++
> ...
>
>
> Here is an example of the execution order which may help in demonstrating
> the problem.  The Agent instance on the callstack when the crash occurs has
> an ID of 110.  According to the log output, this Agent is still in the
> global table.
>
> ...
> Registering lua agent: 108
> AgentContainer::AddAgent(0xdd19918) [108]
> TubeTravelSequenceAgent:__finalize() [28]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [28]
> AgentContainer::RemoveAgent(0xdd590b0) [105]
> TubeTravelSequenceAgent:__finalize() [27]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [27]
> Unregistering lua agent: 105
> Registering lua agent: 109
> AgentContainer::AddAgent(0xc32a6b0) [109]
> TubeTravelSequenceAgent:__finalize() [26]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [26]
> AgentContainer::RemoveAgent(0xc2a3570) [106]
> Unregistering lua agent: 106
> Registering lua agent: 110      <<<<<<<<<<< Agent 110 added
> AgentContainer::AddAgent(0xdd55be0) [110]    <<<<<<<<<<<<<< Agent 110 added
> TubeTravelSequenceAgent:__finalize() [25]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [25]
> TubeTravelSequenceAgent:__finalize() [24]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [24]
> AgentContainer::RemoveAgent(0xdd71e18) [107]
> Unregistering lua agent: 107
> Registering lua agent: 111
> AgentContainer::AddAgent(0xdd902d0) [111]
> TubeTravelSequenceAgent:__finalize() [23]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [23]
> TubeTravelSequenceAgent:__finalize() [22]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [22]
> AgentContainer::RemoveAgent(0xdd19918) [108]
> Unregistering lua agent: 108
> ScriptableAgent:__finalize() [21]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [21]
> Registering lua agent: 112
> AgentContainer::AddAgent(0xc268a60) [112]
> TubeTravelSequenceAgent:__finalize() [108]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [108]
> TubeTravelSequenceAgent:__finalize() [107]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [107]
> TubeTravelSequenceAgent:__finalize() [106]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [106]
> TubeTravelSequenceAgent:__finalize() [105]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [105]
> TubeTravelSequenceAgent:__finalize() [104]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [104]
> TubeTravelSequenceAgent:__finalize() [103]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [103]
> TubeTravelSequenceAgent:__finalize() [102]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [102]
> TubeTravelSequenceAgent:__finalize() [101]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [101]
> TubeTravelSequenceAgent:__finalize() [100]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [100]
> TubeTravelSequenceAgent:__finalize() [99]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [99]
> TubeTravelSequenceAgent:__finalize() [98]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [98]
> TubeTravelSequenceAgent:__finalize() [97]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [97]
> TubeTravelSequenceAgent:__finalize() [96]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [96]
> TubeTravelSequenceAgent:__finalize() [95]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [95]
> TubeTravelSequenceAgent:__finalize() [94]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [94]
> TubeTravelSequenceAgent:__finalize() [93]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [93]
> TubeTravelSequenceAgent:__finalize() [92]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [92]
> TubeTravelSequenceAgent:__finalize() [91]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [91]
> TubeTravelSequenceAgent:__finalize() [90]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [90]
> TubeTravelSequenceAgent:__finalize() [89]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [89]
> TubeTravelSequenceAgent:__finalize() [88]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [88]
> TubeTravelSequenceAgent:__finalize() [87]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [87]
> TubeTravelSequenceAgent:__finalize() [86]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [86]
> TubeTravelSequenceAgent:__finalize() [85]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [85]
> TubeTravelSequenceAgent:__finalize() [84]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [84]
> TubeTravelSequenceAgent:__finalize() [83]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [83]
> TubeTravelSequenceAgent:__finalize() [82]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [82]
> TubeTravelSequenceAgent:__finalize() [81]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [81]
> TubeTravelSequenceAgent:__finalize() [80]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [80]
> TubeTravelSequenceAgent:__finalize() [79]
> ScriptableAgent_luabind::~ScriptableAgent_luabind(): [79]
> First-chance exception at 0x01cf37f6 in nanite_debug.exe: 0xC0000005:
> Access violation reading location 0x00000028.
> Unhandled exception at 0x01cf37f6 in nanite_debug.exe: 0xC0000005: Access
> violation reading location 0x00000028.
> First-chance exception at 0x01cf37f6 in nanite_debug.exe: 0xC0000005:
> Access violation reading location 0x00000028.
> Unhandled exception at 0x01cf37f6 in nanite_debug.exe: 0xC0000005: Access
> violation reading location 0x00000028.
>
>
> I have also seen another variation of this problem where the assertion in
> wrapper_base.hpp on line 124 fails.  The code around this assertion is
>
>             // get the function
>             lua_State* L = m_self.state();
>             m_self.get(L);
>             assert(!lua_isnil(L, -1));               <<<<<<< fails
>             detail::do_call_member_selection(L, name);
>
>
> I have seen that someone else has come across this problem recently but
> there was no solution suggested for it.
>
>
> http://stackoverflow.com/questions/6236827/assertion-failure-in-luabind
>
>
> Any help would be appreciated.  Let me know if you need more info.  Thanks!
>
>     Drew
>
> --
> Drew McLean
> Lead Tech Programmer
> A Priori Games
> (250) 508-3346
> www.apriorigames.com
>
>

------------------------------------------------------------------------------
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