diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-04 17:27:13 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-04 17:27:13 -0300 |
| commit | bdc85357aa41a9610498232c2cffe7aa191e5cf6 (patch) | |
| tree | 49acbe61a8c1f4dfaa36892ad01eba7cf56a78f4 | |
| parent | b291008cc2a63eb19918d4cce7e58118f4154b03 (diff) | |
| download | lua-bdc85357aa41a9610498232c2cffe7aa191e5cf6.tar.gz lua-bdc85357aa41a9610498232c2cffe7aa191e5cf6.tar.bz2 lua-bdc85357aa41a9610498232c2cffe7aa191e5cf6.zip | |
Bug: Active-lines for stripped vararg functions
Lua seg. faults when asked to create the 'activelines' table for a
vararg function with no debug information.
| -rw-r--r-- | ldebug.c | 36 | ||||
| -rw-r--r-- | manual/manual.of | 12 | ||||
| -rw-r--r-- | testes/db.lua | 9 |
3 files changed, 34 insertions, 23 deletions
| @@ -31,7 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | 33 | ||
| 34 | #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL) | 34 | #define LuaClosure(f) ((f) != NULL && (f)->c.tt == LUA_VLCL) |
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | static const char *funcnamefromcall (lua_State *L, CallInfo *ci, | 37 | static const char *funcnamefromcall (lua_State *L, CallInfo *ci, |
| @@ -255,7 +255,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
| 255 | 255 | ||
| 256 | 256 | ||
| 257 | static void funcinfo (lua_Debug *ar, Closure *cl) { | 257 | static void funcinfo (lua_Debug *ar, Closure *cl) { |
| 258 | if (noLuaClosure(cl)) { | 258 | if (!LuaClosure(cl)) { |
| 259 | ar->source = "=[C]"; | 259 | ar->source = "=[C]"; |
| 260 | ar->srclen = LL("=[C]"); | 260 | ar->srclen = LL("=[C]"); |
| 261 | ar->linedefined = -1; | 261 | ar->linedefined = -1; |
| @@ -288,29 +288,31 @@ static int nextline (const Proto *p, int currentline, int pc) { | |||
| 288 | 288 | ||
| 289 | 289 | ||
| 290 | static void collectvalidlines (lua_State *L, Closure *f) { | 290 | static void collectvalidlines (lua_State *L, Closure *f) { |
| 291 | if (noLuaClosure(f)) { | 291 | if (!LuaClosure(f)) { |
| 292 | setnilvalue(s2v(L->top.p)); | 292 | setnilvalue(s2v(L->top.p)); |
| 293 | api_incr_top(L); | 293 | api_incr_top(L); |
| 294 | } | 294 | } |
| 295 | else { | 295 | else { |
| 296 | int i; | ||
| 297 | TValue v; | ||
| 298 | const Proto *p = f->l.p; | 296 | const Proto *p = f->l.p; |
| 299 | int currentline = p->linedefined; | 297 | int currentline = p->linedefined; |
| 300 | Table *t = luaH_new(L); /* new table to store active lines */ | 298 | Table *t = luaH_new(L); /* new table to store active lines */ |
| 301 | sethvalue2s(L, L->top.p, t); /* push it on stack */ | 299 | sethvalue2s(L, L->top.p, t); /* push it on stack */ |
| 302 | api_incr_top(L); | 300 | api_incr_top(L); |
| 303 | setbtvalue(&v); /* boolean 'true' to be the value of all indices */ | 301 | if (p->lineinfo != NULL) { /* proto with debug information? */ |
| 304 | if (!(p->flag & PF_ISVARARG)) /* regular function? */ | 302 | int i; |
| 305 | i = 0; /* consider all instructions */ | 303 | TValue v; |
| 306 | else { /* vararg function */ | 304 | setbtvalue(&v); /* boolean 'true' to be the value of all indices */ |
| 307 | lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP); | 305 | if (!(p->flag & PF_ISVARARG)) /* regular function? */ |
| 308 | currentline = nextline(p, currentline, 0); | 306 | i = 0; /* consider all instructions */ |
| 309 | i = 1; /* skip first instruction (OP_VARARGPREP) */ | 307 | else { /* vararg function */ |
| 310 | } | 308 | lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP); |
| 311 | for (; i < p->sizelineinfo; i++) { /* for each instruction */ | 309 | currentline = nextline(p, currentline, 0); |
| 312 | currentline = nextline(p, currentline, i); /* get its line */ | 310 | i = 1; /* skip first instruction (OP_VARARGPREP) */ |
| 313 | luaH_setint(L, t, currentline, &v); /* table[line] = true */ | 311 | } |
| 312 | for (; i < p->sizelineinfo; i++) { /* for each instruction */ | ||
| 313 | currentline = nextline(p, currentline, i); /* get its line */ | ||
| 314 | luaH_setint(L, t, currentline, &v); /* table[line] = true */ | ||
| 315 | } | ||
| 314 | } | 316 | } |
| 315 | } | 317 | } |
| 316 | } | 318 | } |
| @@ -339,7 +341,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
| 339 | } | 341 | } |
| 340 | case 'u': { | 342 | case 'u': { |
| 341 | ar->nups = (f == NULL) ? 0 : f->c.nupvalues; | 343 | ar->nups = (f == NULL) ? 0 : f->c.nupvalues; |
| 342 | if (noLuaClosure(f)) { | 344 | if (!LuaClosure(f)) { |
| 343 | ar->isvararg = 1; | 345 | ar->isvararg = 1; |
| 344 | ar->nparams = 0; | 346 | ar->nparams = 0; |
| 345 | } | 347 | } |
diff --git a/manual/manual.of b/manual/manual.of index 337731fe..4fbdbf31 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
| @@ -8942,13 +8942,13 @@ The returned table can contain all the fields returned by @Lid{lua_getinfo}, | |||
| 8942 | with the string @id{what} describing which fields to fill in. | 8942 | with the string @id{what} describing which fields to fill in. |
| 8943 | The default for @id{what} is to get all information available, | 8943 | The default for @id{what} is to get all information available, |
| 8944 | except the table of valid lines. | 8944 | except the table of valid lines. |
| 8945 | If present, | 8945 | The option @Char{f} |
| 8946 | the option @Char{f} | ||
| 8947 | adds a field named @id{func} with the function itself. | 8946 | adds a field named @id{func} with the function itself. |
| 8948 | If present, | 8947 | The option @Char{L} adds a field named @id{activelines} |
| 8949 | the option @Char{L} | 8948 | with the table of valid lines, |
| 8950 | adds a field named @id{activelines} with the table of | 8949 | provided the function is a Lua function. |
| 8951 | valid lines. | 8950 | If the function has no debug information, |
| 8951 | the table is empty. | ||
| 8952 | 8952 | ||
| 8953 | For instance, the expression @T{debug.getinfo(1,"n").name} returns | 8953 | For instance, the expression @T{debug.getinfo(1,"n").name} returns |
| 8954 | a name for the current function, | 8954 | a name for the current function, |
diff --git a/testes/db.lua b/testes/db.lua index d3758c41..49ff8e3e 100644 --- a/testes/db.lua +++ b/testes/db.lua | |||
| @@ -49,6 +49,15 @@ do | |||
| 49 | end | 49 | end |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | -- bug in 5.4.4-5.4.6: activelines in vararg functions | ||
| 53 | -- without debug information | ||
| 54 | do | ||
| 55 | local func = load(string.dump(load("print(10)"), true)) | ||
| 56 | local actl = debug.getinfo(func, "L").activelines | ||
| 57 | assert(#actl == 0) -- no line info | ||
| 58 | end | ||
| 59 | |||
| 60 | |||
| 52 | -- test file and string names truncation | 61 | -- test file and string names truncation |
| 53 | local a = "function f () end" | 62 | local a = "function f () end" |
| 54 | local function dostring (s, x) return load(s, x)() end | 63 | local function dostring (s, x) return load(s, x)() end |
