mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 11:39:42 +00:00
Attempt to catch freezes on Windows
This commit is contained in:
parent
46564f08ad
commit
c746a8abb7
4 changed files with 63 additions and 1 deletions
|
@ -144,6 +144,7 @@ namespace Crash
|
|||
mShm->mEvent = CrashSHM::Event::Startup;
|
||||
mShm->mStartup.mShmMutex = duplicateHandle(mShmMutex);
|
||||
mShm->mStartup.mAppProcessHandle = duplicateHandle(GetCurrentProcess());
|
||||
mShm->mStartup.mAppMainThreadId = GetThreadId(GetCurrentThread());
|
||||
mShm->mStartup.mSignalApp = duplicateHandle(mSignalAppEvent);
|
||||
mShm->mStartup.mSignalMonitor = duplicateHandle(mSignalMonitorEvent);
|
||||
|
||||
|
@ -196,7 +197,7 @@ namespace Crash
|
|||
// must remain until monitor has finished
|
||||
waitMonitor();
|
||||
|
||||
std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + std::string(mShm->mStartup.mLogFilePath) + "'.\n Please report this to https://gitlab.com/OpenMW/openmw/issues !";
|
||||
std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + std::string(mShm->mStartup.mLogFilePath) + "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !";
|
||||
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#include <SDL_messagebox.h>
|
||||
|
||||
#include "windows_crashcatcher.hpp"
|
||||
#include "windows_crashmonitor.hpp"
|
||||
#include "windows_crashshm.hpp"
|
||||
|
@ -28,6 +30,7 @@ namespace Crash
|
|||
|
||||
mShmMutex = mShm->mStartup.mShmMutex;
|
||||
mAppProcessHandle = mShm->mStartup.mAppProcessHandle;
|
||||
mAppMainThreadId = mShm->mStartup.mAppMainThreadId;
|
||||
mSignalAppEvent = mShm->mStartup.mSignalApp;
|
||||
mSignalMonitorEvent = mShm->mStartup.mSignalMonitor;
|
||||
}
|
||||
|
@ -80,6 +83,44 @@ namespace Crash
|
|||
return code == STILL_ACTIVE;
|
||||
}
|
||||
|
||||
bool CrashMonitor::isAppFrozen()
|
||||
{
|
||||
if (!mAppWindowHandle)
|
||||
{
|
||||
EnumWindows([](HWND handle, LPARAM param) -> BOOL {
|
||||
CrashMonitor& crashMonitor = *(CrashMonitor*)param;
|
||||
DWORD processId;
|
||||
if (GetWindowThreadProcessId(handle, &processId) == crashMonitor.mAppMainThreadId && processId == GetProcessId(crashMonitor.mAppProcessHandle))
|
||||
{
|
||||
if (GetWindow(handle, GW_OWNER) == 0)
|
||||
{
|
||||
crashMonitor.mAppWindowHandle = handle;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, (LPARAM)this);
|
||||
if (mAppWindowHandle)
|
||||
{
|
||||
// TODO: use https://devblogs.microsoft.com/oldnewthing/20111026-00/?p=9263 to monitor for the window being destroyed
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (IsHungAppWindow)
|
||||
return IsHungAppWindow(mAppWindowHandle);
|
||||
else
|
||||
{
|
||||
BOOL debuggerPresent;
|
||||
|
||||
if (CheckRemoteDebuggerPresent(mAppProcessHandle, &debuggerPresent) && debuggerPresent)
|
||||
return false;
|
||||
if (SendMessageTimeoutA(mAppWindowHandle, WM_NULL, 0, 0, 0, 5000, nullptr) == 0)
|
||||
return GetLastError() == ERROR_TIMEOUT;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CrashMonitor::run()
|
||||
{
|
||||
try
|
||||
|
@ -88,8 +129,16 @@ namespace Crash
|
|||
signalApp();
|
||||
|
||||
bool running = true;
|
||||
bool frozen = false;
|
||||
while (isAppAlive() && running)
|
||||
{
|
||||
if (isAppFrozen())
|
||||
{
|
||||
frozen = true;
|
||||
handleCrash();
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
if (waitApp())
|
||||
{
|
||||
shmLock();
|
||||
|
@ -113,6 +162,13 @@ namespace Crash
|
|||
}
|
||||
}
|
||||
|
||||
if (frozen)
|
||||
{
|
||||
TerminateProcess(mAppProcessHandle, -1);
|
||||
std::string message = "OpenMW appears to have frozen.\nCrash log saved to '" + std::string(mShm->mStartup.mLogFilePath) + "'.\nPlease report this to https://gitlab.com/OpenMW/openmw/issues !";
|
||||
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr);
|
||||
}
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
|
|
@ -21,6 +21,8 @@ public:
|
|||
private:
|
||||
|
||||
HANDLE mAppProcessHandle = nullptr;
|
||||
DWORD mAppMainThreadId = 0;
|
||||
HWND mAppWindowHandle = nullptr;
|
||||
|
||||
// triggered when the monitor process wants to wake the parent process (received via SHM)
|
||||
HANDLE mSignalAppEvent = nullptr;
|
||||
|
@ -37,6 +39,8 @@ private:
|
|||
|
||||
bool isAppAlive() const;
|
||||
|
||||
bool isAppFrozen();
|
||||
|
||||
void shmLock();
|
||||
|
||||
void shmUnlock();
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Crash
|
|||
struct Startup
|
||||
{
|
||||
HANDLE mAppProcessHandle;
|
||||
DWORD mAppMainThreadId;
|
||||
HANDLE mSignalApp;
|
||||
HANDLE mSignalMonitor;
|
||||
HANDLE mShmMutex;
|
||||
|
|
Loading…
Reference in a new issue