2014-09-20 2 views
0

У меня есть кодLua на сопрограммное выдаёт ошибку сегментации резюме

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. Backtrace:

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 

это на линии ошибки сегментации 522 (LUA 5.2) п = (CI-> u.c.k) (L);/ продолжение вызова */

Есть ли кто-нибудь знаком с lua core? Почему это происходит?

+1

Сложения Lua с утверждениями и проверками API и убедитесь, что ни одна из ваших функций C не делает что-то неправильное с Lua API. –

+0

Большое спасибо, я включил api cheking, и это помогло мне выяснить проблему. Утверждение было lua/lapi.c: 938: lua_pcallk: Assertion '(L-> status == 0) &&" не может делать вызовы на ненормальном потоке "'не удалось. – user1940679

ответ

1

Проблема заключалась в том, что я сохранял текущий Lua_State в evtimer.new и вызывал обратный вызов таймера (с pcall) в контексте потока, где вызывался evtimer.new. В этом случае нити не был возобновлен, когда таймер пытался вызвать обратный вызов, и это вызвало порчу Lua внутреннего состояния Я установил его с помощью lua_resume на стороне C, чтобы возобновить нить вместо вызова Lua callaback

Смежные вопросы