void Panic_Panic(const char *format, va_list args) { char buf[1024]; static int count = 0; Str_Vsnprintf(buf, sizeof buf, format, args); /* * Write the message to stderr first, so there's always * some sort of record. * Don't try to do anything fancy, since this is before * panic loop detection. In particular, try not to call * any of our functions (that may call Panic()). */ fputs(buf, stderr); #ifdef _WIN32 Win32U_OutputDebugString(buf); #endif /* * Make sure Panic gets logged */ Log_DisableThrottling(); /* * Panic loop detection: * first time - do the whole report and shutdown sequence * second time - log and exit * beyond second time - just exit */ switch (count++) { case 0: break; case 1: Log("%s", buf); Log("Panic loop\n"); default: fprintf(stderr, "Panic loop\n"); Util_ExitProcessAbruptly(1); NOT_REACHED(); } /* * Log panic information, and make sure we don't remove * the log file on exit. */ Log("%s", buf); Util_Backtrace(0); Log_SetAlwaysKeep(TRUE); /* * Do the debugging steps early before we have a chance * to double panic. */ Panic_DumpGuiResources(); #if defined(_WIN32) || !defined(VMX86_TOOLS) if (Panic_GetCoreDumpOnPanic()) { CoreDump_CoreDump(); } #endif Panic_LoopOnPanic(); /* * Show pretty panic dialog. * This is where things can go badly wrong. */ Panic_PostPanicMsg(buf); /* * Bye */ exit(-1); NOT_REACHED(); }
void Panic_Panic(const char *format, va_list args) { char buf[1024]; static int count = 0; MXUser_SetInPanic(); Str_Vsnprintf(buf, sizeof buf, format, args); /* * Write the message to stderr first, so there's always * some sort of record. * Don't try to do anything fancy, since this is before * panic loop detection. In particular, try not to call * any of our functions (that may call Panic()). */ fputs(buf, stderr); #ifdef _WIN32 /* * This would nominally be Win32U_OutputDebugString. However, * OutputDebugString is unusual in that the W version converts * to local encoding and calls the A version. * * Since any such conversion is risky (read: can Panic) and * we haven't yet hit the loop detection, we will conservatively * dump UTF-8 via the A version. */ OutputDebugStringA(buf); #endif /* * Make sure Panic gets logged */ Log_DisableThrottling(); /* * Panic loop detection: * first time - do the whole report and shutdown sequence * second time - log and exit * beyond second time - just exit */ switch (count++) { case 0: break; case 1: Log("PANIC: %s", buf); Log("Panic loop\n"); default: fprintf(stderr, "Panic loop\n"); Util_ExitProcessAbruptly(1); NOT_REACHED(); } #ifdef _WIN32 /* * Output again, in a way that we hope localizes correctly. Since * we are converting, this can Panic, so it must run after loop * detection. */ Win32U_OutputDebugString(buf); #endif /* * Log panic information. */ Log("PANIC: %s", buf); Util_Backtrace(0); /* * Do the debugging steps early before we have a chance * to double panic. */ Panic_DumpGuiResources(); #if defined(_WIN32) || !defined(VMX86_TOOLS) if (Panic_GetCoreDumpOnPanic()) { CoreDump_CoreDump(); } #endif Panic_LoopOnPanic(); /* * Show pretty panic dialog. * This is where things can go badly wrong. */ Panic_PostPanicMsg(buf); /* * Bye */ Log("Exiting\n"); exit(-1); NOT_REACHED(); }