From a44c18f516d470fe652cbea592065a5d23b5531c Mon Sep 17 00:00:00 2001 From: divverent Date: Tue, 13 Jan 2009 09:15:13 +0000 Subject: [PATCH] remove the PRVM_BOUNDSCHECK_CVAR define instead, add a -noboundscheck command line option (those who really want to make use of that in their mod can easily make a wrapper that adds this command, e.g. a lnk file in the start menu) also add a -norunaway command line option that turns off the runaway loop counter git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8645 d7cf8633-e32d-0410-b094-e92efae38249 --- prvm_edict.c | 21 +++++---- prvm_exec.c | 111 +++++++++++++++++++++++++++++++++++---------- prvm_execprogram.h | 6 +++ 3 files changed, 106 insertions(+), 32 deletions(-) diff --git a/prvm_edict.c b/prvm_edict.c index d8499c43..f1fb2a28 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -31,10 +31,6 @@ int prvm_type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(v ddef_t *PRVM_ED_FieldAtOfs(int ofs); qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s, qboolean parsebackslash); -// LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others)) -#ifdef PRVM_BOUNDSCHECK_CVAR -cvar_t prvm_boundscheck = {0, "prvm_boundscheck", "1", "enables detection of out of bounds memory access in the QuakeC code being run (in other words, prevents really exceedingly bad QuakeC code from doing nasty things to your computer)"}; -#endif // LordHavoc: prints every opcode as it executes - warning: this is significant spew cvar_t prvm_traceqc = {0, "prvm_traceqc", "0", "prints every QuakeC statement as it is executed (only for really thorough debugging!)"}; // LordHavoc: counts usage of each QuakeC statement @@ -44,6 +40,12 @@ cvar_t prvm_leaktest = {0, "prvm_leaktest", "0", "try to detect memory leaks in cvar_t prvm_leaktest_ignore_classnames = {0, "prvm_leaktest_ignore_classnames", "", "classnames of entities to NOT leak check because they are found by find(world, classname, ...) but are actually spawned by QC code (NOT map entities)"}; cvar_t prvm_errordump = {0, "prvm_errordump", "0", "write a savegame on crash to crash-server.dmp"}; +qboolean prvm_runawaycheck = true; + +// LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others)) +// enables detection of out of bounds memory access in the QuakeC code being run (in other words, prevents really exceedingly bad QuakeC code from doing nasty things to your computer) +qboolean prvm_boundscheck = true; + extern sizebuf_t vm_tempstringsbuf; //============================================================================ @@ -2112,10 +2114,10 @@ void PRVM_Init (void) Cmd_AddCommand ("cl_cmd", PRVM_GameCommand_Client_f, "calls the client QC function GameCommand with the supplied string as argument"); Cmd_AddCommand ("menu_cmd", PRVM_GameCommand_Menu_f, "calls the menu QC function GameCommand with the supplied string as argument"); Cmd_AddCommand ("sv_cmd", PRVM_GameCommand_Server_f, "calls the server QC function GameCommand with the supplied string as argument"); - // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others)) -#ifdef PRVM_BOUNDSCHECK_CVAR - Cvar_RegisterVariable (&prvm_boundscheck); -#endif + + // COMMANDLINEOPTION: PRVM: -noboundscheck disables the bounds checks (security hole if CSQC is in use!) + prvm_boundscheck = !COM_CheckParm("-noboundscheck"); + Cvar_RegisterVariable (&prvm_traceqc); Cvar_RegisterVariable (&prvm_statementprofiling); Cvar_RegisterVariable (&prvm_backtraceforwarnings); @@ -2123,6 +2125,9 @@ void PRVM_Init (void) Cvar_RegisterVariable (&prvm_leaktest_ignore_classnames); Cvar_RegisterVariable (&prvm_errordump); + // COMMANDLINEOPTION: PRVM: -norunaway disables the runaway loop check (it might be impossible to exit DarkPlaces if used!) + prvm_runawaycheck = !COM_CheckParm("-norunaway"); + //VM_Cmd_Init(); } diff --git a/prvm_exec.c b/prvm_exec.c index 8adee10f..f644f9fd 100644 --- a/prvm_exec.c +++ b/prvm_exec.c @@ -586,12 +586,11 @@ PRVM_ExecuteProgram #define OPA ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->a]) #define OPB ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->b]) #define OPC ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->c]) -#ifdef PRVM_BOUNDSCHECK_CVAR -extern cvar_t prvm_boundscheck; -#endif extern cvar_t prvm_traceqc; extern cvar_t prvm_statementprofiling; extern sizebuf_t vm_tempstringsbuf; +extern qboolean prvm_runawaycheck; +extern qboolean prvm_boundscheck; void PRVM_ExecuteProgram (func_t fnum, const char *errormessage) { dstatement_t *st, *startst; @@ -634,77 +633,141 @@ void PRVM_ExecuteProgram (func_t fnum, const char *errormessage) chooseexecprogram: cachedpr_trace = prog->trace; - if (prvm_statementprofiling.integer) + if (prvm_runawaycheck) { -#define PRVMSTATEMENTPROFILING 1 -#ifdef PRVM_BOUNDSCHECK_CVAR - if (prvm_boundscheck.integer) -#endif +#define PRVMRUNAWAYCHECK 1 + if (prvm_statementprofiling.integer) { -#define PRVMBOUNDSCHECK 1 - if (prog->trace) +#define PRVMSTATEMENTPROFILING 1 + if (prvm_boundscheck) { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { #define PRVMTRACE 1 #include "prvm_execprogram.h" #undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK } else { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { #include "prvm_execprogram.h" + } } -#undef PRVMBOUNDSCHECK +#undef PRVMSTATEMENTPROFILING } -#ifdef PRVM_BOUNDSCHECK_CVAR else { - if (prog->trace) + if (prvm_boundscheck) { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { #define PRVMTRACE 1 #include "prvm_execprogram.h" #undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK } else { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { #include "prvm_execprogram.h" + } } } -#endif -#undef PRVMSTATEMENTPROFILING +#undef PRVMRUNAWAYCHECK 1 } else { -#ifdef PRVM_BOUNDSCHECK_CVAR - if (prvm_boundscheck.integer) -#endif + if (prvm_statementprofiling.integer) { -#define PRVMBOUNDSCHECK 1 - if (prog->trace) +#define PRVMSTATEMENTPROFILING 1 + if (prvm_boundscheck) { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { #define PRVMTRACE 1 #include "prvm_execprogram.h" #undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK } else { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { #include "prvm_execprogram.h" + } } -#undef PRVMBOUNDSCHECK +#undef PRVMSTATEMENTPROFILING } -#ifdef PRVM_BOUNDSCHECK_CVAR else { - if (prog->trace) + if (prvm_boundscheck) { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { #define PRVMTRACE 1 #include "prvm_execprogram.h" #undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK } else { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { #include "prvm_execprogram.h" + } } } -#endif } cleanup: diff --git a/prvm_execprogram.h b/prvm_execprogram.h index 38a13859..064054e8 100644 --- a/prvm_execprogram.h +++ b/prvm_execprogram.h @@ -243,12 +243,14 @@ prog->xfunction->profile += (st - startst); st += st->b - 1; // offset the s++ startst = st; +#if PRVMRUNAWAYCHECK if (++jumpcount == 10000000) { prog->xstatement = st - prog->statements; PRVM_Profile(1<<30, 1000000); PRVM_ERROR("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", PRVM_NAME, jumpcount); } +#endif } break; @@ -258,12 +260,14 @@ prog->xfunction->profile += (st - startst); st += st->b - 1; // offset the s++ startst = st; +#if PRVMRUNAWAYCHECK if (++jumpcount == 10000000) { prog->xstatement = st - prog->statements; PRVM_Profile(1<<30, 1000000); PRVM_ERROR("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", PRVM_NAME, jumpcount); } +#endif } break; @@ -271,12 +275,14 @@ prog->xfunction->profile += (st - startst); st += st->a - 1; // offset the s++ startst = st; +#if PRVMRUNAWAYCHECK if (++jumpcount == 10000000) { prog->xstatement = st - prog->statements; PRVM_Profile(1<<30, 1000000); PRVM_ERROR("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", PRVM_NAME, jumpcount); } +#endif break; case OP_CALL0: -- 2.39.2