lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



>> though I can't narrow it to one script, it's always a combination of scripts resulting in a
>> crash inside lua_close where the 'L' lua_State is 0xfeeefeee (garbage collected)...   I
>> haven't traced it yet (will tonight) but it seems like there is a luabind object on the stack
>> still referencing one of the dead threads that I lua_removed, and which apparently was
>> soon after garbage collected. 

I found this problem, so am posting here in case anyone else has it as well...
The problem was that sometimes the app would crash on lua_close, inside of some luabind stuff referencing a lua_State (the thread ptr returned by lua_newthread) that was garbage collected already.

My problem was that I was calling luabind::call_function and luabind::globals with my thread state (t), instead of with the interpreter's state (L)

// brakes on lua_close:
t = lua_newthread( L );
luabind::object class_constructor_function = luabind::globals(L)[classname];
mActorPtr = luabind::call_function<Actor*>( class_constructor_function );
mActorObj = luabind::object( L, mActorPtr );

// runs without crashes
t = lua_newthread( L );
luabind::object class_constructor_function = luabind::globals(L)[classname];
mActorPtr = luabind::call_function<Actor*>( class_constructor_function );
mActorObj = luabind::object( L, mActorPtr );


sorry for the luabind post here...  though I suppose the _idea_ applies to functions in lua as well, i.e. don't use the thread to access globals, and don't store the thread in with objects that will be GC'd after you GC your thread...  since during deletion those objects could access the invalid memory inside the already deleted thread at that point...

just wanted to tie up my original post.. all problems have been solved, thanks everyone.

On 10/31/06, subatomic < kevin@subatomicglue.com> wrote:
Thanks Rici,

I did get it working using lua_setfield (basically the same as lua_setglobal) as a line-by-line replacement for luaL_ref.   I use sprintf( name, "%x", threadptr ) to create a unique name for it.  This seems to create the reference count increment to keep the thread from being GC'd...   Really strange. 

Any ideas what changed between 5.0 and 5.1 to cause luaL_ref not to work?  Seems funny that luabind would cause the issue, I'm using the same version (cvshead) of luabind as I was using in 5.0.3...  So if luabind is somehow stomping the luaL_ref results now, it should have stomped them before right?

>> The other thing is that there is only one garbage collector.
makes sense, thanks for pointing it out.

>> The comment about having to collect actors before their thread is
>> deleted suggests that something is wrong with your finalizer model, if
>> you actually experienced the crash to which you refer.

Could you point me to some information about "finalizer models" ?   I'm not sure what to look for on this, and searching google doesn't turn anything up.  Are you refering to the way I close down the app?   I do get a crash %50 of the time in lua_close, depending on what scripts are run.  though I can't narrow it to one script, it's always a combination of scripts resulting in a crash inside lua_close where the 'L' lua_State is 0xfeeefeee (garbage collected)...   I haven't traced it yet (will tonight) but it seems like there is a luabind object on the stack still referencing one of the dead threads that I lua_removed, and which apparently was soon after garbage collected.   I suspect I just have to find the luabind object and kill it before forcing the removal of its thread...


thanks


On 10/31/06, Rici Lake < lua@ricilake.net> wrote:

On 31-Oct-06, at 3:56 AM, subatomic wrote:

> Thumbing through the 5.1 ref manual, I tried this instead of luaL_ref:
>
> lua_setfield(L, LUA_GLOBALSINDEX, "bok");
>
> and it seems to work (my thread is not garbage collected).
>
> I don't like the string lookup, and I also wonder about the best way
> to generate a unique string-per-thread (just convert the thread ptr to
> string??). seems hacky, I really liked the luaL_ref way of doing
> this... I'd still be very interested to hear what people know about
> all this, and what way (other than the stack) should I ref my threads
> to save them from the perils of the GC.

I took a glance at your code, but it's not clear to me what might be
going wrong. I'd check to make sure that the thread is still in the
registry where you put it, in case perhaps luabind is playing some
games with the registry. (lua_rawgeti(L, LUA_REGISTRYINDEX,
thread_reference) will push it onto the stack.)

A couple of notes, though.

First, I think you should be less nervous about just keeping your
threads on the Lua stack. It's not the C stack, and its capacity is
pretty well what you want it to be (it's just a malloc()'d array); use
lua_checkstack or luaL_checkstack to expand it to an appropriate size).
You could call lua_gettop(L) after you push the thread onto the stack
in order to get the stack index, which would work like your
thread_reference, and you can delete a single element from the stack
with something like:

   lua_pushnil(L);
   lua_replace(L, index);

That will preserve stack indexes. You could also thread a free list
through the deleted entries, luaL_ref() style, by pushing an integer
instead of nil:

   lua_pushinteger(L, mFree);
   lua_replace(L, index);
   mFree = index;

   // To make a new thread:
   lua_newthread(L);
   if (mFree != 0) {
     int tmp = mFree; mFree = lua_tointeger(L, mFree); lua_replace(L,
tmp);
   }

The other thing is that there is only one garbage collector. You cannot
garbage collect threads independently. When you call:

   lua_gc(some_state, GCCOLLECT, 0);

it will garbage collect the entire Lua universe to which some_state
belongs, using some_state to call finalizers. (It also will guarantee
that some_state is not itself collected, in case there is no other
reference to it; other than that, it doesn't make that much difference
which state you use, although I'd tend to use the main state.)

The comment about having to collect actors before their thread is
deleted suggests that something is wrong with your finalizer model, if
you actually experienced the crash to which you refer.



--
Kevin Meinert
http://www.subatomicglue.com



--
Kevin Meinert
http://www.subatomicglue.com