Cleans up PRVM_Crash() calling and removes redundant code.
Directs menu errors to stderr instead of stdout.
Aborts if a loop is detected in MVM_error_cmd(), matching Host_Error().
Prevents QC's CSQC_Shutdown() being called when CSQC crashes.
Makes cvar prvm_errordump ignore MENUQC crashes.
Improves some messages and comments.
Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
dp_strlcpy(hosterrorstring2, hosterrorstring1, sizeof(hosterrorstring2));
CL_Parse_DumpPacket();
-
CL_Parse_ErrorCleanUp();
- //PR_Crash();
-
// print out where the crash happened, if it was caused by QC (and do a cleanup)
- PRVM_Crash(SVVM_prog);
- PRVM_Crash(CLVM_prog);
-#ifdef CONFIG_MENU
- PRVM_Crash(MVM_prog);
-#endif
-
- Cvar_SetValueQuick(&csqc_progcrc, -1);
- Cvar_SetValueQuick(&csqc_progsize, -1);
+ PRVM_Crash();
if(host.hook.SV_Shutdown)
host.hook.SV_Shutdown();
if (cls.state == ca_dedicated)
- Sys_Abort ("Host_Error: %s",hosterrorstring2); // dedicated servers exit
+ Sys_Abort("Host_Error: %s", hosterrorstring1); // dedicated servers exit
// prevent an endless loop if the error was triggered by a command
Cbuf_Clear(cmd_local->cbuf);
- // DP8 TODO: send a disconnect message indicating we errored out, see Sys_Abort() and Sys_HandleCrash()
- CL_Disconnect();
- cls.demonum = -1;
+ CL_DisconnectEx(false, "Host_Error: %s", hosterrorstring1);
+ cls.demonum = -1; // stop demo loop
hosterror = false;
void MVM_error_cmd(const char *format, ...) DP_FUNC_PRINTF(1);
void MVM_error_cmd(const char *format, ...)
{
- prvm_prog_t *prog = MVM_prog;
static qbool processingError = false;
char errorstring[MAX_INPUTLINE];
va_list argptr;
+ int outfd = sys.outfd;
+
+ // set output to stderr
+ sys.outfd = fileno(stderr);
va_start (argptr, format);
dpvsnprintf (errorstring, sizeof(errorstring), format, argptr);
va_end (argptr);
if (host.framecount < 3)
- Sys_Abort("Menu_Error: %s\n", errorstring);
+ Sys_Abort("Menu_Error: %s", errorstring);
- Con_Printf( "Menu_Error: %s\n", errorstring );
+ Con_Printf(CON_ERROR "Menu_Error: %s\n", errorstring);
- if( !processingError ) {
+ if(!processingError)
+ {
processingError = true;
- PRVM_Crash(prog);
+ PRVM_Crash();
processingError = false;
- } else {
- Con_Printf( "Menu_Error: Recursive call to MVM_error_cmd (from PRVM_Crash)!\n" );
}
+ else
+ Sys_Abort("Menu_Error: Recursive call to MVM_error_cmd (from PRVM_Crash)!");
- // fall back to the normal menu
-
- // say it
- Con_Print("Falling back to normal menu\n");
-
+ Con_Print("Falling back to engine menu\n");
key_dest = key_game;
-
- // init the normal menu now -> this will also correct the menu router pointers
MR_SetRouting (true);
// reset the active scene, too (to be on the safe side ;))
// prevent an endless loop if the error was triggered by a command
Cbuf_Clear(cmd_local->cbuf);
+ // restore configured outfd
+ sys.outfd = outfd;
+
// Let video start at least
Host_AbortCurrentFrame();
}
void PRVM_PrintFunction_f(struct cmd_state_s *cmd);
void PRVM_PrintState(prvm_prog_t *prog, int stack_index);
-void PRVM_Crash(prvm_prog_t *prog);
+void PRVM_Crash(void);
void PRVM_ShortStackTrace(prvm_prog_t *prog, char *buf, size_t bufsize);
const char *PRVM_AllocationOrigin(prvm_prog_t *prog);
void PRVM_GarbageCollection(prvm_prog_t *prog);
}
extern cvar_t prvm_errordump;
-void PRVM_Crash(prvm_prog_t *prog)
+void PRVM_Crash(void)
{
+ prvm_prog_t *prog;
char vabuf[1024];
- int outfd = sys.outfd;
-
- if (prog == NULL)
- return;
- if (!prog->loaded)
- return;
+ int i;
- // set output to stderr
- sys.outfd = fileno(stderr);
+ // determine which program crashed
+ for (i = 0; i < PRVM_PROG_MAX; ++i)
+ if (PRVM_GetProg(i)->loaded && PRVM_GetProg(i)->depth > 0)
+ break;
+ if (i >= PRVM_PROG_MAX)
+ return; // none of them crashed
+ prog = PRVM_GetProg(i);
- PRVM_serverfunction(SV_Shutdown) = 0; // don't call SV_Shutdown on crash
+ Con_Printf("QuakeC crash report for %s:\n", prog->name);
+ PRVM_PrintState(prog, 0);
- if( prog->depth > 0 )
- {
- Con_Printf("QuakeC crash report for %s:\n", prog->name);
- PRVM_PrintState(prog, 0);
- }
+ // don't call graceful shutdown on crash
+ if (prog == SVVM_prog)
+ PRVM_serverfunction(SV_Shutdown) = 0;
+ else if (prog == CLVM_prog)
+ PRVM_clientfunction(CSQC_Shutdown) = 0;
- if(prvm_errordump.integer)
+ if(prvm_errordump.integer && (prog == SVVM_prog || prog == CLVM_prog))
{
// make a savegame
SV_Savegame_to(prog, va(vabuf, sizeof(vabuf), "crash-%s.dmp", prog->name));
// dump the stack so host_error can shutdown functions
prog->depth = 0;
prog->localstack_used = 0;
-
- // delete all tempstrings (FIXME: is this safe in VM->engine->VM recursion?)
- prog->tempstringsbuf.cursize = 0;
-
- // reset the prog pointer
- prog = NULL;
-
- // restore configured outfd
- sys.outfd = outfd;
}
/*
if (prog == SVVM_prog)
SV_FlushBroadcastMessages();
}
-#endif
+#endif // CONFIG_MENU
/*
====================
if (prog == SVVM_prog)
SV_FlushBroadcastMessages();
}
-#endif
+#endif // PROFILING
/*
====================