Lua 跨 C 调用边界产生
Lua yielding across C-call boundary
我试图在调试挂钩中调用 lua_yield
,但在我的输出中出现了这个错误。我想在处理了一定数量的指令后让步,并希望这是执行此操作的方法。
我正在使用一些 Python ctypes
绑定来写这篇文章。
yielding
b'test.lua:1: attempt to yield across C-call boundary'
我认为这应该可行,因为我使用的是 LuaJIT 并且它有一个 fully resumable VM。
@lua_Hook
def l_dbg_count(L: lua_State_p, ar: ctypes.POINTER(lua_Debug)):
if ar.contents.event == EventCode.HookCount:
print("yielding")
lua_yield(L, 0)
#main method
def main():
...
lua_sethook(L, l_dbg_count, DebugEventMask.Count, 1)
luaL_loadfile(L, b"test.lua")
ret = lua_pcall(L, 0, 0, 0)
while True:
if ret != LuaError.Ok and ret != LuaError.Yield:
print(lua_tostring(L, -1))
break
elif ret == LuaError.Yield:
print("resuming")
ret = lua_resume(L, None, 0)
lua_close(L)
我首先必须使用 lua_newthread
推送一个新线程,然后调用 luaL_loadfile
而不是 lua_pcall
,调用 lua_resume
.
我用 C 重写了它以检查从 Lua 到 Python 是否可能存在堆栈展开问题。
void l_dbg_count(lua_State *L, lua_Debug *ar) {
if(ar->event == LUA_HOOKCOUNT) {
printf("yielding\n");
lua_yield(L, 0);
}
}
...
int main(int argc, char **argv) {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_sethook(L, l_dbg_count, LUA_MASKCOUNT, 5);
lua_State *L_t = lua_newthread(L);
luaL_loadfile(L_t, "test.lua");
int ret = lua_resume(L_t, 0);
while(true) {
if(ret != 0 && ret != LUA_YIELD) {
fprintf(stderr, "%s", lua_tostring(L_t, -1));
break;
} else if(ret == LUA_YIELD) {
printf("resuming\n");
ret = lua_resume(L_t, 0);
} else {
break;
}
}
lua_close(L);
return EXIT_SUCCESS;
}
然而,这确实使协程库无法正常工作,因此目前正在寻找可能的修复方法。
我试图在调试挂钩中调用 lua_yield
,但在我的输出中出现了这个错误。我想在处理了一定数量的指令后让步,并希望这是执行此操作的方法。
我正在使用一些 Python ctypes
绑定来写这篇文章。
yielding
b'test.lua:1: attempt to yield across C-call boundary'
我认为这应该可行,因为我使用的是 LuaJIT 并且它有一个 fully resumable VM。
@lua_Hook
def l_dbg_count(L: lua_State_p, ar: ctypes.POINTER(lua_Debug)):
if ar.contents.event == EventCode.HookCount:
print("yielding")
lua_yield(L, 0)
#main method
def main():
...
lua_sethook(L, l_dbg_count, DebugEventMask.Count, 1)
luaL_loadfile(L, b"test.lua")
ret = lua_pcall(L, 0, 0, 0)
while True:
if ret != LuaError.Ok and ret != LuaError.Yield:
print(lua_tostring(L, -1))
break
elif ret == LuaError.Yield:
print("resuming")
ret = lua_resume(L, None, 0)
lua_close(L)
我首先必须使用 lua_newthread
推送一个新线程,然后调用 luaL_loadfile
而不是 lua_pcall
,调用 lua_resume
.
我用 C 重写了它以检查从 Lua 到 Python 是否可能存在堆栈展开问题。
void l_dbg_count(lua_State *L, lua_Debug *ar) {
if(ar->event == LUA_HOOKCOUNT) {
printf("yielding\n");
lua_yield(L, 0);
}
}
...
int main(int argc, char **argv) {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_sethook(L, l_dbg_count, LUA_MASKCOUNT, 5);
lua_State *L_t = lua_newthread(L);
luaL_loadfile(L_t, "test.lua");
int ret = lua_resume(L_t, 0);
while(true) {
if(ret != 0 && ret != LUA_YIELD) {
fprintf(stderr, "%s", lua_tostring(L_t, -1));
break;
} else if(ret == LUA_YIELD) {
printf("resuming\n");
ret = lua_resume(L_t, 0);
} else {
break;
}
}
lua_close(L);
return EXIT_SUCCESS;
}
然而,这确实使协程库无法正常工作,因此目前正在寻找可能的修复方法。