C Lua segfault在协同程序恢复上

C Lua segfault在协同程序恢复上,c,lua,segmentation-fault,C,Lua,Segmentation Fault,我有密码 fun = function() coroutine.resume(co); -- here it segfaults return true; end ; -- evtimer is my binding to libev -- timer = evtimer.new(1,1, fun); -- this works ok and prints "co N" every second co = coroutine.create(function ()

我有密码

fun = function() 
    coroutine.resume(co); -- here it segfaults
    return true;
end ;

-- evtimer is my binding to libev
-- timer = evtimer.new(1,1, fun); -- this works ok and prints "co N" every second


co = coroutine.create(function ()
        timer = evtimer.new(1,1, fun); --this segfaults


         for i=1,100000 do
             print("co", i)
             coroutine.yield(111);
        end
end)
-- timer = evtimer.new(1,1, fun); -- this works too

coroutine.resume(co);

timer:start(); --start timer
-- here main thread ends and libev event loop starts. Timer callback is called by event loop
当在lua core内的resume上的Corroutine segfaults内创建计时器时,会发生变化。回溯:

Program received signal SIGSEGV, Segmentation fault.
0x000000000066ec00 in ?? ()
(gdb) backtrace
#0  0x000000000066ec00 in ?? () 
#1  0x0000000000413430 in resume (L=0x6841a0, ud=0x6d8ac0) at ./src/myprogram/lua/ldo.c:522
#2  0x00000000004120e9 in luaD_rawrunprotected (L=0x6841a0, f=0x4132da <resume>, ud=0x6d8ac0)
    at ./src/myprogram/lua/ldo.c:131
#3  0x00000000004134ef in lua_resume (L=0x6841a0, from=0x6841a0, nargs=0)
    at ./src/myprogram/lua/ldo.c:543
#4  0x0000000000429b4e in auxresume (L=0x6841a0, co=0x6841a0, narg=0)
    at ./src/myprogram/lua/lcorolib.c:31
#5  0x0000000000429c5a in luaB_coresume (L=0x6841a0) at ./src/myprogram/lua/lcorolib.c:53
#6  0x0000000000412b19 in luaD_precall (L=0x6841a0, func=0x6d8aa0, nresults=2)
    at ./src/myprogram/lua/ldo.c:319
#7  0x0000000000424b2b in luaV_execute (L=0x6841a0) at ./src/myprogram/lua/lvm.c:709
#8  0x0000000000412f8a in luaD_call (L=0x6841a0, func=0x6d8a70, nResults=1, allowyield=0)
    at ./src/myprogram/lua/ldo.c:402
#9  0x000000000040c77a in f_call (L=0x6841a0, ud=0x7fffffffe000) at ./src/myprogram/lua/lapi.c:923
#10 0x00000000004120e9 in luaD_rawrunprotected (L=0x6841a0, f=0x40c73e <f_call>, ud=0x7fffffffe000)
    at ./src/myprogram/lua/ldo.c:131
#11 0x0000000000413722 in luaD_pcall (L=0x6841a0, func=0x40c73e <f_call>, u=0x7fffffffe000,
    old_top=112, ef=0) at ./src/myprogram/lua/ldo.c:603
#12 0x000000000040c84a in lua_pcallk (L=0x6841a0, nargs=0, nresults=1, errfunc=0, ctx=0, k=0x0)
    at ./src/myprogram/lua/lapi.c:949
#13 0x0000000000433a54 in lua_script_pcall (ls=0x6841a0, nargs=0, nresults=1)
    at ./src/myprogram//lua_script.c:41
#14 0x00000000004353b0 in lua_evtimer_callback (loop=0x66cc20 <default_loop_struct>, w=0x684938,
    revents=256) at ./src/myprogram//evtimer_lualib.c:21
#15 0x0000000000406d41 in ev_invoke_pending (loop=0x66cc20 <default_loop_struct>)
    at ./src/myprogram/libev/ev.c:2994
#16 0x000000000040763b in ev_run (loop=0x66cc20 <default_loop_struct>, flags=0)
    at ./src/myprogram/libev/ev.c:3394
程序接收信号SIGSEGV,分段故障。
0x000000000066ec00英寸??()
(gdb)回溯
#0 0x000000000066ec00英寸??() 
#1 0x0000000000413430在./src/myprogram/lua/ldo.c:522的简历中(L=0x6841a0,ud=0x6d8ac0)
#2 0x00000000004120e9在luaD_rawrunprotected中(L=0x6841a0,f=0x4132da,ud=0x6d8ac0)
地址./src/myprogram/lua/ldo.c:131
#lua_resume中的3 0x00000000004134ef(L=0x6841a0,from=0x6841a0,nargs=0)
地址./src/myprogram/lua/ldo.c:543
#auxresume中的4 0x0000000000429b4e(L=0x6841a0,co=0x6841a0,narg=0)
at./src/myprogram/lua/lcololib.c:31
#位于./src/myprogram/lua/lcorolib.c:53的luaB_coresume(L=0x6841a0)中的5 0x0000000000429c5a
#luaD_预分解中的6 0x0000000000412b19(L=0x6841a0,func=0x6d8aa0,nresults=2)
地址./src/myprogram/lua/ldo.c:319
#在./src/myprogram/lua/lvm.c:709执行luaV_中的7 0x00000000004B2B(L=0x6841a0)
#luaD_调用中的8 0x0000000000412f8a(L=0x6841a0,func=0x6d8a70,nResults=1,AllowyField=0)
地址./src/myprogram/lua/ldo.c:402
#9 0x000000000040c77a在/src/myprogram/lua/lapi.c:923的f_调用中(L=0x6841a0,ud=0x7fffffffe000)
#10 0x00000000004120e9在luaD_rawrunprotected中(L=0x6841a0,f=0x40c73e,ud=0x7FFFFFE000)
地址./src/myprogram/lua/ldo.c:131
#luaD_pcall中的11 0x0000000000413722(L=0x6841a0,func=0x40c73e,u=0x7fffffffe000,
在./src/myprogram/lua/ldo.c:603处的旧_top=112,ef=0)
#lua_pcallk中的12 0x000000000040c84a(L=0x6841a0,nargs=0,nresults=1,errfunc=0,ctx=0,k=0x0)
地址./src/myprogram/lua/lapi.c:949
#lua_script_pcall中的13 0x0000000000433a54(ls=0x6841a0,nargs=0,nresults=1)
在./src/myprogram//lua_script.c:41
#lua_evtimer_回调中的14 0x0000000000453B0(循环=0x66cc20,w=0x684938,
revents=256)at./src/myprogram//evtimer\u lualib.c:21
#ev_invoke_挂起中的15 0x0000000000406d41(循环=0x66cc20)
地址./src/myprogram/libev/ev.c:2994
#ev_运行中的16 0x000000000040763b(循环=0x66cc20,标志=0)
地址./src/myprogram/libev/ev.c:3394
它在第522行(lua 5.2)n=(ci->u.c.k)(L)上划分故障呼叫延续*/


有人熟悉lua core吗?为什么会发生这种情况?

问题是我在调用evtimer.new的线程上下文中保存了evtimer.new中的当前Lua_状态,并调用了计时器回调(使用pcall)。 在这种情况下,当计时器试图调用回调时,线程未恢复,这导致lua内部状态损坏
我在C端使用lua_resume来恢复线程,而不是调用lua callaback来修复它

在启用断言和API检查的情况下构建lua,并确保您的C函数没有对lua API做任何不正确的操作。非常感谢,我打开了API检查,它帮助我发现了问题。断言为lua/lapi.c:938:lua_pcallk:Assertion`(L->status==0)&&“无法对非正常线程执行调用”失败。