X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=prvm_exec.c;h=ae340eece405769163407311c0ece5420106518f;hb=9a48353dc19ae3bf696fabbfa0388e200fb5acfc;hp=7481114822f751e2948290990a8ca322f7ff11f8;hpb=fe0d5dc2d85167fb8042bcb5157e93728e74e53a;p=xonotic%2Fdarkplaces.git diff --git a/prvm_exec.c b/prvm_exec.c index 74811148..ae340eec 100644 --- a/prvm_exec.c +++ b/prvm_exec.c @@ -265,6 +265,74 @@ void PRVM_StackTrace (void) } } +void PRVM_ShortStackTrace(char *buf, size_t bufsize) +{ + mfunction_t *f; + int i; + + if(prog) + { + dpsnprintf(buf, bufsize, "(%s) ", prog->name); + } + else + { + strlcpy(buf, "", sizeof(buf)); + return; + } + + prog->stack[prog->depth].s = prog->xstatement; + prog->stack[prog->depth].f = prog->xfunction; + for (i = prog->depth;i > 0;i--) + { + f = prog->stack[i].f; + + if(strlcat(buf, + f + ? va("%s:%s(%i) ", PRVM_GetString(f->s_file), PRVM_GetString(f->s_name), prog->stack[i].s - f->first_statement) + : " ", + bufsize + ) >= bufsize) + break; + } +} + + +void PRVM_CallProfile () +{ + mfunction_t *f, *best; + int i; + double max; + double sum; + + Con_Printf( "%s Call Profile:\n", PRVM_NAME ); + + sum = 0; + do + { + max = 0; + best = NULL; + for (i=0 ; iprogs->numfunctions ; i++) + { + f = &prog->functions[i]; + if (max < f->totaltime) + { + max = f->totaltime; + best = f; + } + } + if (best) + { + sum += best->totaltime; + Con_Printf("%9.4f %s\n", best->totaltime, PRVM_GetString(best->s_name)); + best->totaltime = 0; + } + } while (best); + + Con_Printf("Total time since last profile reset: %9.4f\n", Sys_DoubleTime() - prog->starttime); + Con_Printf(" - used by QC code of this VM: %9.4f\n", sum); + + prog->starttime = Sys_DoubleTime(); +} void PRVM_Profile (int maxfunctions, int mininstructions) { @@ -305,6 +373,29 @@ void PRVM_Profile (int maxfunctions, int mininstructions) } while (best); } +/* +============ +PRVM_CallProfile_f + +============ +*/ +void PRVM_CallProfile_f (void) +{ + if (Cmd_Argc() != 2) + { + Con_Print("prvm_callprofile \n"); + return; + } + + PRVM_Begin; + if(!PRVM_SetProgFromString(Cmd_Argv(1))) + return; + + PRVM_CallProfile(); + + PRVM_End; +} + /* ============ PRVM_Profile_f @@ -364,17 +455,27 @@ void PRVM_PrintState(void) } extern sizebuf_t vm_tempstringsbuf; +extern cvar_t prvm_errordump; +void Host_Savegame_to (const char *name); void PRVM_Crash(void) { if (prog == NULL) return; + prog->funcoffsets.SV_Shutdown = 0; // don't call SV_Shutdown on crash + if( prog->depth > 0 ) { Con_Printf("QuakeC crash report for %s:\n", PRVM_NAME); PRVM_PrintState(); } + if(prvm_errordump.integer) + { + // make a savegame + Host_Savegame_to(va("crash-%s.dmp", PRVM_NAME)); + } + // dump the stack so host_error can shutdown functions prog->depth = 0; prog->localstack_used = 0; @@ -485,10 +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]) -extern cvar_t prvm_boundscheck; 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; @@ -497,11 +599,14 @@ void PRVM_ExecuteProgram (func_t fnum, const char *errormessage) prvm_eval_t *ptr; int jumpcount, cachedpr_trace, exitdepth; int restorevm_tempstringsbuf_cursize; + double calltime; + + calltime = Sys_DoubleTime(); if (!fnum || fnum >= (unsigned int)prog->progs->numfunctions) { if (prog->globaloffsets.self >= 0 && PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict) - PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict)); + PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict), NULL); PRVM_ERROR ("PRVM_ExecuteProgram: %s", errormessage); } @@ -528,67 +633,139 @@ void PRVM_ExecuteProgram (func_t fnum, const char *errormessage) chooseexecprogram: cachedpr_trace = prog->trace; - if (prvm_statementprofiling.integer) + if (prvm_runawaycheck) { -#define PRVMSTATEMENTPROFILING 1 - if (prvm_boundscheck.integer) +#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 } 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" + } } } -#undef PRVMSTATEMENTPROFILING +#undef PRVMRUNAWAYCHECK } else { - if (prvm_boundscheck.integer) + 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 } 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" + } } } } @@ -598,4 +775,8 @@ cleanup: Con_Printf("PRVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog->functions[fnum].s_name), vm_tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize); // delete tempstrings created by this function vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; + + prog->functions[fnum].totaltime += (Sys_DoubleTime() - calltime); + + SV_FlushBroadcastMessages(); }