File diff r21435:37fd42ff92b8 → r21436:38079fc3bcd8
src/os/windows/crashlog_win.cpp
Show inline comments
 
@@ -478,97 +478,97 @@ char *CrashLogWindows::AppendDecodedStac
 
	return ret;
 
}
 
#endif /* _MSC_VER */
 

	
 
extern bool CloseConsoleLogIfActive();
 
static void ShowCrashlogWindow();
 

	
 
/**
 
 * Stack pointer for use when 'starting' the crash handler.
 
 * Not static as gcc's inline assembly needs it that way.
 
 */
 
void *_safe_esp = NULL;
 

	
 
static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
 
{
 
	if (CrashLogWindows::current != NULL) {
 
		CrashLog::AfterCrashLogCleanup();
 
		ExitProcess(2);
 
	}
 

	
 
	if (GamelogTestEmergency()) {
 
		static const TCHAR _emergency_crash[] =
 
			_T("A serious fault condition occurred in the game. The game will shut down.\n")
 
			_T("As you loaded an emergency savegame no crash information will be generated.\n");
 
		MessageBox(NULL, _emergency_crash, _T("Fatal Application Failure"), MB_ICONERROR);
 
		ExitProcess(3);
 
	}
 

	
 
	if (SaveloadCrashWithMissingNewGRFs()) {
 
		static const TCHAR _saveload_crash[] =
 
			_T("A serious fault condition occurred in the game. The game will shut down.\n")
 
			_T("As you loaded an savegame for which you do not have the required NewGRFs\n")
 
			_T("no crash information will be generated.\n");
 
		MessageBox(NULL, _saveload_crash, _T("Fatal Application Failure"), MB_ICONERROR);
 
		ExitProcess(3);
 
	}
 

	
 
	CrashLogWindows *log = new CrashLogWindows(ep);
 
	CrashLogWindows::current = log;
 
	char *buf = log->FillCrashLog(log->crashlog, lastof(log->crashlog));
 
	log->WriteCrashDump(log->crashdump_filename, lastof(log->crashdump_filename));
 
	log->AppendDecodedStacktrace(buf, lastof(log->crashlog));
 
	log->WriteCrashLog(log->crashlog, log->crashlog_filename, lastof(log->crashlog_filename));
 
	log->WriteScreenshot(log->screenshot_filename, lastof(log->screenshot_filename));
 

	
 
	/* Close any possible log files */
 
	CloseConsoleLogIfActive();
 

	
 
	if ((_video_driver == NULL || _video_driver->HasGUI()) && _safe_esp != NULL) {
 
	if ((VideoDriver::GetInstance() == NULL || VideoDriver::GetInstance()->HasGUI()) && _safe_esp != NULL) {
 
#ifdef _M_AMD64
 
		ep->ContextRecord->Rip = (DWORD64)ShowCrashlogWindow;
 
		ep->ContextRecord->Rsp = (DWORD64)_safe_esp;
 
#else
 
		ep->ContextRecord->Eip = (DWORD)ShowCrashlogWindow;
 
		ep->ContextRecord->Esp = (DWORD)_safe_esp;
 
#endif
 
		return EXCEPTION_CONTINUE_EXECUTION;
 
	}
 

	
 
	CrashLog::AfterCrashLogCleanup();
 
	return EXCEPTION_EXECUTE_HANDLER;
 
}
 

	
 
static void CDECL CustomAbort(int signal)
 
{
 
	RaiseException(0xE1212012, 0, 0, NULL);
 
}
 

	
 
/* static */ void CrashLog::InitialiseCrashLog()
 
{
 
#ifdef _M_AMD64
 
	CONTEXT ctx;
 
	RtlCaptureContext(&ctx);
 

	
 
	/* The stack pointer for AMD64 must always be 16-byte aligned inside a
 
	 * function. As we are simulating a function call with the safe ESP value,
 
	 * we need to subtract 8 for the imaginary return address otherwise stack
 
	 * alignment would be wrong in the called function. */
 
	_safe_esp = (void *)(ctx.Rsp - 8);
 
#else
 
#if defined(_MSC_VER)
 
	_asm {
 
		mov _safe_esp, esp
 
	}
 
#else
 
	asm("movl %esp, __safe_esp");
 
#endif
 
#endif
 

	
 
	/* SIGABRT is not an unhandled exception, so we need to intercept it. */
 
	signal(SIGABRT, CustomAbort);
 
#if defined(_MSC_VER)
 
	/* Don't show abort message as we will get the crashlog window anyway. */
 
	_set_abort_behavior(0, _WRITE_ABORT_MSG);
 
#endif
 
	SetUnhandledExceptionFilter(ExceptionHandler);
 
}