Merge pull request #763 from ergo720/crash-fix

Crash detection implementation
This commit is contained in:
PatrickvL 2017-10-10 22:17:58 +02:00 committed by GitHub
commit 5d1d8f109c
6 changed files with 84 additions and 0 deletions

View File

@ -137,6 +137,7 @@ void EmuShared::Cleanup()
EmuShared::EmuShared() EmuShared::EmuShared()
{ {
Load(); Load();
m_bMultiXbe = false;
} }
// ****************************************************************** // ******************************************************************

View File

@ -406,6 +406,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
{ {
case WM_CREATE: case WM_CREATE:
{ {
CreateThread(NULL, NULL, CrashMonitorWrapper, (void*)this, NULL, NULL); // create the crash monitoring thread
if (m_hwndChild == NULL) { if (m_hwndChild == NULL) {
float fps = 0; float fps = 0;
float mspf = 0; float mspf = 0;
@ -1942,3 +1943,52 @@ void WndMain::StopEmulation()
UpdateCaption(); UpdateCaption();
RefreshMenus(); RefreshMenus();
} }
// wrapper function to call CrashMonitor
DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid)
{
static_cast<WndMain*>(lpVoid)->CrashMonitor();
return 0;
}
// monitor for crashes
void WndMain::CrashMonitor()
{
bool bMultiXbe;
HANDLE hCrashMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "CrashMutex");
DWORD state = WaitForSingleObject(hCrashMutex, INFINITE);
g_EmuShared->GetMultiXbeFlag(&bMultiXbe);
if (state == WAIT_OBJECT_0) // StopEmulation
{
CloseHandle(hCrashMutex);
return;
}
if (state == WAIT_ABANDONED && !bMultiXbe) // that's a crash
{
CloseHandle(hCrashMutex);
if (m_bIsStarted) // that's a hard crash, Dr Watson is invoked
{
KillTimer(m_hwnd, TIMERID_FPS);
//KillTimer(m_hwnd, 2); for the LED
//DrawDefaultLedBitmap(hwnd); for the LED
m_hwndChild = NULL;
m_bIsStarted = false;
UpdateCaption();
RefreshMenus();
}
return;
}
// multi-xbe
// destroy this thread and start a new one
CloseHandle(hCrashMutex);
bMultiXbe = false;
g_EmuShared->SetMultiXbeFlag(&bMultiXbe);
return;
}

View File

@ -121,6 +121,16 @@ class WndMain : public Wnd
// ****************************************************************** // ******************************************************************
void UpdateCaption(); void UpdateCaption();
// ******************************************************************
// * crash monitoring wrapper function
// ******************************************************************
static DWORD WINAPI CrashMonitorWrapper(LPVOID lpVoid);
// ******************************************************************
// * crash monitoring function thread
// ******************************************************************
void CrashMonitor();
// ****************************************************************** // ******************************************************************
// * drawing information // * drawing information
// ****************************************************************** // ******************************************************************

View File

@ -1171,6 +1171,17 @@ static DWORD WINAPI EmuRenderWindow(LPVOID lpVoid)
RegisterClassEx(&wc); RegisterClassEx(&wc);
} }
bool bMultiXbe;
g_EmuShared->GetMultiXbeFlag(&bMultiXbe);
// precaution for multi-xbe titles in the case CrashMonitor has still not destoyed the previous mutex
while (bMultiXbe)
{
g_EmuShared->GetMultiXbeFlag(&bMultiXbe);
}
HANDLE hCrashMutex = CreateMutex(NULL, TRUE, "CrashMutex");
// create the window // create the window
{ {
DWORD dwStyle = (g_XBVideo.GetFullscreen() || (CxbxKrnl_hEmuParent == 0))? WS_OVERLAPPEDWINDOW : WS_CHILD; DWORD dwStyle = (g_XBVideo.GetFullscreen() || (CxbxKrnl_hEmuParent == 0))? WS_OVERLAPPEDWINDOW : WS_CHILD;
@ -1262,6 +1273,8 @@ static DWORD WINAPI EmuRenderWindow(LPVOID lpVoid)
delete dbgConsole; delete dbgConsole;
if (hCrashMutex != NULL) { ReleaseMutex(hCrashMutex); }
CxbxKrnlCleanup(NULL); CxbxKrnlCleanup(NULL);
} }

View File

@ -483,6 +483,9 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur
// Relaunch Cxbx, to load another Xbe // Relaunch Cxbx, to load another Xbe
{ {
bool bMultiXbe = true;
g_EmuShared->SetMultiXbeFlag(&bMultiXbe);
char szArgsBuffer[4096]; char szArgsBuffer[4096];
snprintf(szArgsBuffer, 4096, "/load \"%s\" %u %d \"%s\"", XbePath.c_str(), CxbxKrnl_hEmuParent, CxbxKrnl_DebugMode, CxbxKrnl_DebugFileName); snprintf(szArgsBuffer, 4096, "/load \"%s\" %u %d \"%s\"", XbePath.c_str(), CxbxKrnl_hEmuParent, CxbxKrnl_DebugMode, CxbxKrnl_DebugFileName);

View File

@ -116,6 +116,12 @@ class EmuShared : public Mutex
void GetCurrentFPS(float *value) { Lock(); *value = m_FPS; Unlock(); } void GetCurrentFPS(float *value) { Lock(); *value = m_FPS; Unlock(); }
void SetCurrentFPS(float *value) { Lock(); m_FPS = *value; Unlock(); } void SetCurrentFPS(float *value) { Lock(); m_FPS = *value; Unlock(); }
// ******************************************************************
// * MultiXbe flag Accessors
// ******************************************************************
void GetMultiXbeFlag(bool *value) { Lock(); *value = m_bMultiXbe; Unlock(); }
void SetMultiXbeFlag(bool *value) { Lock(); m_bMultiXbe = *value; Unlock(); }
private: private:
// ****************************************************************** // ******************************************************************
@ -135,6 +141,7 @@ class EmuShared : public Mutex
int m_XInputEnabled; int m_XInputEnabled;
float m_MSpF; float m_MSpF;
float m_FPS; float m_FPS;
bool m_bMultiXbe;
}; };
// ****************************************************************** // ******************************************************************