void PRVM_ShortStackTrace(prvm_prog_t *prog, char *buf, size_t bufsize)
{
- mfunction_t *f;
- int i;
+ mfunction_t *f;
+ int i;
char vabuf[1024];
+ char *p;
if(prog)
{
- dpsnprintf(buf, bufsize, "(%s) ", prog->name);
+ i = dpsnprintf(buf, bufsize, "(%s) ", prog->name);
+ p = buf + max(0, i);
}
else
{
for (i = prog->depth;i > 0;i--)
{
f = prog->stack[i].f;
-
- if(dp_strlcat(buf,
+ p = dp_stpecpy(
+ p,
+ buf + bufsize,
f
? va(vabuf, sizeof(vabuf), "%s:%s(%i) ", PRVM_GetString(prog, f->s_file), PRVM_GetString(prog, f->s_name), prog->stack[i].s - f->first_statement)
- : "<NULL> ",
- bufsize
- ) >= bufsize)
+ : "<NULL> "
+ );
+ if (p == buf + bufsize)
break;
}
}
}
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;
-
- cl.csqc_loaded = false;
-
- 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
/*
====================