1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Improve robustness of CrashCatcher registration

This commit is contained in:
Hunter Bridges 2022-02-15 22:11:56 -08:00
parent ff5dee3583
commit 795c70af2f
3 changed files with 73 additions and 3 deletions

View file

@ -1178,6 +1178,7 @@ struct CrashCatchMemory
public: public:
CrashCatcher* mBpManager; CrashCatcher* mBpManager;
int mABIVersion; int mABIVersion;
int mCounter;
}; };
#define CRASHCATCH_ABI_VERSION 1 #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)); CrashCatchMemory* sharedMem = (CrashCatchMemory*)MapViewOfFile(fileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(CrashCatchMemory));
if (sharedMem != NULL) if (sharedMem != NULL)
{ {
if (sharedMem->mABIVersion == CRASHCATCH_ABI_VERSION) 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; sCrashCatcher = sharedMem->mBpManager;
}
::UnmapViewOfFile(sharedMem); ::UnmapViewOfFile(sharedMem);
} }
::CloseHandle(fileMapping); ::CloseHandle(fileMapping);
@ -1219,6 +1230,7 @@ CrashCatcher* CrashCatcher::Get()
sCrashCatcher = new CrashCatcher(); sCrashCatcher = new CrashCatcher();
sharedMem->mBpManager = sCrashCatcher; sharedMem->mBpManager = sCrashCatcher;
sharedMem->mABIVersion = CRASHCATCH_ABI_VERSION; sharedMem->mABIVersion = CRASHCATCH_ABI_VERSION;
sharedMem->mCounter = 1;
::UnmapViewOfFile(sharedMem); ::UnmapViewOfFile(sharedMem);
::ReleaseMutex(mutex); ::ReleaseMutex(mutex);
} }
@ -1235,3 +1247,49 @@ CrashCatcher* CrashCatcher::Get()
sCrashCatcher = new CrashCatcher(); sCrashCatcher = new CrashCatcher();
return sCrashCatcher; 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;
}

View file

@ -35,6 +35,7 @@ public:
virtual void SetRelaunchCmd(const StringImpl& relaunchCmd); virtual void SetRelaunchCmd(const StringImpl& relaunchCmd);
static CrashCatcher* Get(); static CrashCatcher* Get();
static int Shutdown();
}; };
NS_BF_END NS_BF_END

View file

@ -917,6 +917,8 @@ static void InitCPUFreq()
} }
} }
static void(*sOldSIGABRTHandler)(int signal) = nullptr;
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags) BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags)
{ {
InitCPUFreq(); 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. // default, but explicitly setting it seems like a good idea.
_set_abort_behavior(_CALL_REPORTFAULT, _CALL_REPORTFAULT); _set_abort_behavior(_CALL_REPORTFAULT, _CALL_REPORTFAULT);
// Then we install our abort handler. // Then we install our abort handler.
signal(SIGABRT, &AbortHandler); sOldSIGABRTHandler = signal(SIGABRT, &AbortHandler);
if (sOldSIGABRTHandler == SIG_ERR)
sOldSIGABRTHandler = nullptr;
CrashCatcher::Get()->Init(); CrashCatcher::Get()->Init();
if ((flags & BfpSystemInitFlag_SilentCrash) != 0) if ((flags & BfpSystemInitFlag_SilentCrash) != 0)
@ -988,6 +992,13 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown()
delete gManagerTail; delete gManagerTail;
gManagerTail = next; gManagerTail = next;
} }
if (CrashCatcher::Shutdown())
{
_set_purecall_handler(nullptr);
_set_invalid_parameter_handler(nullptr);
signal(SIGABRT, sOldSIGABRTHandler);
}
} }
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_TickCount() BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_TickCount()