diff --git a/BeefySysLib/platform/win/CrashCatcher.cpp b/BeefySysLib/platform/win/CrashCatcher.cpp index 0177eb57..0b374104 100644 --- a/BeefySysLib/platform/win/CrashCatcher.cpp +++ b/BeefySysLib/platform/win/CrashCatcher.cpp @@ -1178,6 +1178,7 @@ struct CrashCatchMemory public: CrashCatcher* mBpManager; int mABIVersion; + int mCounter; }; #define CRASHCATCH_ABI_VERSION 1 @@ -1202,8 +1203,18 @@ CrashCatcher* CrashCatcher::Get() CrashCatchMemory* sharedMem = (CrashCatchMemory*)MapViewOfFile(fileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(CrashCatchMemory)); if (sharedMem != NULL) { - if (sharedMem->mABIVersion == CRASHCATCH_ABI_VERSION) - sCrashCatcher = sharedMem->mBpManager; + if (sharedMem->mABIVersion == 0 && sharedMem->mBpManager == NULL && sharedMem->mCounter == 0) + { + sCrashCatcher = new CrashCatcher(); + sharedMem->mBpManager = sCrashCatcher; + sharedMem->mABIVersion = CRASHCATCH_ABI_VERSION; + sharedMem->mCounter = 1; + } + else if (sharedMem->mABIVersion == CRASHCATCH_ABI_VERSION) + { + sharedMem->mCounter++; + sCrashCatcher = sharedMem->mBpManager; + } ::UnmapViewOfFile(sharedMem); } ::CloseHandle(fileMapping); @@ -1219,6 +1230,7 @@ CrashCatcher* CrashCatcher::Get() sCrashCatcher = new CrashCatcher(); sharedMem->mBpManager = sCrashCatcher; sharedMem->mABIVersion = CRASHCATCH_ABI_VERSION; + sharedMem->mCounter = 1; ::UnmapViewOfFile(sharedMem); ::ReleaseMutex(mutex); } @@ -1234,4 +1246,50 @@ CrashCatcher* CrashCatcher::Get() if (sCrashCatcher == NULL) sCrashCatcher = new CrashCatcher(); return sCrashCatcher; +} + +int CrashCatcher::Shutdown() +{ + if (sCrashCatcher == NULL) + return 0; + + char mutexName[128]; + sprintf(mutexName, "BfCrashCatch_mutex_%d", GetCurrentProcessId()); + char memName[128]; + sprintf(memName, "BfCrashCatch_mem_%d", GetCurrentProcessId()); + + auto mutex = ::CreateMutexA(NULL, TRUE, mutexName); + if (mutex != NULL) + { + HANDLE fileMapping = ::OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, memName); + if (fileMapping != NULL) + { + CrashCatchMemory* sharedMem = (CrashCatchMemory*)MapViewOfFile(fileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(CrashCatchMemory)); + if (sharedMem != NULL) + { + if (sharedMem->mABIVersion == CRASHCATCH_ABI_VERSION && sharedMem->mBpManager != NULL && sharedMem->mCounter > 0) + { + sharedMem->mCounter--; + + if (sharedMem->mCounter <= 0) + { + delete sharedMem->mBpManager; + sharedMem->mBpManager = NULL; + sharedMem->mCounter = 0; + sharedMem->mABIVersion = 0; + } + } + + ::UnmapViewOfFile(sharedMem); + } + + ::CloseHandle(fileMapping); + } + + ::CloseHandle(mutex); + } + + sCrashCatcher = NULL; + + return 1; } \ No newline at end of file diff --git a/BeefySysLib/platform/win/CrashCatcher.h b/BeefySysLib/platform/win/CrashCatcher.h index 10e58415..7d8209b4 100644 --- a/BeefySysLib/platform/win/CrashCatcher.h +++ b/BeefySysLib/platform/win/CrashCatcher.h @@ -35,6 +35,7 @@ public: virtual void SetRelaunchCmd(const StringImpl& relaunchCmd); static CrashCatcher* Get(); + static int Shutdown(); }; NS_BF_END diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp index 0e71a0e8..4893040e 100644 --- a/BeefySysLib/platform/win/Platform.cpp +++ b/BeefySysLib/platform/win/Platform.cpp @@ -917,6 +917,8 @@ static void InitCPUFreq() } } +static void(*sOldSIGABRTHandler)(int signal) = nullptr; + BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags) { InitCPUFreq(); @@ -947,7 +949,9 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flag // default, but explicitly setting it seems like a good idea. _set_abort_behavior(_CALL_REPORTFAULT, _CALL_REPORTFAULT); // Then we install our abort handler. - signal(SIGABRT, &AbortHandler); + sOldSIGABRTHandler = signal(SIGABRT, &AbortHandler); + if (sOldSIGABRTHandler == SIG_ERR) + sOldSIGABRTHandler = nullptr; CrashCatcher::Get()->Init(); if ((flags & BfpSystemInitFlag_SilentCrash) != 0) @@ -988,6 +992,13 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown() delete gManagerTail; gManagerTail = next; } + + if (CrashCatcher::Shutdown()) + { + _set_purecall_handler(nullptr); + _set_invalid_parameter_handler(nullptr); + signal(SIGABRT, sOldSIGABRTHandler); + } } BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_TickCount()