diff --git a/include/config.h b/include/config.h index 6764c021e..1093463ef 100644 --- a/include/config.h +++ b/include/config.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 config.h $NHDT-Date: 1702948586 2023/12/19 01:16:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.179 $ */ +/* NetHack 3.7 config.h $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.181 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -669,6 +669,13 @@ typedef unsigned char uchar; /* undef this to check if sandbox breaks something */ #define NHL_SANDBOX +#ifdef NHL_SANDBOX +#ifdef CHRONICLE + /* LIVELOG (and therefore CHRONICLE) is needed for --loglua */ +#define LIVELOG +#endif +#endif + /* End of Section 4 */ #ifdef TTY_TILES_ESCCODES diff --git a/include/decl.h b/include/decl.h index 2ca3cb705..17c70bab5 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1698264758 2023/10/25 20:12:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.339 $ */ +/* NetHack 3.7 decl.h $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.351 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -541,6 +541,8 @@ struct instance_globals_l { /* nhlua.c */ genericptr_t luacore; /* lua_State * */ char lua_warnbuf[BUFSZ]; + int loglua; + int lua_sid; /* options.c */ boolean loot_reset_justpicked; diff --git a/include/extern.h b/include/extern.h index 2ff78fe73..45880d68c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1704316439 2024/01/03 21:13:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1359 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.1358 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1998,7 +1998,8 @@ extern boolean nhl_loadlua(lua_State *, const char *) NONNULLARG12; extern char *get_nh_lua_variables(void); extern void save_luadata(NHFILE *) NONNULLARG1; extern void restore_luadata(NHFILE *) NONNULLARG1; -extern int nhl_pcall(lua_State *, int, int) NONNULLARG1; +extern int nhl_pcall(lua_State *, int, int, const char *) NONNULLARG1; +extern int nhl_pcall_handle(lua_State *, int, int, const char *, NHL_pcall_action) NONNULLARG1; extern boolean load_lua(const char *, nhl_sandbox_info *) NONNULLARG12; ATTRNORETURN extern void nhl_error(lua_State *, const char *) NORETURN NONNULLARG12; extern void lcheck_param_table(lua_State *) NONNULLARG1; diff --git a/include/global.h b/include/global.h index 529a1c99d..eb93dde80 100644 --- a/include/global.h +++ b/include/global.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 global.h $NHDT-Date: 1703716158 2023/12/27 22:29:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.157 $ */ +/* NetHack 3.7 global.h $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.159 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -552,10 +552,6 @@ typedef struct nhl_sandbox_info { #define NHL_SB_VERSION 0x40000000 /* Debugging library - mostly unsafe. */ #define NHL_SB_DEBUGGING 0x08000000 - /* Use with memlimit/steps/perpcall to get usage. */ -#define NHL_SB_REPORT 0x04000000 - /* As above, but do full gc on each nhl_pcall. */ -#define NHL_SB_REPORT2 0x02000000 /* Low level groups. If you need these, you probably need to define * a new high level group instead. */ @@ -591,4 +587,10 @@ typedef struct nhl_sandbox_info { #define NHL_SBRV_ACCEPT 2 #define NHL_SBRV_FAIL 3 +/* NHL_pcall_handle action values */ +typedef enum NHL_pcall_action { + NHLpa_panic, + NHLpa_impossible +} NHL_pcall_action; + #endif /* GLOBAL_H */ diff --git a/src/allmain.c b/src/allmain.c index fda143822..3b4ee094e 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 allmain.c $NHDT-Date: 1697779529 2023/10/20 05:25:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.223 $ */ +/* NetHack 3.7 allmain.c $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.238 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -511,7 +511,7 @@ moveloop_core(void) if (gl.luacore && nhcb_counts[NHCB_END_TURN]) { lua_getglobal(gl.luacore, "nh_callback_run"); lua_pushstring(gl.luacore, nhcb_name[NHCB_END_TURN]); - nhl_pcall(gl.luacore, 1, 0); + nhl_pcall_handle(gl.luacore, 1, 0, "moveloop_core", NHLpa_panic); } } diff --git a/src/cmd.c b/src/cmd.c index 1272b87c7..a17a1eefa 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1703070187 2023/12/20 11:03:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.695 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.699 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -486,7 +486,7 @@ can_do_extcmd(const struct ext_func_tab *extcmd) lua_getglobal(gl.luacore, "nh_callback_run"); lua_pushstring(gl.luacore, nhcb_name[NHCB_CMD_BEFORE]); lua_pushstring(gl.luacore, extcmd->ef_txt); - nhl_pcall(gl.luacore, 2, 1); + nhl_pcall_handle(gl.luacore, 2, 1, "can_do_extcmd", NHLpa_panic); if (!lua_toboolean(gl.luacore, -1)) return FALSE; } @@ -1389,7 +1389,10 @@ wiz_load_lua(void) { if (wizard) { char buf[BUFSZ]; - nhl_sandbox_info sbi = {NHL_SB_SAFE | NHL_SB_DEBUGGING, 0, 0, 0}; + /* Large but not unlimited memory and CPU so random bits of + * code can be tested by wizards. */ + nhl_sandbox_info sbi = {NHL_SB_SAFE | NHL_SB_DEBUGGING, + 16*1024*1024, 0, 16*1024*1024}; buf[0] = '\0'; getlin("Load which lua file?", buf); diff --git a/src/decl.c b/src/decl.c index 8c9fe0146..eb4590a91 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.c $NHDT-Date: 1701132220 2023/11/28 00:43:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.304 $ */ +/* NetHack 3.7 decl.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.309 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -505,6 +505,8 @@ const struct instance_globals_l g_init_l = { /* nhlua.c */ UNDEFINED_VALUE, /* luacore */ DUMMY, /* lua_warnbuf[] */ + 0, /* loglua */ + 0, /* lua_sid */ /* options.c */ FALSE, /* loot_reset_justpicked */ /* save.c */ diff --git a/src/do.c b/src/do.c index 517f812dc..96adbe74a 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do.c $NHDT-Date: 1702023250 2023/12/08 08:14:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.368 $ */ +/* NetHack 3.7 do.c $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.376 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1557,7 +1557,7 @@ goto_level( if (gl.luacore && nhcb_counts[NHCB_LVL_LEAVE]) { lua_getglobal(gl.luacore, "nh_callback_run"); lua_pushstring(gl.luacore, nhcb_name[NHCB_LVL_LEAVE]); - nhl_pcall(gl.luacore, 1, 0); + nhl_pcall_handle(gl.luacore, 1, 0, "goto_level", NHLpa_panic); } /* tethered movement makes level change while trapped feasible */ diff --git a/src/dungeon.c b/src/dungeon.c index a856f2c3b..3185549d2 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dungeon.c $NHDT-Date: 1703070190 2023/12/20 11:03:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.205 $ */ +/* NetHack 3.7 dungeon.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.207 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -867,7 +867,7 @@ init_dungeons(void) struct proto_dungeon pd; struct level_map *lev_map; int tidx; - nhl_sandbox_info sbi = {NHL_SB_SAFE, 0, 0, 0}; + nhl_sandbox_info sbi = {NHL_SB_SAFE, 1*1024*1024, 0, 1*1024*1024}; (void) memset(&pd, 0, sizeof (struct proto_dungeon)); pd.n_levs = pd.n_brs = 0; diff --git a/src/mklev.c b/src/mklev.c index fe07cb3f2..67f773d7a 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mklev.c $NHDT-Date: 1702839454 2023/12/17 18:57:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.169 $ */ +/* NetHack 3.7 mklev.c $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.174 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Alex Smith, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -267,7 +267,7 @@ makerooms(void) boolean tried_vault = FALSE; int themeroom_tries = 0; char *fname; - nhl_sandbox_info sbi = {NHL_SB_SAFE, 0, 0, 0}; + nhl_sandbox_info sbi = {NHL_SB_SAFE, 1*1024*1024, 0, 1*1024*1024}; lua_State *themes = (lua_State *) gl.luathemes[u.uz.dnum]; if (!themes && *(fname = gd.dungeons[u.uz.dnum].themerms)) { @@ -292,9 +292,7 @@ makerooms(void) iflags.in_lua = gi.in_mk_themerooms = TRUE; gt.themeroom_failed = FALSE; lua_getglobal(themes, "pre_themerooms_generate"); - if ( nhl_pcall(themes, 0, 0)){ - impossible("Lua error: %s", lua_tostring(themes, -1)); - } + nhl_pcall_handle(themes, 0, 0, "makerooms-1", NHLpa_impossible); iflags.in_lua = gi.in_mk_themerooms = FALSE; } @@ -313,9 +311,7 @@ makerooms(void) iflags.in_lua = gi.in_mk_themerooms = TRUE; gt.themeroom_failed = FALSE; lua_getglobal(themes, "themerooms_generate"); - if (nhl_pcall(themes, 0, 0)) { - impossible("Lua error: %s", lua_tostring(themes, -1)); - } + nhl_pcall_handle(themes, 0, 0, "makerooms-2", NHLpa_panic); iflags.in_lua = gi.in_mk_themerooms = FALSE; if (gt.themeroom_failed && ((themeroom_tries++ > 10) @@ -332,9 +328,7 @@ makerooms(void) iflags.in_lua = gi.in_mk_themerooms = TRUE; gt.themeroom_failed = FALSE; lua_getglobal(themes, "post_themerooms_generate"); - if ( nhl_pcall(themes, 0, 0)){ - impossible("Lua error: %s", lua_tostring(themes, -1)); - } + nhl_pcall_handle(themes, 0, 0, "makerooms-3", NHLpa_panic); iflags.in_lua = gi.in_mk_themerooms = FALSE; wallification(1, 0, COLNO - 1, ROWNO - 1); @@ -1237,7 +1231,7 @@ makelevel(void) if (gl.luacore && nhcb_counts[NHCB_LVL_ENTER]) { lua_getglobal(gl.luacore, "nh_callback_run"); lua_pushstring(gl.luacore, nhcb_name[NHCB_LVL_ENTER]); - nhl_pcall(gl.luacore, 1, 0); + nhl_pcall_handle(gl.luacore, 1, 0, "makelevel", NHLpa_panic); } } diff --git a/src/nhlsel.c b/src/nhlsel.c index d627afec3..4b04d243b 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhlua.c $NHDT-Date: 1582675449 2020/02/26 00:04:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 3.7 nhlua.c $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.61 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ @@ -917,8 +917,7 @@ l_selection_iterate(lua_State *L) lua_pushvalue(L, 2); lua_pushinteger(L, tmpx); lua_pushinteger(L, tmpy); - if (nhl_pcall(L, 2, 0)) { - impossible("Lua error: %s", lua_tostring(L, -1)); + if (nhl_pcall_handle(L, 2, 0, "l_selection_iterate", NHLpa_impossible)) { /* abort the loops to prevent possible error cascade */ goto out; } diff --git a/src/nhlua.c b/src/nhlua.c index 8eb14f591..27afc3d8f 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhlua.c $NHDT-Date: 1701978168 2023/12/07 19:42:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ +/* NetHack 3.7 nhlua.c $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.126 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ @@ -76,7 +76,7 @@ static int traceback_handler(lua_State *); #ifdef NHL_SANDBOX static void nhlL_openlibs(lua_State *, uint32_t); #endif -static lua_State *nhlL_newstate (nhl_sandbox_info *); +static lua_State *nhlL_newstate (nhl_sandbox_info *, const char *); static void end_luapat(void); static const char *const nhcore_call_names[NUM_NHCORE_CALLS] = { @@ -102,6 +102,12 @@ typedef struct nhl_user_data { uint32_t steps; /* current counter */ uint32_t osteps; /* original steps value */ uint32_t perpcall; /* per pcall steps value */ + + /* stats */ + uint32_t statctr; /* stats step reload count */ + uint32_t sid; /* id number (per state) */ + const char *name; /* for stats logging (per pcall) */ + #ifdef NHL_SANDBOX jmp_buf jb; #endif @@ -112,12 +118,8 @@ static lua_State *luapat; /* instance for file pattern matching */ void l_nhcore_init(void) { -#if 1 - nhl_sandbox_info sbi = {NHL_SB_SAFE, 0, 0, 0}; -#else - /* Sample sbi for getting resource usage information. */ - nhl_sandbox_info sbi = {NHL_SB_SAFE|NHL_SB_REPORT2, 10000000, 10000000, 0}; -#endif + nhl_sandbox_info sbi = {NHL_SB_SAFE, 1*1024*1024, 0, 1*1024*1024}; + if ((gl.luacore = nhl_init(&sbi)) != 0) { if (!nhl_loadlua(gl.luacore, "nhcore.lua")) { gl.luacore = (lua_State *) 0; @@ -163,9 +165,7 @@ l_nhcore_call(int callidx) if (ltyp == LUA_TFUNCTION) { lua_remove(gl.luacore, -2); /* nhcore_call_names[callidx] */ lua_remove(gl.luacore, -2); /* nhcore */ - if (nhl_pcall(gl.luacore, 0, 1)) { - impossible("Lua error: %s", lua_tostring(gl.luacore, -1)); - } + nhl_pcall_handle(gl.luacore, 0, 1, "l_nhcore_call", NHLpa_panic); } else { /*impossible("nhcore.%s is not a lua function", nhcore_call_names[callidx]);*/ @@ -1127,9 +1127,9 @@ nhl_variable(lua_State *L) else if (typ == LUA_TTABLE) { lua_getglobal(gl.luacore, "nh_get_variables_string"); lua_pushvalue(gl.luacore, -2); - nhl_pcall(gl.luacore, 1, 1); + nhl_pcall_handle(gl.luacore, 1, 1, "nhl_variable", NHLpa_panic); luaL_loadstring(L, lua_tostring(gl.luacore, -1)); - nhl_pcall(L, 0, 1); + nhl_pcall_handle(L, 0, 1, "nhl_variable-1", NHLpa_panic); } else nhl_error(L, "Cannot get variable of that type"); return 1; @@ -1156,9 +1156,9 @@ nhl_variable(lua_State *L) lua_getglobal(L, "nh_set_variables_string"); lua_pushstring(L, key); lua_pushvalue(L, -3); /* copy value to top */ - nhl_pcall(L, 2, 1); + nhl_pcall_handle(L, 2, 1, "nhl_variable-2", NHLpa_panic); luaL_loadstring(gl.luacore, lua_tostring(L, -1)); - nhl_pcall(gl.luacore, 0, 0); + nhl_pcall_handle(gl.luacore, 0, 0, "nhl_variable-3", NHLpa_panic); } else nhl_error(L, "Cannot set variable of that type"); return 0; @@ -1187,8 +1187,7 @@ get_nh_lua_variables(void) lua_getglobal(gl.luacore, "get_variables_string"); if (lua_type(gl.luacore, -1) == LUA_TFUNCTION) { - if (nhl_pcall(gl.luacore, 0, 1)) { - impossible("Lua error: %s", lua_tostring(gl.luacore, -1)); + if (nhl_pcall_handle(gl.luacore, 0, 1, "get_nh_lua_variables", NHLpa_impossible)) { return key; } key = dupstr(lua_tostring(gl.luacore, -1)); @@ -1229,7 +1228,7 @@ restore_luadata(NHFILE *nhfp) l_nhcore_init(); luaL_loadstring(gl.luacore, lua_data); free(lua_data); - nhl_pcall(gl.luacore, 0, 0); + nhl_pcall_handle(gl.luacore, 0, 0, "restore_luadata", NHLpa_panic); } /* local stairs = stairways(); */ @@ -1545,7 +1544,7 @@ nhl_callback(lua_State *L) lua_getglobal(gl.luacore, rm ? "nh_callback_rm" : "nh_callback_set"); lua_pushstring(gl.luacore, cb); lua_pushstring(gl.luacore, fn); - nhl_pcall(gl.luacore, 2, 0); + nhl_pcall_handle(gl.luacore, 2, 0, "nhl_callback", NHLpa_panic); } return 0; } @@ -1867,10 +1866,11 @@ traceback_handler(lua_State *L) return 1; } -/* lua_pcall with our traceback handler and instruction step limiting. +/* lua_pcall with our traceback handler and memory and instruction step + * limiting. * On error, traceback will be on top of stack */ int -nhl_pcall(lua_State *L, int nargs, int nresults) +nhl_pcall(lua_State *L, int nargs, int nresults, const char *name) { struct nhl_user_data *nud; int rv; @@ -1879,36 +1879,65 @@ nhl_pcall(lua_State *L, int nargs, int nresults) lua_insert(L, 1); (void) lua_getallocf(L, (void **) &nud); #ifdef NHL_SANDBOX + if(nud && name){ + nud->name = name; + } + /* NB: We don't need to deal with nud->memlimit - Lua handles that. */ if (nud && (nud->steps || nud->perpcall)) { - if (nud->perpcall) + if (nud->perpcall){ nud->steps = nud->perpcall; + nud->statctr = 0; + } if (setjmp(nud->jb)) { /* panic, because we don't know if the game state is corrupt */ - panic("time exceeded"); + /* XXX can we get a lua stack trace as well? */ + panic("Lua time exceeded %d:%s",nud->sid,nud->name?nud->name:"(unknown)"); } } #endif rv = lua_pcall(L, nargs, nresults, 1); + lua_remove(L, 1); /* remove handler */ + #ifdef NHL_SANDBOX - if (nud && (nud->flags & (NHL_SB_REPORT | NHL_SB_REPORT2)) != 0 - && (nud->memlimit || nud->osteps || nud->perpcall)) { - if (nud->flags & NHL_SB_REPORT2) - lua_gc(L, LUA_GCCOLLECT); - pline("Lua context=%p RAM: %lu STEPS:%lu", (void *) L, - (unsigned long) nud->inuse, - (unsigned long) (nud->perpcall - ? (nud->perpcall - nud->steps) - : (nud->osteps - nud->steps))); + if(nud && nud->perpcall && gl.loglua){ + long ic = nud->statctr*NHL_SB_STEPSIZE; // an approximation + livelog_printf(LL_DEBUG, "LUASTATS PCAL %d:%s %ld", + nud->sid,nud->name,ic); + } + if(nud && nud->memlimit && gl.loglua){ + lua_gc(L, LUA_GCCOLLECT); + livelog_printf(LL_DEBUG, "LUASTATS PMEM %d:%s %u", + nud->sid,nud->name,nud->inuse); } #endif - return rv; } -/* XXX impossible() should be swappable with pline or nothing via flag */ +int +nhl_pcall_handle(lua_State *L, int nargs, int nresults, const char *name, + NHL_pcall_action npa +){ + int rv = nhl_pcall(L, nargs, nresults, name); + if(rv){ + nhl_user_data *nud; + (void)lua_getallocf(L, (void**)&nud); + /* XXX can we get a lua stack trace as well? */ + switch(npa){ + case NHLpa_panic: + panic("time exceeded %d:%s %s", nud->sid, + nud->name?nud->name:"(unknown)", lua_tostring(L, -1)); + case NHLpa_impossible: + impossible("Lua error: %d:%s %s", nud->sid, + nud->name?nud->name:"(unknown)", lua_tostring(L, -1)); + } + } + return rv; +} + +/* XXX impossible() should be swappable with pline/nothing/panic via flag */ /* read lua code/data from a dlb module or an external file into a string buffer and feed that to lua */ boolean @@ -2004,8 +2033,7 @@ nhl_loadlua(lua_State *L, const char *fname) ret = FALSE; goto give_up; } else { - if (nhl_pcall(L, 0, LUA_MULTRET)) { - impossible("Lua error: %s", lua_tostring(L, -1)); + if (nhl_pcall_handle(L, 0, LUA_MULTRET, fname, NHLpa_impossible)) { ret = FALSE; goto give_up; } @@ -2017,6 +2045,7 @@ nhl_loadlua(lua_State *L, const char *fname) if (buf) free((genericptr_t) buf); return ret; +#undef LOADCHUNKSIZE } DISABLE_WARNING_CONDEXPR_IS_CONSTANT @@ -2038,7 +2067,7 @@ nhl_init(nhl_sandbox_info *sbi) } #endif - lua_State *L = nhlL_newstate(sbi); + lua_State *L = nhlL_newstate(sbi,"nhl_init"); iflags.in_lua = TRUE; /* Temporary for development XXX */ @@ -2092,8 +2121,23 @@ RESTORE_WARNING_CONDEXPR_IS_CONSTANT void nhl_done(lua_State *L) { - if (L) + if (L) { + if(gl.loglua){ + nhl_user_data *nud; + (void)lua_getallocf(L, (void**)&nud); + if(nud && nud->osteps){ + long ic = nud->statctr*NHL_SB_STEPSIZE; // an approximation + livelog_printf(LL_DEBUG, "LUASTATS DONE %d:%s %ld", + nud->sid, nud->name,ic); + } + if(nud && nud->memlimit && !nud->perpcall){ + lua_gc(L, LUA_GCCOLLECT); + livelog_printf(LL_DEBUG, "LUASTATS DMEM %d:%s %u", + nud->sid, nud->name,nud->inuse); + } + } lua_close(L); + } iflags.in_lua = FALSE; } @@ -2124,7 +2168,7 @@ DISABLE_WARNING_CONDEXPR_IS_CONSTANT const char * get_lua_version(void) { - nhl_sandbox_info sbi = {NHL_SB_VERSION, 0, 0, 0}; + nhl_sandbox_info sbi = {NHL_SB_VERSION, 1*1024*1024, 0, 1*1024*1024}; if (gl.lua_ver[0] == 0) { lua_State *L = nhl_init(&sbi); @@ -2176,6 +2220,26 @@ RESTORE_WARNING_CONDEXPR_IS_CONSTANT /*** *** SANDBOX / HARDENING CODE ***/ +/* + * Tracing the sandbox: + * 1. Make sure CHRONICLE and LIVELOG are defined in config.h. + * 2. Rebuild the game. + * 3. Run the game and do whatever you want to check with lua. + * 4. Find the logged information in livelog. + * + * Logging format in livelog: + * message=LUASTATS : + * where: + * TYPE + * DONE rough number of step taken during the life of the VM + * DMEM memory in use at destruction of VM + * PCAL rough number of steps during lua_pcall + * PMEM memory in use after lua_pcall returns + * SID a small integer identifying the Lua VM instance + * TAG a string from the nhl_luapcall call + * DATA memory: rough number of bytes in use by the VM(see NHL_ALLOC_ADJUST) + * steps: rough number of steps by the VM(see NHL_SB_STEPSIZE) + */ #ifdef NHL_SANDBOX enum ewhen {NEVER, IFFLAG, EOT}; @@ -2669,7 +2733,7 @@ nhl_alloc(void *ud, void *ptr, size_t osize, size_t nsize) NHL_ALLOC_ADJUST(delta); nud->inuse += delta; if (nud->inuse > nud->memlimit) - return 0; + return NULL; } if (nsize == 0) { @@ -2731,15 +2795,16 @@ nhl_hookfn(lua_State *L, lua_Debug *ar UNUSED) longjmp(nud->jb, 1); nud->steps -= NHL_SB_STEPSIZE; + nud->statctr++; } #endif static lua_State * -nhlL_newstate(nhl_sandbox_info *sbi) +nhlL_newstate(nhl_sandbox_info *sbi, const char *name) { nhl_user_data *nud = 0; - if (sbi->memlimit || sbi->steps) { + if (sbi->memlimit || sbi->steps || sbi->perpcall) { nud = nhl_alloc(NULL, NULL, 0, sizeof (struct nhl_user_data)); if (!nud) return 0; @@ -2748,9 +2813,15 @@ nhlL_newstate(nhl_sandbox_info *sbi) nud->steps = 0; nud->osteps = 0; nud->flags = sbi->flags; /* save reporting flags */ + nud->statctr = 0; uint32_t sz = sizeof (struct nhl_user_data); NHL_ALLOC_ADJUST(sz); nud->inuse = sz; + + if(name){ + nud->name = name; + } + nud->sid = ++gl.lua_sid; } lua_State *L = lua_newstate(nhl_alloc, nud); diff --git a/src/questpgr.c b/src/questpgr.c index decc7c102..8b95d6bd6 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 questpgr.c $NHDT-Date: 1687036548 2023/06/17 21:15:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */ +/* NetHack 3.7 questpgr.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.87 $ */ /* Copyright 1991, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ @@ -476,7 +476,7 @@ com_pager_core( lua_State *L; char *text = NULL, *synopsis = NULL, *fallback_msgid = NULL; boolean res = FALSE; - nhl_sandbox_info sbi = {NHL_SB_SAFE, 0, 0, 0}; + nhl_sandbox_info sbi = {NHL_SB_SAFE, 1*1024*1024, 0, 1*1024*1024}; if (skip_pager(TRUE)) return FALSE; diff --git a/src/sp_lev.c b/src/sp_lev.c index c6f9b8b72..0e5603b4b 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sp_lev.c $NHDT-Date: 1695159628 2023/09/19 21:40:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.339 $ */ +/* NetHack 3.7 sp_lev.c $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.350 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -3312,9 +3312,7 @@ lspo_monster(lua_State *L) if (tmpmons.has_invent && lua_type(L, -1) == LUA_TFUNCTION) { lua_remove(L, -2); - if (nhl_pcall(L, 0, 0)){ - impossible("Lua error: %s", lua_tostring(L, -1)); - } + nhl_pcall_handle(L, 0, 0, "lspo_monster", NHLpa_panic); spo_end_moninvent(); } else lua_pop(L, 1); @@ -3659,9 +3657,7 @@ lspo_object(lua_State *L) if (lua_type(L, -1) == LUA_TFUNCTION) { lua_remove(L, -2); nhl_push_obj(L, otmp); - if (nhl_pcall(L, 1, 0)){ - impossible("Lua error: %s", lua_tostring(L, -1)); - } + nhl_pcall_handle(L, 1, 0, "lspo_object", NHLpa_panic); } else lua_pop(L, 1); @@ -4012,9 +4008,7 @@ lspo_room(lua_State *L) if (lua_type(L, -1) == LUA_TFUNCTION) { lua_remove(L, -2); l_push_mkroom_table(L, tmpcr); - if (nhl_pcall(L, 1, 0)){ - impossible("Lua error: %s", lua_tostring(L, -1)); - } + nhl_pcall_handle(L, 1, 0, "lspo_room", NHLpa_panic); } else lua_pop(L, 1); spo_endroom(gc.coder); @@ -6268,9 +6262,7 @@ lspo_region(lua_State *L) if (lua_type(L, -1) == LUA_TFUNCTION) { lua_remove(L, -2); l_push_mkroom_table(L, troom); - if (nhl_pcall(L, 1, 0)){ - impossible("Lua error: %s", lua_tostring(L, -1)); - } + nhl_pcall_handle(L, 1, 0, "lspo_region", NHLpa_panic); } else { lua_pop(L, 1); } @@ -6880,9 +6872,7 @@ TODO: gc.coder->croom needs to be updated } else if (has_contents) { l_push_wid_hei_table(L, gx.xsize, gy.ysize); - if (nhl_pcall(L, 1, 0)){ - impossible("Lua error: %s", lua_tostring(L, -1)); - } + nhl_pcall_handle(L, 1, 0, "lspo_map", NHLpa_panic); reset_xystart_size(); } @@ -7049,7 +7039,7 @@ boolean load_special(const char *name) { boolean result = FALSE; - nhl_sandbox_info sbi = {NHL_SB_SAFE, 0, 0, 0}; + nhl_sandbox_info sbi = {NHL_SB_SAFE, 1*1024*1024, 0, 1*1024*1024}; create_des_coder(); diff --git a/sys/unix/sysconf b/sys/unix/sysconf index c02b546e0..7114a1bbd 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.7 sysconf $NHDT-Date: 1646322470 2022/03/03 15:47:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ +# NetHack 3.7 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.44 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. # @@ -93,7 +93,7 @@ MAXPLAYERS=10 # Use "Live logging" for important events (achievements, wishes, etc) # Only available if NetHack was compiled with LIVELOG. -# Only really meaningful for public servers. +# Only really meaningful for public servers or debugging. # See the log in-game with #chronicle -command. # Bitmask for kinds of things you want to log - combine the following values # as desired. @@ -113,7 +113,7 @@ MAXPLAYERS=10 # 0x1000 - Log 'minor' achievements - can be spammy # 0x2000 - Spoiler event; can include in livelog but hidden from #chronicle # 0x4000 - Include as 'major' event in dumplog; can be hidden from livelog -# 0x8000 - Livelog debug msgs (currently only 'enter new level') +# 0x8000 - Livelog debug msgs #LIVELOG=0x1FFF # Show debugging information originating from these source files. diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 122c2a96d..96669d23d 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixmain.c $NHDT-Date: 1699233290 2023/11/06 01:14:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ */ +/* NetHack 3.7 unixmain.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.124 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -482,6 +482,14 @@ process_options(int argc, char *argv[]) config_error_add("Unknown option: %.60s", origarg); } break; + case 'l': +#ifdef LIVELOG + if(!strncmp(arg, "-loglua", 7)){ + gl.loglua = 1; + } else +#endif + config_error_add("Unknown option: %.60s", origarg); + break; case 'p': /* profession (role) */ if (arg[2]) { if ((i = str2role(&arg[2])) >= 0) diff --git a/sys/vms/sysconf b/sys/vms/sysconf index a518dc32c..8fb357e3c 100644 --- a/sys/vms/sysconf +++ b/sys/vms/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.7 sysconf $NHDT-Date: 1596498305 2020/08/03 23:45:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +# NetHack 3.7 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.7 $ # Copyright (c) 2015 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # @@ -77,7 +77,7 @@ HIDEUSAGE=1 # Use "Live logging" for important events (achievements, wishes, etc) # Only available if NetHack was compiled with LIVELOG. -# Only really meaningful for public servers. +# Only really meaningful for public servers or debugging. # See the log in-game with #chronicle -command. # Bitmask for kinds of things you want to log - combine the following values # as desired. @@ -97,7 +97,7 @@ HIDEUSAGE=1 # 0x1000 - Log 'minor' achievements - can be spammy # 0x2000 - Spoiler event; can include in livelog but hidden from #chronicle # 0x4000 - Include as 'major' event in dumplog; can be hidden from livelog -# 0x8000 - Livelog debug msgs (currently only 'enter new level') +# 0x8000 - Livelog debug msgs #LIVELOG=0x1FFF # Show debugging information originating from these source files.