legatt 32f4597c4d Base frontend module
- Naming style migrated to camel-case
- P7lib logger sources added
- Vcpkg manifest, CMake presets and build moved to root
- SDL2, Vulkan and RmlUi dependencies added
- Logger LOG macro added
- Logger  configuration
- SDL2 window configuration
- Vulkan configuration
- RmlUi configuration
- SDL event loop
2025-08-08 00:07:32 +03:00

294 lines
8.4 KiB
C

////////////////////////////////////////////////////////////////////////////////
// /
// 2012-2020 (c) Baical /
// /
// This library is free software; you can redistribute it and/or /
// modify it under the terms of the GNU Lesser General Public /
// License as published by the Free Software Foundation; either /
// version 3.0 of the License, or (at your option) any later version. /
// /
// This library is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
// Lesser General Public License for more details. /
// /
// You should have received a copy of the GNU Lesser General Public /
// License along with this library. /
// /
////////////////////////////////////////////////////////////////////////////////
//http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus
#ifndef PSIGNAL_H
#define PSIGNAL_H
#include <new.h>
#include <crtdbg.h>
#include "signal.h"
#include "ISignal.h"
static stChContext g_stContext = {0};
////////////////////////////////////////////////////////////////////////////////
//ChSignalHandler
static void __cdecl ChSignalHandler(int i_iSignal)
{
if (g_stContext.iProcessed)
{
return;
}
g_stContext.iProcessed ++;
const char *l_pText = "unknown signal";
if (SIGABRT == i_iSignal)
{
l_pText = "SIGABRT";
}
else if (SIGFPE == i_iSignal)
{
l_pText = "SIGFPE";
}
else if (SIGILL == i_iSignal)
{
l_pText = "SIGILL";
}
else if (SIGINT == i_iSignal)
{
l_pText = "SIGINT";
}
else if (SIGSEGV == i_iSignal)
{
l_pText = "SIGSEGV";
}
else if (SIGTERM == i_iSignal)
{
l_pText = "SIGTERM";
}
if (g_stContext.pUserHandler)
{
g_stContext.pUserHandler((eCrashCode)(eCrashSignal + i_iSignal), l_pText, g_stContext.pUserContext);
}
exit(1);
}//ChSignalHandler
////////////////////////////////////////////////////////////////////////////////
//ChUnhandledExceptionFilter
static LONG WINAPI ChUnhandledExceptionFilter(__in struct _EXCEPTION_POINTERS *i_pException)
{
if (g_stContext.iProcessed)
{
return EXCEPTION_CONTINUE_SEARCH;
}
if ( (STATUS_ACCESS_VIOLATION == i_pException->ExceptionRecord->ExceptionCode)
|| (EXCEPTION_ARRAY_BOUNDS_EXCEEDED == i_pException->ExceptionRecord->ExceptionCode)
|| (EXCEPTION_DATATYPE_MISALIGNMENT == i_pException->ExceptionRecord->ExceptionCode)
|| (EXCEPTION_FLT_DIVIDE_BY_ZERO == i_pException->ExceptionRecord->ExceptionCode)
|| (EXCEPTION_FLT_STACK_CHECK == i_pException->ExceptionRecord->ExceptionCode)
|| (EXCEPTION_ILLEGAL_INSTRUCTION == i_pException->ExceptionRecord->ExceptionCode)
|| (EXCEPTION_INT_DIVIDE_BY_ZERO == i_pException->ExceptionRecord->ExceptionCode)
|| (EXCEPTION_NONCONTINUABLE_EXCEPTION == i_pException->ExceptionRecord->ExceptionCode)
|| (EXCEPTION_PRIV_INSTRUCTION == i_pException->ExceptionRecord->ExceptionCode)
|| (EXCEPTION_STACK_OVERFLOW == i_pException->ExceptionRecord->ExceptionCode)
//|| ( == i_pException->ExceptionRecord.ExceptionCode)
)
{
g_stContext.iProcessed ++;
if (g_stContext.pUserHandler)
{
g_stContext.pUserHandler(eCrashException, i_pException, g_stContext.pUserContext);
}
exit(1);
}
return EXCEPTION_CONTINUE_SEARCH;
}//ChUnhandledExceptionFilter
////////////////////////////////////////////////////////////////////////////////
//ChPurecallHandler
static void ChPurecallHandler(void)
{
if (g_stContext.iProcessed)
{
return;
}
g_stContext.iProcessed ++;
if (g_stContext.pUserHandler)
{
g_stContext.pUserHandler(eCrashPureCall, "Pure call", g_stContext.pUserContext);
}
exit(1);
}//ChPurecallHandler
////////////////////////////////////////////////////////////////////////////////
//ChMemoryAllocationHandler
static int ChMemoryAllocationHandler(size_t i_szSize)
{
if (g_stContext.iProcessed)
{
return 0;
}
g_stContext.iProcessed ++;
char l_pText[32];
sprintf_s(l_pText, "%lld", (tINT64)i_szSize);
if (g_stContext.pUserHandler)
{
g_stContext.pUserHandler(eCrashMemAlloc, l_pText, g_stContext.pUserContext);
}
exit(1);
return 0;
}//ChMemoryAllocationHandler
////////////////////////////////////////////////////////////////////////////////
//ChInvalidParameterHandler
static void ChInvalidParameterHandler(const wchar_t* i_pExpression,
const wchar_t* i_pFunction,
const wchar_t* i_pFile,
unsigned int i_dwLine,
uintptr_t i_pReserved
)
{
if (g_stContext.iProcessed)
{
return;
}
g_stContext.iProcessed ++;
char l_pText[148];
const wchar_t *l_pFunction = i_pFunction ? i_pFunction : L"Func:Unk";
const wchar_t *l_pFile = i_pFile ? i_pFile : L"File:Unk";
size_t l_szFile = i_pFile ? wcslen(i_pFile) : 0;
size_t l_szFunc = i_pFunction ? wcslen(i_pFunction) : 0;
if ( l_szFile > 64 )
{
l_szFile -= 64;
}
if ( l_szFunc > 64 )
{
l_szFunc -= 64;
}
sprintf_s(l_pText, "{%S}{%S}{%d}", l_pFunction + l_szFunc, l_pFile + l_szFile, (int)i_dwLine);
if (g_stContext.pUserHandler)
{
g_stContext.pUserHandler(eCrashInvalidParameter, l_pText, g_stContext.pUserContext);
}
exit(1);
}//ChInvalidParameterHandler
////////////////////////////////////////////////////////////////////////////////
//ChInstallPrivate
static tBOOL ChInstallPrivate()
{
////////////////////////////////////////////////////////////////////////////
//initialize handlers for all possible cases
signal(SIGABRT, ChSignalHandler);
signal(SIGFPE, ChSignalHandler);
signal(SIGILL, ChSignalHandler);
signal(SIGINT, ChSignalHandler);
signal(SIGSEGV, ChSignalHandler);
signal(SIGTERM, ChSignalHandler);
//SetUnhandledExceptionFilter(ChUnhandledExceptionFilter);
AddVectoredExceptionHandler(1, ChUnhandledExceptionFilter);
_set_purecall_handler(ChPurecallHandler);
_set_new_mode(1);
_set_new_handler(ChMemoryAllocationHandler);
_set_invalid_parameter_handler(ChInvalidParameterHandler);
_CrtSetReportMode(_CRT_ERROR, 0);
_CrtSetReportMode(_CRT_ASSERT, 0);
return TRUE;
}//ChInstallPrivate
////////////////////////////////////////////////////////////////////////////////
//ChInstall
static tBOOL ChInstall()
{
if (g_stContext.iInstalled)
{
return FALSE;
}
////////////////////////////////////////////////////////////////////////////
//initialize parameters
memset(&g_stContext, 0, sizeof(g_stContext));
g_stContext.iInstalled = 1;
g_stContext.iProcessed = 0;
ChInstallPrivate();
return TRUE;
}//ChInstall
////////////////////////////////////////////////////////////////////////////////
//ChSetHandler
static tBOOL ChSetHandler(fnCrashHandler i_fnHandler)
{
if (!g_stContext.iInstalled)
{
return FALSE;
}
g_stContext.pUserHandler = i_fnHandler;
return TRUE;
}//ChSetHandler
////////////////////////////////////////////////////////////////////////////////
//ChSetContext
static tBOOL ChSetContext(void *i_pContext)
{
if (!g_stContext.iInstalled)
{
return FALSE;
}
g_stContext.pUserContext = i_pContext;
return TRUE;
}//ChSetContext
////////////////////////////////////////////////////////////////////////////////
//ChUnInstall
static tBOOL ChUnInstall()
{
return TRUE;
}//ChUnInstall
#endif //PSIGNAL_H