| 305 | thread_local void *_safe_esp = nullptr; |
| 306 | |
| 307 | static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep) |
| 308 | { |
| 309 | /* Restore system timer resolution. */ |
| 310 | timeEndPeriod(1); |
| 311 | |
| 312 | /* Disable our event loop. */ |
| 313 | SetWindowLongPtr(GetActiveWindow(), GWLP_WNDPROC, (LONG_PTR)&DefWindowProc); |
| 314 | |
| 315 | if (CrashLogWindows::current != nullptr) { |
| 316 | CrashLog::AfterCrashLogCleanup(); |
| 317 | ImmediateExitProcess(2); |
| 318 | } |
| 319 | |
| 320 | if (_gamelog.TestEmergency()) { |
| 321 | static const wchar_t _emergency_crash[] = |
| 322 | L"A serious fault condition occurred in the game. The game will shut down.\n" |
| 323 | L"As you loaded an emergency savegame no crash information will be generated.\n"; |
| 324 | MessageBox(nullptr, _emergency_crash, L"Fatal Application Failure", MB_ICONERROR); |
| 325 | ImmediateExitProcess(3); |
| 326 | } |
| 327 | |
| 328 | if (SaveloadCrashWithMissingNewGRFs()) { |
| 329 | static const wchar_t _saveload_crash[] = |
| 330 | L"A serious fault condition occurred in the game. The game will shut down.\n" |
| 331 | L"As you loaded an savegame for which you do not have the required NewGRFs\n" |
| 332 | L"no crash information will be generated.\n"; |
| 333 | MessageBox(nullptr, _saveload_crash, L"Fatal Application Failure", MB_ICONERROR); |
| 334 | ImmediateExitProcess(3); |
| 335 | } |
| 336 | |
| 337 | CrashLogWindows *log = new CrashLogWindows(ep); |
| 338 | CrashLogWindows::current = log; |
| 339 | log->MakeCrashLog(); |
| 340 | |
| 341 | /* Close any possible log files */ |
| 342 | CloseConsoleLogIfActive(); |
| 343 | |
| 344 | if ((VideoDriver::GetInstance() == nullptr || VideoDriver::GetInstance()->HasGUI()) && _safe_esp != nullptr) { |
| 345 | #ifdef _M_AMD64 |
| 346 | ep->ContextRecord->Rip = (DWORD64)ShowCrashlogWindow; |
| 347 | ep->ContextRecord->Rsp = (DWORD64)_safe_esp; |
| 348 | #elif defined(_M_IX86) |
| 349 | ep->ContextRecord->Eip = (DWORD)ShowCrashlogWindow; |
| 350 | ep->ContextRecord->Esp = (DWORD)_safe_esp; |
| 351 | #elif defined(_M_ARM64) |
| 352 | ep->ContextRecord->Pc = (DWORD64)ShowCrashlogWindow; |
| 353 | ep->ContextRecord->Sp = (DWORD64)_safe_esp; |
| 354 | #endif |
| 355 | return EXCEPTION_CONTINUE_EXECUTION; |
| 356 | } |
| 357 | |
| 358 | CrashLog::AfterCrashLogCleanup(); |
| 359 | return EXCEPTION_EXECUTE_HANDLER; |
| 360 | } |
| 361 | |
| 362 | static LONG WINAPI VectoredExceptionHandler(EXCEPTION_POINTERS *ep) |
| 363 | { |
no test coverage detected