diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-02-13 14:01:17 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-02-13 14:01:17 -0200 |
| commit | 4bdf9962bfd413077d979af4ddc406e7fcd4bbd6 (patch) | |
| tree | 49308264448bd40f47c1af1cfd722045dbe4508d /ldebug.c | |
| parent | e0306e386fdaa1b1f18f0c293a4b14de8b8a8536 (diff) | |
| download | lua-4bdf9962bfd413077d979af4ddc406e7fcd4bbd6.tar.gz lua-4bdf9962bfd413077d979af4ddc406e7fcd4bbd6.tar.bz2 lua-4bdf9962bfd413077d979af4ddc406e7fcd4bbd6.zip | |
bug: suspended function can have its 'func' field not pointing to
its function, crashing debug functions
Diffstat (limited to '')
| -rw-r--r-- | ldebug.c | 27 |
1 files changed, 25 insertions, 2 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.109 2014/12/10 11:30:09 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.110 2015/01/02 12:52:22 roberto Exp roberto $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -49,6 +49,22 @@ static int currentline (CallInfo *ci) { | |||
| 49 | 49 | ||
| 50 | 50 | ||
| 51 | /* | 51 | /* |
| 52 | ** If function yielded, its 'func' can be in the 'extra' field. The | ||
| 53 | ** next function restores 'func' to its correct value for debugging | ||
| 54 | ** purposes. (It exchanges 'func' and 'extra'; so, when called again, | ||
| 55 | ** after debugging, it also "re-restores" ** 'func' to its altered value. | ||
| 56 | */ | ||
| 57 | static void swapextra (lua_State *L) { | ||
| 58 | if (L->status == LUA_YIELD) { | ||
| 59 | CallInfo *ci = L->ci; /* get function that yielded */ | ||
| 60 | StkId temp = ci->func; /* exchange its 'func' and 'extra' values */ | ||
| 61 | ci->func = restorestack(L, ci->extra); | ||
| 62 | ci->extra = savestack(L, temp); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | |||
| 67 | /* | ||
| 52 | ** this function can be called asynchronous (e.g. during a signal) | 68 | ** this function can be called asynchronous (e.g. during a signal) |
| 53 | */ | 69 | */ |
| 54 | LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { | 70 | LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { |
| @@ -144,6 +160,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, | |||
| 144 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | 160 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { |
| 145 | const char *name; | 161 | const char *name; |
| 146 | lua_lock(L); | 162 | lua_lock(L); |
| 163 | swapextra(L); | ||
| 147 | if (ar == NULL) { /* information about non-active function? */ | 164 | if (ar == NULL) { /* information about non-active function? */ |
| 148 | if (!isLfunction(L->top - 1)) /* not a Lua function? */ | 165 | if (!isLfunction(L->top - 1)) /* not a Lua function? */ |
| 149 | name = NULL; | 166 | name = NULL; |
| @@ -158,6 +175,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
| 158 | api_incr_top(L); | 175 | api_incr_top(L); |
| 159 | } | 176 | } |
| 160 | } | 177 | } |
| 178 | swapextra(L); | ||
| 161 | lua_unlock(L); | 179 | lua_unlock(L); |
| 162 | return name; | 180 | return name; |
| 163 | } | 181 | } |
| @@ -165,12 +183,15 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
| 165 | 183 | ||
| 166 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | 184 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { |
| 167 | StkId pos = 0; /* to avoid warnings */ | 185 | StkId pos = 0; /* to avoid warnings */ |
| 168 | const char *name = findlocal(L, ar->i_ci, n, &pos); | 186 | const char *name; |
| 169 | lua_lock(L); | 187 | lua_lock(L); |
| 188 | swapextra(L); | ||
| 189 | name = findlocal(L, ar->i_ci, n, &pos); | ||
| 170 | if (name) { | 190 | if (name) { |
| 171 | setobjs2s(L, pos, L->top - 1); | 191 | setobjs2s(L, pos, L->top - 1); |
| 172 | L->top--; /* pop value */ | 192 | L->top--; /* pop value */ |
| 173 | } | 193 | } |
| 194 | swapextra(L); | ||
| 174 | lua_unlock(L); | 195 | lua_unlock(L); |
| 175 | return name; | 196 | return name; |
| 176 | } | 197 | } |
| @@ -270,6 +291,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
| 270 | CallInfo *ci; | 291 | CallInfo *ci; |
| 271 | StkId func; | 292 | StkId func; |
| 272 | lua_lock(L); | 293 | lua_lock(L); |
| 294 | swapextra(L); | ||
| 273 | if (*what == '>') { | 295 | if (*what == '>') { |
| 274 | ci = NULL; | 296 | ci = NULL; |
| 275 | func = L->top - 1; | 297 | func = L->top - 1; |
| @@ -288,6 +310,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
| 288 | setobjs2s(L, L->top, func); | 310 | setobjs2s(L, L->top, func); |
| 289 | api_incr_top(L); | 311 | api_incr_top(L); |
| 290 | } | 312 | } |
| 313 | swapextra(L); /* correct before option 'L', which can raise a mem. error */ | ||
| 291 | if (strchr(what, 'L')) | 314 | if (strchr(what, 'L')) |
| 292 | collectvalidlines(L, cl); | 315 | collectvalidlines(L, cl); |
| 293 | lua_unlock(L); | 316 | lua_unlock(L); |
