aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-01-16 16:07:39 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-01-16 16:07:39 -0300
commit664bda02ba4bd167728a2acbe658cc4a9dd9b0b5 (patch)
treefc6fe196de8326e2eee3deb81e448525a362afa8
parent2d8d5c74b5ef3d333314feede0165df7c3d13811 (diff)
downloadlua-664bda02ba4bd167728a2acbe658cc4a9dd9b0b5.tar.gz
lua-664bda02ba4bd167728a2acbe658cc4a9dd9b0b5.tar.bz2
lua-664bda02ba4bd167728a2acbe658cc4a9dd9b0b5.zip
fixing 'lua_status' in panic.
'luaD_throw' may call 'luaE_resetthread', which returns an error code but clears 'L->status'; so, 'luaD_throw' should set that status again.
-rw-r--r--ldo.c1
-rw-r--r--ltests.c10
-rw-r--r--testes/api.lua19
3 files changed, 28 insertions, 2 deletions
diff --git a/ldo.c b/ldo.c
index fb9df5d3..994ad6f0 100644
--- a/ldo.c
+++ b/ldo.c
@@ -133,6 +133,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
133 else { /* thread has no error handler */ 133 else { /* thread has no error handler */
134 global_State *g = G(L); 134 global_State *g = G(L);
135 errcode = luaE_resetthread(L, errcode); /* close all upvalues */ 135 errcode = luaE_resetthread(L, errcode); /* close all upvalues */
136 L->status = cast_byte(errcode);
136 if (g->mainthread->errorJmp) { /* main thread has a handler? */ 137 if (g->mainthread->errorJmp) { /* main thread has a handler? */
137 setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */ 138 setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */
138 luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ 139 luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
diff --git a/ltests.c b/ltests.c
index 6c77703c..83d08ac8 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1367,7 +1367,7 @@ static int checkpanic (lua_State *L) {
1367 b.L = L; 1367 b.L = L;
1368 L1 = lua_newstate(f, ud, 0); /* create new state */ 1368 L1 = lua_newstate(f, ud, 0); /* create new state */
1369 if (L1 == NULL) { /* error? */ 1369 if (L1 == NULL) { /* error? */
1370 lua_pushnil(L); 1370 lua_pushstring(L, MEMERRMSG);
1371 return 1; 1371 return 1;
1372 } 1372 }
1373 lua_atpanic(L1, panicback); /* set its panic function */ 1373 lua_atpanic(L1, panicback); /* set its panic function */
@@ -1507,7 +1507,7 @@ static int getindex_aux (lua_State *L, lua_State *L1, const char **pc) {
1507 1507
1508 1508
1509static const char *const statcodes[] = {"OK", "YIELD", "ERRRUN", 1509static const char *const statcodes[] = {"OK", "YIELD", "ERRRUN",
1510 "ERRSYNTAX", MEMERRMSG, "ERRGCMM", "ERRERR"}; 1510 "ERRSYNTAX", MEMERRMSG, "ERRERR"};
1511 1511
1512/* 1512/*
1513** Avoid these stat codes from being collected, to avoid possible 1513** Avoid these stat codes from being collected, to avoid possible
@@ -1806,6 +1806,12 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
1806 int level = getnum; 1806 int level = getnum;
1807 luaL_traceback(L1, L1, msg, level); 1807 luaL_traceback(L1, L1, msg, level);
1808 } 1808 }
1809 else if EQ("threadstatus") {
1810 lua_pushstring(L1, statcodes[lua_status(L1)]);
1811 }
1812 else if EQ("alloccount") {
1813 l_memcontrol.countlimit = cast_uint(getnum);
1814 }
1809 else if EQ("return") { 1815 else if EQ("return") {
1810 int n = getnum; 1816 int n = getnum;
1811 if (L1 != L) { 1817 if (L1 != L) {
diff --git a/testes/api.lua b/testes/api.lua
index b7e34f7f..21f703fd 100644
--- a/testes/api.lua
+++ b/testes/api.lua
@@ -416,6 +416,10 @@ do
416 -- trivial error 416 -- trivial error
417 assert(T.checkpanic("pushstring hi; error") == "hi") 417 assert(T.checkpanic("pushstring hi; error") == "hi")
418 418
419 -- thread status inside panic (bug in 5.4.4)
420 assert(T.checkpanic("pushstring hi; error", "threadstatus; return 2") ==
421 "ERRRUN")
422
419 -- using the stack inside panic 423 -- using the stack inside panic
420 assert(T.checkpanic("pushstring hi; error;", 424 assert(T.checkpanic("pushstring hi; error;",
421 [[checkstack 5 XX 425 [[checkstack 5 XX
@@ -433,6 +437,21 @@ do
433 assert(T.checkpanic("newuserdata 20000") == MEMERRMSG) 437 assert(T.checkpanic("newuserdata 20000") == MEMERRMSG)
434 T.totalmem(0) -- restore high limit 438 T.totalmem(0) -- restore high limit
435 439
440 -- memory error + thread status
441 local x = T.checkpanic(
442 [[ alloccount 0 # force a memory error in next line
443 newtable
444 ]],
445 [[
446 alloccount -1 # allow free allocations again
447 pushstring XX
448 threadstatus
449 concat 2 # to make sure message came from here
450 return 1
451 ]])
452 T.alloccount()
453 assert(x == "XX" .. "not enough memory")
454
436 -- stack error 455 -- stack error
437 if not _soft then 456 if not _soft then
438 local msg = T.checkpanic[[ 457 local msg = T.checkpanic[[