mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 20:42:21 +02:00
Extensive runtime refactor to reduce generated executable sizes
This commit is contained in:
parent
4e750a7e1a
commit
ddd9b1b218
74 changed files with 2514 additions and 717 deletions
|
@ -100,12 +100,14 @@ enum BfpCrashReportKind
|
|||
};
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_InitCrashCatcher(BfpSystemInitFlags flags);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashReportKind(BfpCrashReportKind crashReportKind);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfoFunc(BfpCrashInfoFunc crashInfoFunc);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str); // Can do at any time, or during CrashInfoFunc callbacks
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashRelaunchCmd(const char* str);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown();
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_ShutdownCrashCatcher();
|
||||
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_TickCount();
|
||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpSystem_GetTimeStamp();
|
||||
BFP_EXPORT uint16 BFP_CALLTYPE BfpSystem_EndianSwap16(uint16 val);
|
||||
|
|
|
@ -52,7 +52,6 @@ static SYMGETMODULEBASEPROC gSymGetModuleBase = NULL;
|
|||
static SYMGETSYMFROMADDRPROC gSymGetSymFromAddr = NULL;
|
||||
static SYMGETLINEFROMADDR gSymGetLineFromAddr = NULL;
|
||||
|
||||
|
||||
static bool CreateMiniDump(EXCEPTION_POINTERS* pep, const StringImpl& filePath);
|
||||
|
||||
static bool LoadImageHelp()
|
||||
|
@ -117,47 +116,6 @@ static bool LoadImageHelp()
|
|||
return true;
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
DWORD dwExceptionCode;
|
||||
char *szMessage;
|
||||
} gMsgTable[] = {
|
||||
{ STATUS_SEGMENT_NOTIFICATION, "Segment Notification" },
|
||||
{ STATUS_BREAKPOINT, "Breakpoint" },
|
||||
{ STATUS_SINGLE_STEP, "Single step" },
|
||||
{ STATUS_WAIT_0, "Wait 0" },
|
||||
{ STATUS_ABANDONED_WAIT_0, "Abandoned Wait 0" },
|
||||
{ STATUS_USER_APC, "User APC" },
|
||||
{ STATUS_TIMEOUT, "Timeout" },
|
||||
{ STATUS_PENDING, "Pending" },
|
||||
{ STATUS_GUARD_PAGE_VIOLATION, "Guard Page Violation" },
|
||||
{ STATUS_DATATYPE_MISALIGNMENT, "Data Type Misalignment" },
|
||||
{ STATUS_ACCESS_VIOLATION, "Access Violation" },
|
||||
{ STATUS_IN_PAGE_ERROR, "In Page Error" },
|
||||
{ STATUS_NO_MEMORY, "No Memory" },
|
||||
{ STATUS_ILLEGAL_INSTRUCTION, "Illegal Instruction" },
|
||||
{ STATUS_NONCONTINUABLE_EXCEPTION, "Noncontinuable Exception" },
|
||||
{ STATUS_INVALID_DISPOSITION, "Invalid Disposition" },
|
||||
{ STATUS_ARRAY_BOUNDS_EXCEEDED, "Array Bounds Exceeded" },
|
||||
{ STATUS_FLOAT_DENORMAL_OPERAND, "Float Denormal Operand" },
|
||||
{ STATUS_FLOAT_DIVIDE_BY_ZERO, "Divide by Zero" },
|
||||
{ STATUS_FLOAT_INEXACT_RESULT, "Float Inexact Result" },
|
||||
{ STATUS_FLOAT_INVALID_OPERATION, "Float Invalid Operation" },
|
||||
{ STATUS_FLOAT_OVERFLOW, "Float Overflow" },
|
||||
{ STATUS_FLOAT_STACK_CHECK, "Float Stack Check" },
|
||||
{ STATUS_FLOAT_UNDERFLOW, "Float Underflow" },
|
||||
{ STATUS_INTEGER_DIVIDE_BY_ZERO, "Integer Divide by Zero" },
|
||||
{ STATUS_INTEGER_OVERFLOW, "Integer Overflow" },
|
||||
{ STATUS_PRIVILEGED_INSTRUCTION, "Privileged Instruction" },
|
||||
{ STATUS_STACK_OVERFLOW, "Stack Overflow" },
|
||||
{ STATUS_CONTROL_C_EXIT, "Ctrl+C Exit" },
|
||||
{ 0xFFFFFFFF, "" }
|
||||
};
|
||||
|
||||
static HFONT gDialogFont;
|
||||
static HFONT gBoldFont;
|
||||
static String gErrorTitle;
|
||||
static String gErrorText;
|
||||
static HWND gDebugButtonWindow = NULL;
|
||||
static HWND gYesButtonWindow = NULL;
|
||||
static HWND gNoButtonWindow = NULL;
|
||||
|
@ -265,19 +223,19 @@ static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& erro
|
|||
gUseDefaultFonts = aVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT;
|
||||
|
||||
int aHeight = -MulDiv(8, 96, 72);
|
||||
gDialogFont = ::CreateFontA(aHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
|
||||
HFONT gDialogFont = ::CreateFontA(aHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
|
||||
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
|
||||
|
||||
aHeight = -MulDiv(10, 96, 72);
|
||||
gBoldFont = ::CreateFontA(aHeight, 0, 0, 0, FW_BOLD, FALSE, FALSE,
|
||||
HFONT gBoldFont = ::CreateFontA(aHeight, 0, 0, 0, FW_BOLD, FALSE, FALSE,
|
||||
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
|
||||
|
||||
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
|
||||
|
||||
gErrorTitle = errorTitle;
|
||||
gErrorText = errorText;
|
||||
String gErrorTitle = errorTitle;
|
||||
String gErrorText = errorText;
|
||||
|
||||
WNDCLASSW wc;
|
||||
wc.style = 0;
|
||||
|
@ -935,6 +893,44 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
|
|||
|
||||
///////////////////////////
|
||||
// first name the exception
|
||||
|
||||
struct
|
||||
{
|
||||
DWORD dwExceptionCode;
|
||||
char* szMessage;
|
||||
} gMsgTable[] = {
|
||||
{ STATUS_SEGMENT_NOTIFICATION, "Segment Notification" },
|
||||
{ STATUS_BREAKPOINT, "Breakpoint" },
|
||||
{ STATUS_SINGLE_STEP, "Single step" },
|
||||
{ STATUS_WAIT_0, "Wait 0" },
|
||||
{ STATUS_ABANDONED_WAIT_0, "Abandoned Wait 0" },
|
||||
{ STATUS_USER_APC, "User APC" },
|
||||
{ STATUS_TIMEOUT, "Timeout" },
|
||||
{ STATUS_PENDING, "Pending" },
|
||||
{ STATUS_GUARD_PAGE_VIOLATION, "Guard Page Violation" },
|
||||
{ STATUS_DATATYPE_MISALIGNMENT, "Data Type Misalignment" },
|
||||
{ STATUS_ACCESS_VIOLATION, "Access Violation" },
|
||||
{ STATUS_IN_PAGE_ERROR, "In Page Error" },
|
||||
{ STATUS_NO_MEMORY, "No Memory" },
|
||||
{ STATUS_ILLEGAL_INSTRUCTION, "Illegal Instruction" },
|
||||
{ STATUS_NONCONTINUABLE_EXCEPTION, "Noncontinuable Exception" },
|
||||
{ STATUS_INVALID_DISPOSITION, "Invalid Disposition" },
|
||||
{ STATUS_ARRAY_BOUNDS_EXCEEDED, "Array Bounds Exceeded" },
|
||||
{ STATUS_FLOAT_DENORMAL_OPERAND, "Float Denormal Operand" },
|
||||
{ STATUS_FLOAT_DIVIDE_BY_ZERO, "Divide by Zero" },
|
||||
{ STATUS_FLOAT_INEXACT_RESULT, "Float Inexact Result" },
|
||||
{ STATUS_FLOAT_INVALID_OPERATION, "Float Invalid Operation" },
|
||||
{ STATUS_FLOAT_OVERFLOW, "Float Overflow" },
|
||||
{ STATUS_FLOAT_STACK_CHECK, "Float Stack Check" },
|
||||
{ STATUS_FLOAT_UNDERFLOW, "Float Underflow" },
|
||||
{ STATUS_INTEGER_DIVIDE_BY_ZERO, "Integer Divide by Zero" },
|
||||
{ STATUS_INTEGER_OVERFLOW, "Integer Overflow" },
|
||||
{ STATUS_PRIVILEGED_INSTRUCTION, "Privileged Instruction" },
|
||||
{ STATUS_STACK_OVERFLOW, "Stack Overflow" },
|
||||
{ STATUS_CONTROL_C_EXIT, "Ctrl+C Exit" },
|
||||
{ 0xFFFFFFFF, "" }
|
||||
};
|
||||
|
||||
char *szName = NULL;
|
||||
for (int i = 0; gMsgTable[i].dwExceptionCode != 0xFFFFFFFF; i++)
|
||||
{
|
||||
|
|
|
@ -39,9 +39,14 @@
|
|||
|
||||
USING_NS_BF;
|
||||
|
||||
static void Crash_Error(const char* msg);
|
||||
|
||||
typedef void(*BfpCrashErrorFunc)(const char* str);
|
||||
|
||||
static bool gTimerInitialized = false;
|
||||
static int gTimerDivisor = 0;
|
||||
CritSect gBfpCritSect;
|
||||
BfpCrashErrorFunc gCrashErrorFunc = Crash_Error;
|
||||
|
||||
struct WindowsSharedInfo
|
||||
{
|
||||
|
@ -415,8 +420,9 @@ void Beefy::BFFatalError(const StringImpl& message, const StringImpl& file, int
|
|||
gBFApp->mSysDialogCnt++;
|
||||
#endif
|
||||
|
||||
String failMsg = StrFormat("%s in %s:%d", message.c_str(), file.c_str(), line);
|
||||
BfpSystem_FatalError(failMsg.c_str(), "FATAL ERROR");
|
||||
char* failMsg = new char[message.length() + file.length() + 64];
|
||||
sprintf(failMsg, "%s in %s:%d", message.c_str(), file.c_str(), line);
|
||||
BfpSystem_FatalError(failMsg, "FATAL ERROR");
|
||||
|
||||
#ifndef BF_NO_BFAPP
|
||||
if (gBFApp != NULL)
|
||||
|
@ -906,6 +912,7 @@ static void __cdecl AbortHandler(int)
|
|||
static int64 gCPUFreq = -1;
|
||||
static int64 gStartCPUTick = -1;
|
||||
static int64 gStartQPF = -1;
|
||||
static void(*sOldSIGABRTHandler)(int signal) = nullptr;
|
||||
|
||||
static void InitCPUFreq()
|
||||
{
|
||||
|
@ -918,10 +925,31 @@ static void InitCPUFreq()
|
|||
}
|
||||
}
|
||||
|
||||
static void(*sOldSIGABRTHandler)(int signal) = nullptr;
|
||||
static void Crash_Error(const char* msg)
|
||||
{
|
||||
HMODULE hMod = GetModuleHandleA(NULL);
|
||||
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
|
||||
PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((uint8*)hMod + pDosHdr->e_lfanew);
|
||||
bool isCLI = pNtHdr->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
|
||||
if (isCLI)
|
||||
fprintf(stderr, "**** FATAL APPLICATION ERROR ****\n%s\n", msg);
|
||||
else
|
||||
::MessageBoxA(NULL, msg, "FATAL ERROR", MB_ICONSTOP);
|
||||
_set_purecall_handler(nullptr);
|
||||
_set_invalid_parameter_handler(nullptr);
|
||||
signal(SIGABRT, sOldSIGABRTHandler);
|
||||
abort();
|
||||
}
|
||||
|
||||
static void Crash_Error_CrashHandler(const char* msg)
|
||||
{
|
||||
CrashCatcher::Get()->Crash(msg);
|
||||
}
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags)
|
||||
{
|
||||
gCrashErrorFunc = Crash_Error;
|
||||
InitCPUFreq();
|
||||
|
||||
::_set_error_mode(_OUT_TO_STDERR);
|
||||
|
@ -935,7 +963,9 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flag
|
|||
|
||||
if (version != BFP_VERSION)
|
||||
{
|
||||
BfpSystem_FatalError(StrFormat("Bfp build version '%d' does not match requested version '%d'", BFP_VERSION, version).c_str(), "BFP FATAL ERROR");
|
||||
char msg[1024];
|
||||
sprintf(msg, "Bfp build version '%d' does not match requested version '%d'", BFP_VERSION, version);
|
||||
BfpSystem_FatalError(msg, "BFP FATAL ERROR");
|
||||
}
|
||||
|
||||
if ((flags & BfpSystemInitFlag_InstallCrashCatcher) != 0)
|
||||
|
@ -953,13 +983,17 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flag
|
|||
sOldSIGABRTHandler = signal(SIGABRT, &AbortHandler);
|
||||
if (sOldSIGABRTHandler == SIG_ERR)
|
||||
sOldSIGABRTHandler = nullptr;
|
||||
|
||||
CrashCatcher::Get()->Init();
|
||||
if ((flags & BfpSystemInitFlag_SilentCrash) != 0)
|
||||
CrashCatcher::Get()->SetCrashReportKind(BfpCrashReportKind_None);
|
||||
}
|
||||
}
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_InitCrashCatcher(BfpSystemInitFlags flags)
|
||||
{
|
||||
CrashCatcher::Get()->Init();
|
||||
if ((flags & BfpSystemInitFlag_SilentCrash) != 0)
|
||||
CrashCatcher::Get()->SetCrashReportKind(BfpCrashReportKind_None);
|
||||
gCrashErrorFunc = Crash_Error_CrashHandler;
|
||||
}
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv)
|
||||
{
|
||||
// This isn't required on Windows, but it is on Linux
|
||||
|
@ -993,7 +1027,10 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown()
|
|||
delete gManagerTail;
|
||||
gManagerTail = next;
|
||||
}
|
||||
}
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_ShutdownCrashCatcher()
|
||||
{
|
||||
if (CrashCatcher::Shutdown())
|
||||
{
|
||||
_set_purecall_handler(nullptr);
|
||||
|
@ -1092,9 +1129,17 @@ BFP_EXPORT uint64 BFP_CALLTYPE BfpSystem_InterlockedCompareExchange64(uint64* pt
|
|||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_FatalError(const char* error, const char* title)
|
||||
{
|
||||
if (title != NULL)
|
||||
CrashCatcher::Get()->Crash(String(title) + "\n" + String(error));
|
||||
else
|
||||
CrashCatcher::Get()->Crash(error);
|
||||
{
|
||||
int errorLen = (int)strlen(error);
|
||||
int titleLen = (int)strlen(title);
|
||||
char* str = new char[errorLen + 1 + titleLen + 1];
|
||||
strcpy(str, title);
|
||||
strcat(str, "\n");
|
||||
strcat(str, error);
|
||||
gCrashErrorFunc(str);
|
||||
}
|
||||
else
|
||||
gCrashErrorFunc(error);
|
||||
}
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetCommandLine(char* outStr, int* inOutStrSize, BfpSystemResult* outResult)
|
||||
|
@ -2245,9 +2290,12 @@ static LOCATEXSTATEFEATURE pfnLocateXStateFeature = NULL;
|
|||
typedef BOOL(WINAPI* SETXSTATEFEATURESMASK)(PCONTEXT Context, DWORD64 FeatureMask);
|
||||
static SETXSTATEFEATURESMASK pfnSetXStateFeaturesMask = NULL;
|
||||
|
||||
static uint8 ContextBuffer[4096];
|
||||
static uint8* ContextBuffer;
|
||||
static CONTEXT* CaptureRegistersEx(HANDLE hThread, intptr*& curPtr)
|
||||
{
|
||||
if (ContextBuffer == NULL)
|
||||
ContextBuffer = new uint8[4096];
|
||||
|
||||
PCONTEXT Context;
|
||||
DWORD ContextSize;
|
||||
DWORD64 FeatureMask;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue