aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-05-13 13:10:35 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-05-13 13:10:35 -0300
commitdfbde4c7d540f81f2cc539741a2c1f4c00f91c10 (patch)
treeafb17d64bd9d7b5e61f94f373561c2fa98d5e713
parentde794a6527058e75b674118b35f39dcbb13e88b1 (diff)
downloadlua-dfbde4c7d540f81f2cc539741a2c1f4c00f91c10.tar.gz
lua-dfbde4c7d540f81f2cc539741a2c1f4c00f91c10.tar.bz2
lua-dfbde4c7d540f81f2cc539741a2c1f4c00f91c10.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.c36
-rw-r--r--manual/manual.of12
-rw-r--r--testes/db.lua9
3 files changed, 34 insertions, 23 deletions
diff --git a/ldebug.c b/ldebug.c
index d6f132ea..591b3528 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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
37static const char *funcnamefromcall (lua_State *L, CallInfo *ci, 37static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
@@ -254,7 +254,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
254 254
255 255
256static void funcinfo (lua_Debug *ar, Closure *cl) { 256static void funcinfo (lua_Debug *ar, Closure *cl) {
257 if (noLuaClosure(cl)) { 257 if (!LuaClosure(cl)) {
258 ar->source = "=[C]"; 258 ar->source = "=[C]";
259 ar->srclen = LL("=[C]"); 259 ar->srclen = LL("=[C]");
260 ar->linedefined = -1; 260 ar->linedefined = -1;
@@ -288,29 +288,31 @@ static int nextline (const Proto *p, int currentline, int pc) {
288 288
289 289
290static void collectvalidlines (lua_State *L, Closure *f) { 290static 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->is_vararg) /* 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->is_vararg) /* 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 b68d41c9..c5c74696 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -8773,13 +8773,13 @@ The returned table can contain all the fields returned by @Lid{lua_getinfo},
8773with the string @id{what} describing which fields to fill in. 8773with the string @id{what} describing which fields to fill in.
8774The default for @id{what} is to get all information available, 8774The default for @id{what} is to get all information available,
8775except the table of valid lines. 8775except the table of valid lines.
8776If present, 8776The option @Char{f}
8777the option @Char{f}
8778adds a field named @id{func} with the function itself. 8777adds a field named @id{func} with the function itself.
8779If present, 8778The option @Char{L} adds a field named @id{activelines}
8780the option @Char{L} 8779with the table of valid lines,
8781adds a field named @id{activelines} with the table of 8780provided the function is a Lua function.
8782valid lines. 8781If the function has no debug information,
8782the table is empty.
8783 8783
8784For instance, the expression @T{debug.getinfo(1,"n").name} returns 8784For instance, the expression @T{debug.getinfo(1,"n").name} returns
8785a name for the current function, 8785a 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
49end 49end
50 50
51 51
52-- bug in 5.4.4-5.4.6: activelines in vararg functions
53-- without debug information
54do
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
58end
59
60
52-- test file and string names truncation 61-- test file and string names truncation
53local a = "function f () end" 62local a = "function f () end"
54local function dostring (s, x) return load(s, x)() end 63local function dostring (s, x) return load(s, x)() end