|
This is a follow-up to a recent thread about yielding in hooks. Thank
you all for help in clarifying how the line hook works.
Lua flags a stack overflow assertion in the following simple code
(both in 5.1 and 5.2). It is a small extension to the previous
example, but this one keeps a reference to thread L in the registry:
void hook(lua_State* L, lua_Debug* ar)
{
lua_yield(L, 0);
}
int main(int argc, char* argv[])
{
int threadId;
lua_State* L = luaL_newstate();
lua_sethook(L, hook, LUA_MASKLINE, 0);
luaL_loadstring(L,
"i = 2\n"
"print(i)");
lua_pushthread(L);
threadId = luaL_ref(L, LUA_REGISTRYINDEX);
lua_resume(L, 0, 0);
luaL_unref(L, LUA_REGISTRYINDEX, threadId); // **** THIS LINE CRASHES ****
}
The code registers a reference to L in the registry. It then steps one
line of Lua code ("i = 2") and the hook function yields. When it tries
to unreference L, the following assertion is fired:
L->top < L->ci->top
This assertion seems to indicate a stack overflow.
Here is the stack:
msvcr100d.dll!_wassert() Line 153 C
lua.exe!lua_rawgeti(lua_State * L=0x007b1d58, int idx=-1001000, int
n=0) Line 648 + 0x45 bytes C
lua.exe!luaL_unref(lua_State * L=0x007b1d58, int t=-1001000, int
ref=3) Line 545 + 0xf bytes C
Is L in some invalid state after yielding in the hook? Is the stack
not usable? Is the registry corrupt?
-Erik