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.
Diffstat (limited to '')
-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 |