[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: lua_getlocal crashes after yield from a debug hook
- From: Roberto Ierusalimschy <roberto@...>
- Date: Fri, 13 Feb 2015 10:44:21 -0200
> I try to fix it, but maybe there is a better solution :)
Maybe this one?
-- Roberto
===================================================================
RCS file: RCS/ldebug.c,v
retrieving revision 2.110
diff -u2 -r2.110 ldebug.c
--- ldebug.c 2015/01/02 12:52:22 2.110
+++ ldebug.c 2015/02/13 12:33:20
@@ -50,4 +50,20 @@
/*
+** If function yielded, its 'func' can be in the 'extra' field. The
+** next function restores 'func' to its correct value for debugging
+** purposes. (It exchanges 'func' and 'extra'; so, when called again,
+** after debugging, it also "re-restores" ** 'func' to its altered value.
+*/
+static void swapextra (lua_State *L) {
+ if (L->status == LUA_YIELD) {
+ CallInfo *ci = L->ci; /* get function that yielded */
+ StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
+ ci->func = restorestack(L, ci->extra);
+ ci->extra = savestack(L, temp);
+ }
+}
+
+
+/*
** this function can be called asynchronous (e.g. during a signal)
*/
@@ -145,4 +161,5 @@
const char *name;
lua_lock(L);
+ swapextra(L);
if (ar == NULL) { /* information about non-active function? */
if (!isLfunction(L->top - 1)) /* not a Lua function? */
@@ -159,4 +176,5 @@
}
}
+ swapextra(L);
lua_unlock(L);
return name;
@@ -166,10 +184,13 @@
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
StkId pos = 0; /* to avoid warnings */
- const char *name = findlocal(L, ar->i_ci, n, &pos);
+ const char *name;
lua_lock(L);
+ swapextra(L);
+ name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobjs2s(L, pos, L->top - 1);
L->top--; /* pop value */
}
+ swapextra(L);
lua_unlock(L);
return name;
@@ -271,4 +292,5 @@
StkId func;
lua_lock(L);
+ swapextra(L);
if (*what == '>') {
ci = NULL;
@@ -289,4 +311,5 @@
api_incr_top(L);
}
+ swapextra(L); /* correct before option 'L', which can raise a mem. error */
if (strchr(what, 'L'))
collectvalidlines(L, cl);