BUG: debug hooks may get wrong when mixed with coroutines

This commit is contained in:
Roberto Ierusalimschy 2006-06-05 16:36:45 -03:00
parent 2b5c1f99e5
commit a62fca1ebb
2 changed files with 43 additions and 3 deletions

39
bugs
View File

@ -974,3 +974,42 @@ lgc.c:
+ g->estimate -= GCFINALIZECOST;
]]
}
But{
what = [[debug hooks may get wrong when mixed with coroutines]],
report = [[by Ivko Stanilov, 03/06/2006]],
example = [[
co = coroutine.create(function (a,b)
coroutine.yield(a, b)
return b, "end"
end)
debug.sethook(co, function() end, "lcr")
coroutine.resume(co, 100, 2000)
coroutine.resume(co, 100, 2000)
]],
patch = [[
* ldo.c:
@@ -389,6 +389,7 @@
return;
}
else { /* resuming from previous yield */
+ L->status = 0;
if (!f_isLua(ci)) { /* `common' yield? */
/* finish interrupted execution of `OP_CALL' */
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
@@ -399,7 +400,6 @@
else /* yielded inside a hook: just continue its execution */
L->base = L->ci->base;
}
- L->status = 0;
luaV_execute(L, cast_int(L->ci - L->base_ci));
}
]],
}

7
ldo.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 2.36 2005/10/23 17:52:42 roberto Exp roberto $
** $Id: ldo.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -383,12 +383,14 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
static void resume (lua_State *L, void *ud) {
StkId firstArg = cast(StkId, ud);
CallInfo *ci = L->ci;
if (L->status != LUA_YIELD) { /* start coroutine */
if (L->status == 0) { /* start coroutine? */
lua_assert(ci == L->base_ci && firstArg > L->base);
if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
return;
}
else { /* resuming from previous yield */
lua_assert(L->status == LUA_YIELD);
L->status = 0;
if (!f_isLua(ci)) { /* `common' yield? */
/* finish interrupted execution of `OP_CALL' */
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
@ -399,7 +401,6 @@ static void resume (lua_State *L, void *ud) {
else /* yielded inside a hook: just continue its execution */
L->base = L->ci->base;
}
L->status = 0;
luaV_execute(L, cast_int(L->ci - L->base_ci));
}