From 56ba064e5d764afe2f3e6f4bee937b4dbff3638e Mon Sep 17 00:00:00 2001 From: divverent Date: Sat, 19 Jul 2008 19:31:03 +0000 Subject: [PATCH 1/1] add feature "prvm_errordump" to make a savegame on PRVM_Crash - hopefully this helps me find the teambubble.owner==NULL crash bug git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8417 d7cf8633-e32d-0410-b094-e92efae38249 --- host_cmd.c | 119 ++++++++++++++++++++++++++++++--------------------- prvm_edict.c | 2 + prvm_exec.c | 8 ++++ 3 files changed, 80 insertions(+), 49 deletions(-) diff --git a/host_cmd.c b/host_cmd.c index 5c835c63..1a1b3d8d 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -435,6 +435,75 @@ LOAD / SAVE GAME #define SAVEGAME_VERSION 5 +void Host_Savegame_to (const char *name) +{ + qfile_t *f; + int i; + char comment[SAVEGAME_COMMENT_LENGTH+1]; + qboolean isserver; + + isserver = !strcmp(PRVM_NAME, "server"); + + Con_Printf("Saving game to %s...\n", name); + f = FS_Open (name, "wb", false, false); + if (!f) + { + Con_Print("ERROR: couldn't open.\n"); + return; + } + + FS_Printf(f, "%i\n", SAVEGAME_VERSION); + + memset(comment, 0, sizeof(comment)); + if(isserver) + dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(prog->edicts->fields.server->message), (int)prog->globals.server->killed_monsters, (int)prog->globals.server->total_monsters); + else + dpsnprintf(comment, sizeof(comment), "(crash dump of %s progs)", PRVM_NAME); + // convert space to _ to make stdio happy + // LordHavoc: convert control characters to _ as well + for (i=0 ; inum_edicts ; i++) + { + //Con_Printf("edict %d...\n", i); + PRVM_ED_Write (f, PRVM_EDICT_NUM(i)); + } + + FS_Close (f); + Con_Print("done.\n"); +} + /* =============== Host_Savegame_f @@ -443,9 +512,6 @@ Host_Savegame_f void Host_Savegame_f (void) { char name[MAX_QPATH]; - qfile_t *f; - int i; - char comment[SAVEGAME_COMMENT_LENGTH+1]; if (!sv.active) { @@ -486,54 +552,9 @@ void Host_Savegame_f (void) strlcpy (name, Cmd_Argv(1), sizeof (name)); FS_DefaultExtension (name, ".sav", sizeof (name)); - Con_Printf("Saving game to %s...\n", name); - f = FS_Open (name, "wb", false, false); - if (!f) - { - Con_Print("ERROR: couldn't open.\n"); - return; - } - SV_VM_Begin(); - - FS_Printf(f, "%i\n", SAVEGAME_VERSION); - - memset(comment, 0, sizeof(comment)); - dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(prog->edicts->fields.server->message), (int)prog->globals.server->killed_monsters, (int)prog->globals.server->total_monsters); - // convert space to _ to make stdio happy - // LordHavoc: convert control characters to _ as well - for (i=0 ; inum_edicts ; i++) - { - Con_Printf("edict %d...\n", i); - PRVM_ED_Write (f, PRVM_EDICT_NUM(i)); - } - + Host_Savegame_to(name); SV_VM_End(); - - FS_Close (f); - Con_Print("done.\n"); } diff --git a/prvm_edict.c b/prvm_edict.c index cb5ef02a..1ccfc36a 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -42,6 +42,7 @@ cvar_t prvm_statementprofiling = {0, "prvm_statementprofiling", "0", "counts how cvar_t prvm_backtraceforwarnings = {0, "prvm_backtraceforwarnings", "0", "print a backtrace for warnings too"}; cvar_t prvm_leaktest = {0, "prvm_leaktest", "0", "try to detect memory leaks in strings or entities"}; 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"}; extern sizebuf_t vm_tempstringsbuf; @@ -2097,6 +2098,7 @@ void PRVM_Init (void) Cvar_RegisterVariable (&prvm_backtraceforwarnings); Cvar_RegisterVariable (&prvm_leaktest); Cvar_RegisterVariable (&prvm_leaktest_ignore_classnames); + Cvar_RegisterVariable (&prvm_errordump); //VM_Cmd_Init(); } diff --git a/prvm_exec.c b/prvm_exec.c index b866ed27..8adee10f 100644 --- a/prvm_exec.c +++ b/prvm_exec.c @@ -455,6 +455,8 @@ 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) @@ -468,6 +470,12 @@ void PRVM_Crash(void) 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; -- 2.39.2