Re: [BUG?] Segmentation fault in lua_error() - easily reproducible

  • From: imzyxwvu@xxxxxxxxx
  • To: "luajit@xxxxxxxxxxxxx" <luajit@xxxxxxxxxxxxx>
  • Date: Sat, 13 Dec 2014 12:50:47 +0800

lua_State created with luaL_newstate isn't a thread. If you want to create a 
thread lua_State, use lua_newthread. And lua_loadstring pushes a function 
instead of a thread. It should be called with lua_call or lua_pcall but not 
lua_resume. It should have throw an error of the wrong type and lead to a Lua 
panic there. lua_resume's secondary argument is the count of arguments to pass 
to the thread so it can be 0. But I agree there shouldn't be a segment fault.

> 在 2014年12月13日,7:58,"Sergei Zhirikov" <dmarc-noreply@xxxxxxxxxxxxx> (Redacted 
> sender "sfzhi@xxxxxxxxx" for DMARC) 写道:
> 
> No offense, but I've got an impression that you didn't quite understand the 
> code. Where did you see a stack index of 0? There is no stack index 
> explicitly specified anywhere at all. The code, doesn't just create a 
> function, it *does* run it - that's what the call to lua_resume() is for. And 
> it does resume a coroutine, which, like any coroutine, consists of a 
> lua_State and a function that runs in it. The best proof of that is that it 
> actually runs and the call to coroutine.yield() does *not* throw an error. 
> But that is all beside the point. The point is that calling lua_error() in a 
> lua_State that is suspended causes a segmentation fault. The whole thing 
> about loading the function that calls yield() is only to bring the lua_State 
> to the suspended state - nothing more. If you don't feel comfortable calling 
> the main Lua thread a coroutine, you can call lua_newthread() to create a new 
> one and then resume it - that won't change the ultimate result: you will get 
> a segfault.
> 
> From: Alex <initrd.gz@xxxxxxxxx>
> To: luajit@xxxxxxxxxxxxx 
> Sent: Friday, December 12, 2014 9:55 PM
> Subject: Re: [BUG?] Segmentation fault in lua_error() - easily reproducible
> 
> Actually, there's a lot errors in the code as well. 0 is never a valid stack 
> index, yet you use it as one in lua_resume. Additionally, calling 
> coroutine.yield() when not inside of a coroutine will throw an error.
> 
> On Fri, Dec 12, 2014 at 3:52 PM, Alex <initrd.gz@xxxxxxxxx> wrote:
> > luaL_loadstring(lua, "coroutine.yield()");
> 
> This just loads the string and creates a function from the contents; it 
> doesn't run it. You then try to resume the resulting function, which isn't a 
> coroutine.
> 
> On Fri, Dec 12, 2014 at 3:44 PM, Sergei Zhirikov 
> <dmarc-noreply@xxxxxxxxxxxxx> wrote:
> Hi,
> 
> I've encountered this case of a consistent segmentation fault in LuaJIT 
> (tested with 2.0.3 on x86 and x86_64).
> The following simple example allows to reproduce it:
> 
> #include <lua.h>
> #include <lualib.h>
> #include <lauxlib.h>
> #include <stdio.h>
> 
> int main()
> {
>   lua_State *lua = luaL_newstate();
>   luaL_openlibs(lua);
>   luaL_loadstring(lua, "coroutine.yield()");
>   int res = lua_resume(lua, 0);
>   printf("res=%d, top=%d\n", res, lua_gettop(lua));
>   lua_pushliteral(lua, "test");
>   lua_error(lua);
>   return 0;
> }
> 
> This code is supposed to panic, but it results in a segmentation fault inside 
> lua_error() instead. Admittedly, this not a very common usage pattern, but 
> calling lua_error() on a suspended Lua thread can be useful sometimes. Also, 
> the "classic" Lua implementation doesn't have a problem with this usage.
> 
> I'm wondering, can this be fixed with a simple patch?
> 
> Thanks & regards,
> Sergei.
> 
> 
> 
> 
> -- 
> Sincerely,
> Alex Parrill
> 
> 
> 
> 
> -- 
> Sincerely,
> Alex Parrill
> 
> 

Other related posts: