Crash (and/or going nuts) in case of error in __gc (Lua 5.4)

classic Classic list List threaded Threaded
4 messages Options
v
Reply | Threaded
Open this post in threaded view
|

Crash (and/or going nuts) in case of error in __gc (Lua 5.4)

v
I've been toying around with Lua 5.4 and its new warnings mechanism.
Unfortunately, it seem to be unable to fulfill its main function of
reporting errors from __gc metamethod.

That's how problem can be reproduced (code grabbed from GitHub mirror,
hash f39e8c06d61078467b3f32499728ed4e9b7b06bc, tested on Ubuntu 19.04):
1. Run standalone Lua
2. Run `setmetatable({},{__gc = function() error('Oops') end})`
3. Just continue hitting enter until you get

Lua warning: error in __gc metamethod (stdin:1: Oops)
Segmentation fault (core dumped)

I originally got this in my (C++ bridge) library where results were
even more weird, including runtime errors (accusing me in calling
table), syntax errors, segfaults, double-frees and more.
--
Valeri Ochinski <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: Crash (and/or going nuts) in case of error in __gc (Lua 5.4)

Sean Conner
It was thus said that the Great v once stated:

> I've been toying around with Lua 5.4 and its new warnings mechanism.
> Unfortunately, it seem to be unable to fulfill its main function of
> reporting errors from __gc metamethod.
>
> That's how problem can be reproduced (code grabbed from GitHub mirror,
> hash f39e8c06d61078467b3f32499728ed4e9b7b06bc, tested on Ubuntu 19.04):
> 1. Run standalone Lua
> 2. Run `setmetatable({},{__gc = function() error('Oops') end})`
> 3. Just continue hitting enter until you get
>
> Lua warning: error in __gc metamethod (stdin:1: Oops)
> Segmentation fault (core dumped)
>
> I originally got this in my (C++ bridge) library where results were
> even more weird, including runtime errors (accusing me in calling
> table), syntax errors, segfaults, double-frees and more.

  I was able to reproduce the issue (also Linux, but not Ubuntu) with the
version mentioned above.  I then recompiled with '-g' to get symbol
information for a backtrace and got:

[spc]lucy:~/apps/lua-5.4>gdb ./lua core.22871
GNU gdb Red Hat Linux (6.3.0.0-1.132.EL4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

Core was generated by ./lua'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/tls/libm.so.6...done.
Loaded symbols for /lib/tls/libm.so.6
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /usr/lib/libreadline.so.4...done.
Loaded symbols for /usr/lib/libreadline.so.4
Reading symbols from /usr/lib/libncurses.so.5...done.
Loaded symbols for /usr/lib/libncurses.so.5
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x0804d5bd in lua_load (L=0x84b200c, reader=0x805f2ac <getS>, data=0xbff0a680, chunkname=0x806e554 "=stdin", mode=0x0) at lapi.c:1060
1060      setobj(L, f->upvals[0]->v, gt);
(gdb) where
#0  0x0804d5bd in lua_load (L=0x84b200c, reader=0x805f2ac <getS>, data=0xbff0a680, chunkname=0x806e554 "=stdin", mode=0x0) at lapi.c:1060
#1  0x0805f2f5 in luaL_loadbufferx (L=0x84b200c, buff=0x84b2588 "@%K\b\005$", size=139142536, name=0x806e554 "=stdin", mode=0x0) at lauxlib.c:809
#2  0x0804b525 in doREPL (L=0x84b200c) at lua.c:470
#3  0x0804bb1b in pmain (L=0x84b200c) at lua.c:597
#4  0x0804f90f in luaD_call (L=0x84b200c, func=0x84b2364, nresults=Variable "nresults" is not available.
) at ldo.c:482
#5  0x0804fb12 in luaD_callnoyield (L=0x84b200c, func=0x84b2364, nResults=1) at ldo.c:526
#6  0x0804d462 in f_call (L=0x84b200c, ud=0x84b2588) at lapi.c:996
#7  0x0804efe8 in luaD_rawrunprotected (L=0x84b200c, f=0x804d44c <f_call>, ud=0xbff0a8c0) at ldo.c:148
#8  0x0804ff8f in luaD_pcall (L=0x84b200c, func=0x804d44c <f_call>, u=0xbff0a8c0, old_top=12, ef=0) at ldo.c:749
#9  0x0804d4c6 in lua_pcallk (L=0x84b200c, nargs=2, nresults=1, errfunc=0, ctx=139142536, k=0) at lapi.c:1022
#10 0x0804bd21 in main (argc=1, argv=0xbff0a9b4) at lua.c:616
(gdb) p L
$1 = (lua_State *) 0x84b200c
(gdb) p f
No symbol "f" in current context.
(gdb) p gt
$2 = (const TValue *) 0x84b2dbc
(gdb)

  -spc (Not sure why gdb can't find 'f' ... )


Reply | Threaded
Open this post in threaded view
|

Re: Crash (and/or going nuts) in case of error in __gc (Lua 5.4)

Andrew Gierth
>>>>> "Sean" == Sean Conner <[hidden email]> writes:

 >> I originally got this in my (C++ bridge) library where results were
 >> even more weird, including runtime errors (accusing me in calling
 >> table), syntax errors, segfaults, double-frees and more.

 Sean>   I was able to reproduce the issue (also Linux, but not Ubuntu)
 Sean> with the version mentioned above.

Looks to me like a stack error; the error object left on the stack by
luaD_pcall is never popped, so the state of the stack is messed up by
the garbage collector. The subsequent error will depend on where the GC
was invoked from, so it's likely to be quite variable.

I guess there needs to be an L->top -= 1; after the luaE_warning calls.

--
Andrew.

Reply | Threaded
Open this post in threaded view
|

Re: Crash (and/or going nuts) in case of error in __gc (Lua 5.4)

Roberto Ierusalimschy
>  >> I originally got this in my (C++ bridge) library where results were
>  >> even more weird, including runtime errors (accusing me in calling
>  >> table), syntax errors, segfaults, double-frees and more.
>
>  [...]
>
> Looks to me like a stack error; the error object left on the stack by
> luaD_pcall is never popped, so the state of the stack is messed up by
> the garbage collector. The subsequent error will depend on where the GC
> was invoked from, so it's likely to be quite variable.
>
> I guess there needs to be an L->top -= 1; after the luaE_warning calls.

Many thanks for the original report and for this prompt diagnostic.

-- Roberto