From 56561de0acdb9cf29d155992440ac3e0d32909dd Mon Sep 17 00:00:00 2001 From: black Date: Wed, 1 Jun 2005 19:21:09 +0000 Subject: [PATCH] -Added Host_AbortCurrentFrame to hide the longjump and make it usable by the VM error functions. -Moved the static variables of Host_Error into the function body. -Changed the definition of error_cmd to be called instead of Host_Error, so the VM control code is in full control of the error processing. -Added MP_Error to the menu, so a menu crash wont shutdown the server anymore. -Fixed an annying bug caused by a typo, that crashes Nexuiz if you query for a string in the serverlist. -PRVM_Crash resets the prog pointer now. -PRVM_Begin use Con_Printf again (but PRVM_DEBUGPRSTACK has been disabled again). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5374 d7cf8633-e32d-0410-b094-e92efae38249 --- host.c | 31 ++++++++++++++++++------------- menu.c | 28 ++++++++++++++++++++++++---- mvm_cmds.c | 2 +- progsvm.h | 8 ++++---- prvm_edict.c | 11 +++++------ prvm_exec.c | 15 +++++---------- quakedef.h | 2 ++ server.h | 2 -- 8 files changed, 59 insertions(+), 40 deletions(-) diff --git a/host.c b/host.c index da431962..608f9c2b 100644 --- a/host.c +++ b/host.c @@ -93,6 +93,18 @@ cvar_t temp1 = {0, "temp1","0"}; cvar_t timestamps = {CVAR_SAVE, "timestamps", "0"}; cvar_t timeformat = {CVAR_SAVE, "timeformat", "[%b %e %X] "}; +/* +================ +Host_AbortCurrentFrame + +aborts the current host frame and goes on with the next one +================ +*/ +void Host_AbortCurrentFrame(void) +{ + longjmp (host_abortserver, 1); +} + /* ================ Host_Error @@ -100,12 +112,11 @@ Host_Error This shuts down both the client and server ================ */ -void PRVM_ProcessError(void); -static char hosterrorstring1[4096]; -static char hosterrorstring2[4096]; -static qboolean hosterror = false; void Host_Error (const char *error, ...) { + static char hosterrorstring1[4096]; + static char hosterrorstring2[4096]; + static qboolean hosterror = false; va_list argptr; va_start (argptr,error); @@ -129,12 +140,9 @@ void Host_Error (const char *error, ...) //PR_Crash(); - //PRVM_Crash(); // crash current prog + // print out where the crash happened, if it was caused by QC (and do a cleanup) + PRVM_Crash(); - // crash all prvm progs - PRVM_CrashAll(); - - PRVM_ProcessError(); Host_ShutdownServer (false); @@ -146,7 +154,7 @@ void Host_Error (const char *error, ...) hosterror = false; - longjmp (host_abortserver, 1); + Host_AbortCurrentFrame(); } void Host_ServerOptions (void) @@ -488,8 +496,6 @@ void Host_ShutdownServer(qboolean crash) return; SV_VM_Begin(); - // print out where the crash happened, if it was caused by QC - //PRVM_Crash(); NetConn_Heartbeat(2); NetConn_Heartbeat(2); @@ -657,7 +663,6 @@ void Host_GetConsoleCommands (void) } } - /* ================== Host_ServerFrame diff --git a/menu.c b/menu.c index 466e9f1f..fadeafba 100644 --- a/menu.c +++ b/menu.c @@ -4605,8 +4605,18 @@ static func_t m_draw, m_keydown; void MR_SetRouting (qboolean forceold); -void MP_Error(void) +void MP_Error(const char *format, ...) { + char errorstring[4096]; + va_list argptr; + + va_start (argptr, format); + dpvsnprintf (errorstring, sizeof(errorstring), format, argptr); + va_end (argptr); + Con_Printf( "Menu_Error: %s\n", errorstring ); + + PRVM_Crash(); + // fall back to the normal menu // say it @@ -4614,10 +4624,10 @@ void MP_Error(void) key_dest = key_game; - //PRVM_ResetProg(); - // init the normal menu now -> this will also correct the menu router pointers MR_SetRouting (TRUE); + + Host_AbortCurrentFrame(); } void MP_Keydown (int key, char ascii) @@ -4689,6 +4699,16 @@ void MP_Shutdown (void) PRVM_End; } +void MP_Fallback (void) +{ + MP_Shutdown(); + + key_dest = key_game; + + // init the normal menu now -> this will also correct the menu router pointers + MR_SetRouting (TRUE); +} + void MP_Init (void) { PRVM_Begin; @@ -4797,7 +4817,7 @@ void MR_Init_Commands(void) Cvar_RegisterVariable (&forceqmenu); Cvar_RegisterVariable (&menu_options_colorcontrol_correctionvalue); if (gamemode == GAME_NETHERWORLD) - Cmd_AddCommand ("menu_fallback", MP_Error); //Force to old-style menu + Cmd_AddCommand ("menu_fallback", MP_Fallback); //Force to old-style menu Cmd_AddCommand ("menu_restart",MR_Restart); Cmd_AddCommand ("togglemenu", Call_MR_ToggleMenu_f); } diff --git a/mvm_cmds.c b/mvm_cmds.c index 401b33d6..55f1340c 100644 --- a/mvm_cmds.c +++ b/mvm_cmds.c @@ -442,7 +442,7 @@ void VM_M_setserverlistmaskstring( void ) int field; VM_SAFEPARMCOUNT( 4, VM_M_setserverlistmaskstring ); - str = PRVM_G_STRING( OFS_PARM1 ); + str = PRVM_G_STRING( OFS_PARM2 ); if( !str ) PRVM_ERROR( "VM_M_setserverlistmaskstring: null string passed!" ); diff --git a/progsvm.h b/progsvm.h index c40fd825..b8ebe800 100644 --- a/progsvm.h +++ b/progsvm.h @@ -360,7 +360,7 @@ typedef struct prvm_prog_s void (*init_cmd)(void); // [INIT] used by PRVM_InitProg void (*reset_cmd)(void); // [INIT] used by PRVM_ResetProg - void (*error_cmd)(void); // [INIT] + void (*error_cmd)(const char *format, ...); // [INIT] } prvm_prog_t; @@ -485,10 +485,10 @@ void PRVM_FreeString(char *s); //============================================================================ // used as replacement for a prog stack -#define PRVM_DEBUGPRSTACK +//#define PRVM_DEBUGPRSTACK #ifdef PRVM_DEBUGPRSTACK -#define PRVM_Begin if(prog != 0) Host_Error("prog not 0(prog = %i) in file: %s line: %i!\n", PRVM_GetProgNr(), __FILE__, __LINE__) +#define PRVM_Begin if(prog != 0) Con_Printf("prog not 0(prog = %i) in file: %s line: %i!\n", PRVM_GetProgNr(), __FILE__, __LINE__) #define PRVM_End prog = 0 #else #define PRVM_Begin @@ -506,7 +506,7 @@ void PRVM_FreeString(char *s); // helper macro to make function pointer calls easier #define PRVM_GCALL(func) if(prog->func) prog->func -#define PRVM_ERROR Host_Error +#define PRVM_ERROR prog->error_cmd // other prog handling functions qboolean PRVM_SetProgFromString(const char *str); diff --git a/prvm_edict.c b/prvm_edict.c index 8420dce8..33b37cc4 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -1234,6 +1234,10 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required ddef_t *infielddefs; dfunction_t *dfunctions; + if( prog->loaded ) { + PRVM_ERROR ("PRVM_LoadProgs: there is already a %s program loaded!\n", PRVM_NAME ); + } + prog->progs = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false); if (prog->progs == NULL) PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME); @@ -1716,6 +1720,7 @@ void PRVM_InitProg(int prognr) memset(prog, 0, sizeof(prvm_prog_t)); prog->time = &prog->_time; + prog->error_cmd = Host_Error; } int PRVM_GetProgNr() @@ -1748,12 +1753,6 @@ prvm_edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline) return NULL; } -void PRVM_ProcessError(void) -{ - if(prog) - PRVM_GCALL(error_cmd)(); -} - /* int NUM_FOR_EDICT_ERROR(prvm_edict_t *e) { diff --git a/prvm_exec.c b/prvm_exec.c index 4314b1fa..ab166f35 100644 --- a/prvm_exec.c +++ b/prvm_exec.c @@ -265,23 +265,18 @@ void PRVM_PrintState(void) void PRVM_Crash() { - - //TODO: make this more compilant with PR_Crash - if (prog->depth < 1) + if( prog->depth > 0 ) { - // kill the stack just to be sure - prog->depth = 0; - prog->localstack_used = 0; - return; + Con_Printf("QuakeC crash report for %s:\n", PRVM_NAME); + PRVM_PrintState(); } - Con_Printf("QuakeC crash report for %s:\n", PRVM_NAME); - PRVM_PrintState(); - // dump the stack so host_error can shutdown functions prog->depth = 0; prog->localstack_used = 0; + // reset the prog pointer + prog = NULL; } /* diff --git a/quakedef.h b/quakedef.h index 041280db..1c3dadd0 100644 --- a/quakedef.h +++ b/quakedef.h @@ -243,6 +243,8 @@ void Host_ClientCommands(const char *fmt, ...); void Host_ShutdownServer(qboolean crash); void Host_Reconnect_f(void); +void Host_AbortCurrentFrame(void); + // skill level for currently loaded level (in case the user changes the cvar while the level is running, this reflects the level actually in use) extern int current_skill; diff --git a/server.h b/server.h index ca02186f..606879b9 100644 --- a/server.h +++ b/server.h @@ -277,8 +277,6 @@ extern server_t sv; extern client_t *host_client; -extern jmp_buf host_abortserver; - //=========================================================== void SV_Init (void); -- 2.39.2