Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DMD GC causing segfault #9

Closed
ghost opened this issue Oct 2, 2010 · 9 comments
Closed

DMD GC causing segfault #9

ghost opened this issue Oct 2, 2010 · 9 comments
Labels

Comments

@ghost
Copy link

ghost commented Oct 2, 2010

Code here http://paste.pocoo.org/show/270340/
Back trace here http://paste.pocoo.org/show/270342/

@JakobOvrum
Copy link
Owner

I haven't been able to reproduce this bug.

Starting from the bottom of the provided snippet, could you try removing one line at a time until the bug goes away? I think that would help pinpointing where the erronous LuaObject is created.

@ryanflegel
Copy link

I have the same issue. I'm on 64-bit Ubuntu and I had to change a few "int"s to "long"s to get it to compile. All that is necessary to cause the segfault is to create a LuaState. Here's my backtrace with some more symbols:

#0 0x000000000040877c in lua_rawgeti (L=0x6bbaa0, idx=-10000, n=0) at lapi.c:573
#1 0x000000000041be10 in luaL_unref (L=0x6bbaa0, t=-10000, ref=2) at lauxlib.c:507
#2 0x00000000004058ed in luad.reference.LuaReference.__dtor() ()
#3 0x0000000000405792 in luad.base.LuaObject.__fieldDtor() ()
#4 0x0000000000452102 in rt_finalize (p=0x7ffff7edaf20, det=false) at ../../../libphobos/rt/lifetime.d:1133
#5 0x000000000045e25a in fullcollect (this=..., stackTop=) at ../../../libphobos/gc/gcx.d:2568
#6 0x000000000045e4a9 in fullcollectshell (this=...) at ../../../libphobos/gc/gcx.d:2329
#7 0x000000000045efa1 in fullCollectNoStack (this=...) at ../../../libphobos/gc/gcx.d:1300
#8 0x000000000045bfb4 in gc_term () at ../../../libphobos/gc/gc.d:133
#9 0x00000000004518ad in tryExec (dg=...) at ../../../libphobos/rt/dmain2.d:482
#10 0x0000000000451a82 in _d_run_main (argc=2, argv=0x7fffffffe338, main_func=) at ../../../libphobos/rt/dmain2.d:562
#11 0x00007ffff73d3d8e in __libc_start_main () from /lib/libc.so.6
#12 0x0000000000404e39 in _start ()

As you can see, it happens when destructing LuaReference. Here is the offending code in lapi.c:

568 LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
569   StkId o;
570   lua_lock(L);
571   o = index2adr(L, idx);
572   api_check(L, ttistable(o));
573   setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
574   api_incr_top(L);
575   lua_unlock(L);
576 }

Here are the values of the vars:
L = (lua_State *) 0x6bbaa0
*L = {next = 0x6bc8a0, tt = 152 '\230', marked = 62 '>',
status = 115 's', top = 0x0, base = 0x0, l_G = 0x6bbb58,
ci = 0x6bbd10, savedpc = 0x0, stack_last = 0x6bc0d0,
stack = 0x6bbe60, end_ci = 0x6bbe28, base_ci = 0x6bbd10,
stacksize = 45, size_ci = 8, nCcalls = 0, baseCcalls = 0,
hookmask = 0 '\000', allowhook = 1 '\001', basehookcount = 0,
hookcount = 0, hook = 0, l_gt = {value = {gc = 0x6bb700,
p = 0x6bb700, n = 3.4877082071225276e-317, b = 7059200},
tt = 5}, env = {value = {gc = 0x0, p = 0x0, n = 0, b = 0},
tt = 0}, openupval = 0x0, gclist = 0x0, errorJmp = 0x0,
errfunc = 0}
L->top = (StkId) 0x0
o = (StkId) 0x6bbbf8
n = 0
idx = -10000

It seems a bit odd to me... not sure why it's crashing.

@ryanflegel
Copy link

A little more investigation reveals that setobj2s is a macro. Here it is again, expanded:

571   o = index2adr(L, idx);
572   api_check(L, ttistable(o));
573 
574   const TValue *o2=(luaH_getnum(hvalue(o), n));
575   TValue *o1=(L->top);
576   o1->value = o2->value;
577   o1->tt=o2->tt;
578   checkliveness(G(L),o1);

576 is the offending line. If you take a look at my previous post, you'll see L->top is 0x0, so o1 is a null pointer that is being accessed.

@ryanflegel
Copy link

I believe I've found the problem. When the LuaState object is GC'd, lua_close() is called in the destructor and then afterwards the LuaReference destructor is called, which calls luaL_unref() with a now invalid lua_state.

I'm not sure what the best way to go about fixing it is, so I'll leave that to you :-).

@JakobOvrum
Copy link
Owner

Sorry for replying late,

I'm aware of the problem (also mentioned in other issues like "Calling a delegate containing a LuaFunction throws an exception"), and I decided long ago to refactor the LuaObject and LuaState objects into structs (which also makes use of LuaObject a bit more performant), but I've never gotten around to doing it.

There is a temporary solution which can help in some applications, but the problem and solution should really be mentioned in the docs (since I'm so slow in fixing it):

auto L = luaL_newstate();
auto state = new LuaState(L);

// use state

// When you're sure it's safe to close it:
lua_close(L);

(Requires that you import the C API)

The workaround has some side effects. The LuaD panic handler throwing an exception is not installed by default. See the source code of the two constructors for LuaState on how to solve this.

@ryanflegel
Copy link

No problem.

Your workaround still doesn't work because of _G and _R created in the LuaState ctor. If I manually delete these in the LuaState dtor, it fixes the crash, though. I guess _G and _R are the objects that we're getting destructed after the lua_state was closed.

I'm not sure if this fixes the underlying problem (I would guess not), as I'm not that familiar with Lua, or D for that matter, but at least for me, it seems to stop the crashing.

@JakobOvrum
Copy link
Owner

Right, nice find!

Indeed, I don't think it really fixes the underlying problem. The delete operator itself is deprecated, and it still leaves the problem of other LuaObject references hanging around after the LuaState is gone.

@GreatEmerald
Copy link

Confirmed on a 64-bit platform, also confirmed the workaround in issue #11 (adding that you need to import luad.c.all in order to make luaL_newstate() work, of course).

@JakobOvrum
Copy link
Owner

LuaObject hierarchy are now structs, this bug should be fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants