static INLINE NORETURN void VMToolsLogPanic(void) { gPanicCount++; if (gEnableCoreDump) { #if defined(_WIN32) CoreDump_CoreDump(); #else char cwd[PATH_MAX]; if (getcwd(cwd, sizeof cwd) != NULL) { if (access(cwd, W_OK) == -1) { /* * Can't write to the working dir. chdir() to the user's home * directory as an attempt to get a valid core dump. */ const char *home = getenv("HOME"); if (home != NULL) { if (chdir(home)) { /* Just to make glibc headers happy. */ } } } } abort(); #endif } /* Same behavior as Panic_Panic(). */ exit(-1); }
static INLINE NORETURN void VMToolsLogPanic(void) { gPanicCount++; /* * Probably, flush the cached logs here. It is not * critial though because we will have the cached * logs in memory anyway. */ if (gEnableCoreDump) { /* * TODO: Make sure to thaw the filesystem before dumping core. */ #if defined(_WIN32) CoreDump_CoreDump(); #else char cwd[PATH_MAX]; if (getcwd(cwd, sizeof cwd) != NULL) { if (access(cwd, W_OK) == -1) { /* * Can't write to the working dir. chdir() to the user's home * directory as an attempt to get a valid core dump. */ const char *home = getenv("HOME"); if (home != NULL) { if (chdir(home)) { /* Just to make glibc headers happy. */ } } } } abort(); #endif } /* Same behavior as Panic_Panic(). */ exit(-1); }
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(); }