diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-02-19 15:05:13 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-02-19 15:05:13 -0200 |
commit | abd8f8433dc6628add06b1aa3568d40c1fdd9c46 (patch) | |
tree | ab803d7df4d59d90224b666662e5a9749b8a4754 | |
parent | ce74637ace147d147578a95c435cf7cafec590b8 (diff) | |
download | lua-github-abd8f8433dc6628add06b1aa3568d40c1fdd9c46.tar.gz |
bug: suspended function can have its 'func' field not pointing to
its function, crashing debug functions
-rw-r--r-- | ldebug.c | 21 |
1 files changed, 19 insertions, 2 deletions
@@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.90.1.2 2013/05/06 17:20:22 roberto Exp roberto $ +** $Id: ldebug.c,v 2.90.1.3 2013/05/16 16:04:15 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -47,6 +47,16 @@ static int currentline (CallInfo *ci) { } +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) */ @@ -144,6 +154,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 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? */ name = NULL; @@ -158,6 +169,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { api_incr_top(L); } } + swapextra(L); lua_unlock(L); return name; } @@ -165,11 +177,14 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 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; } @@ -269,6 +284,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { CallInfo *ci; StkId func; lua_lock(L); + swapextra(L); if (*what == '>') { ci = NULL; func = L->top - 1; @@ -287,6 +303,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { setobjs2s(L, L->top, func); api_incr_top(L); } + swapextra(L); if (strchr(what, 'L')) collectvalidlines(L, cl); lua_unlock(L); |