mirror of
https://github.com/bkaradzic/bx.git
synced 2026-02-17 20:52:37 +01:00
Added Windows SEH.
This commit is contained in:
133
src/debug.cpp
133
src/debug.cpp
@@ -24,14 +24,41 @@
|
|||||||
# include <cxxabi.h> // abi::__cxa_demangle
|
# include <cxxabi.h> // abi::__cxa_demangle
|
||||||
#endif // BX_CONFIG_CALLSTACK_*
|
#endif // BX_CONFIG_CALLSTACK_*
|
||||||
|
|
||||||
#ifndef BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
|
#ifndef BX_CONFIG_EXCEPTION_HANDLING_USE_WINDOWS_SEH
|
||||||
# define BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS 0 \
|
# define BX_CONFIG_EXCEPTION_HANDLING_USE_WINDOWS_SEH BX_PLATFORM_WINDOWS
|
||||||
| (BX_PLATFORM_LINUX && !BX_CRT_NONE)
|
#endif // BX_CONFIG_EXCEPTION_HANDLING_USE_WINDOWS_SEH
|
||||||
#endif // BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
|
|
||||||
|
|
||||||
#if BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
|
#ifndef BX_CONFIG_EXCEPTION_HANDLING_USE_POSIX_SIGNALS
|
||||||
|
# define BX_CONFIG_EXCEPTION_HANDLING_USE_POSIX_SIGNALS 0 \
|
||||||
|
| (BX_PLATFORM_LINUX && !BX_CRT_NONE)
|
||||||
|
#endif // BX_CONFIG_EXCEPTION_HANDLING_USE_POSIX_SIGNALS
|
||||||
|
|
||||||
|
#if BX_CONFIG_EXCEPTION_HANDLING_USE_POSIX_SIGNALS
|
||||||
# include <signal.h>
|
# include <signal.h>
|
||||||
#endif // BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
|
#elif BX_CONFIG_EXCEPTION_HANDLING_USE_WINDOWS_SEH
|
||||||
|
|
||||||
|
struct ExceptionRecord
|
||||||
|
{
|
||||||
|
uint32_t exceptionCode;
|
||||||
|
uint32_t exceptionFlags;
|
||||||
|
|
||||||
|
ExceptionRecord* exceptionRecord;
|
||||||
|
|
||||||
|
uintptr_t exceptionAddress;
|
||||||
|
uint32_t numberParameters;
|
||||||
|
uintptr_t exceptionInformation[15];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExceptionPointers
|
||||||
|
{
|
||||||
|
ExceptionRecord* exceptionRecord;
|
||||||
|
void* contextRecord;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint32_t (__stdcall* TopLevelExceptionFilterFn)(ExceptionPointers* _exceptionInfo);
|
||||||
|
|
||||||
|
extern "C" __declspec(dllimport) TopLevelExceptionFilterFn __stdcall SetUnhandledExceptionFilter(TopLevelExceptionFilterFn _topLevelExceptionFilter);
|
||||||
|
#endif // BX_CONFIG_EXCEPTION_HANDLING_*
|
||||||
|
|
||||||
#if BX_CRT_NONE
|
#if BX_CRT_NONE
|
||||||
# include <bx/crt0.h>
|
# include <bx/crt0.h>
|
||||||
@@ -376,14 +403,14 @@ namespace bx
|
|||||||
writeCallstack(getDebugOut(), stack, num, ErrorIgnore{});
|
writeCallstack(getDebugOut(), stack, num, ErrorIgnore{});
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
|
#if BX_CONFIG_EXCEPTION_HANDLING_USE_POSIX_SIGNALS
|
||||||
struct Signal
|
struct SignalInfo
|
||||||
{
|
{
|
||||||
int32_t signalId;
|
int32_t signalId;
|
||||||
const char* name;
|
const char* name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Signal s_signal[] =
|
static const SignalInfo s_signalInfo[] =
|
||||||
{ // Linux
|
{ // Linux
|
||||||
{ /* 4 */ SIGILL, "SIGILL - Illegal instruction signal." },
|
{ /* 4 */ SIGILL, "SIGILL - Illegal instruction signal." },
|
||||||
{ /* 6 */ SIGABRT, "SIGABRT - Abort signal." },
|
{ /* 6 */ SIGABRT, "SIGABRT - Abort signal." },
|
||||||
@@ -391,11 +418,12 @@ namespace bx
|
|||||||
{ /* 11 */ SIGSEGV, "SIGSEGV - Segmentation violation signal." },
|
{ /* 11 */ SIGSEGV, "SIGSEGV - Segmentation violation signal." },
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExceptionHandler
|
struct ExceptionHandler
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
ExceptionHandler()
|
ExceptionHandler()
|
||||||
{
|
{
|
||||||
|
BX_TRACE("ExceptionHandler - POSIX");
|
||||||
|
|
||||||
stack_t stack;
|
stack_t stack;
|
||||||
stack.ss_sp = s_stack;
|
stack.ss_sp = s_stack;
|
||||||
stack.ss_size = sizeof(s_stack);
|
stack.ss_size = sizeof(s_stack);
|
||||||
@@ -409,9 +437,9 @@ namespace bx
|
|||||||
sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
|
sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
|
||||||
sa.sa_restorer = NULL;
|
sa.sa_restorer = NULL;
|
||||||
|
|
||||||
for (uint32_t ii = 0; ii < BX_COUNTOF(s_signal); ++ii)
|
for (uint32_t ii = 0; ii < BX_COUNTOF(s_exceptionInfo); ++ii)
|
||||||
{
|
{
|
||||||
sigaction(s_signal[ii].signalId, &sa, &m_oldSignalAction[ii]);
|
sigaction(s_exceptionInfo[ii].exceptionCode, &sa, &m_oldSignalAction[ii]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,18 +453,18 @@ namespace bx
|
|||||||
|
|
||||||
const char* name = "Unknown signal?";
|
const char* name = "Unknown signal?";
|
||||||
|
|
||||||
for (uint32_t ii = 0; ii < BX_COUNTOF(s_signal); ++ii)
|
for (uint32_t ii = 0; ii < BX_COUNTOF(s_signalInfo); ++ii)
|
||||||
{
|
{
|
||||||
const Signal& signal = s_signal[ii];
|
const SignalInfo& signalInfo = s_signalInfo[ii];
|
||||||
|
|
||||||
if (signal.signalId == _signalId)
|
if (signalInfo.signalId == _signalId)
|
||||||
{
|
{
|
||||||
name = signal.name;
|
name = signalInfo.name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assertFunction(Location("Exception Handler", -1), 2
|
if (assertFunction(Location("Exception Handler", UINT32_MAX), 2
|
||||||
, "%s SIGNAL %d, ERRNO %d, CODE %d"
|
, "%s SIGNAL %d, ERRNO %d, CODE %d"
|
||||||
, name
|
, name
|
||||||
, _info->si_signo
|
, _info->si_signo
|
||||||
@@ -458,7 +486,72 @@ namespace bx
|
|||||||
|
|
||||||
char ExceptionHandler::s_stack[kExceptionStackSize];
|
char ExceptionHandler::s_stack[kExceptionStackSize];
|
||||||
|
|
||||||
static ExceptionHandler s_exceptionHandler;
|
#elif BX_CONFIG_EXCEPTION_HANDLING_USE_WINDOWS_SEH
|
||||||
#endif // BX_PLATFORM_LINUX
|
|
||||||
|
struct ExceptionInfo
|
||||||
|
{
|
||||||
|
uint32_t exceptionCode;
|
||||||
|
const char* name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ExceptionInfo s_exceptionInfo[] =
|
||||||
|
{ // Windows
|
||||||
|
{ /* EXCEPTION_ACCESS_VIOLATION */ 0xc0000005u, "Access violation." },
|
||||||
|
{ /* EXCEPTION_ILLEGAL_INSTRUCTION */ 0xc000001du, "Illegal instruction." },
|
||||||
|
{ /* EXCEPTION_STACK_OVERFLOW */ 0xc00000fdu, "Stack overflow." },
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExceptionHandler
|
||||||
|
{
|
||||||
|
ExceptionHandler()
|
||||||
|
{
|
||||||
|
BX_TRACE("ExceptionHandler - Windows SEH");
|
||||||
|
SetUnhandledExceptionFilter(topLevelExceptionFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t __stdcall topLevelExceptionFilter(ExceptionPointers* _info)
|
||||||
|
{
|
||||||
|
const char* name = "Unknown signal?";
|
||||||
|
|
||||||
|
const uint32_t exceptionCode = _info->exceptionRecord->exceptionCode;
|
||||||
|
|
||||||
|
for (uint32_t ii = 0; ii < BX_COUNTOF(s_exceptionInfo); ++ii)
|
||||||
|
{
|
||||||
|
const ExceptionInfo& signal = s_exceptionInfo[ii];
|
||||||
|
|
||||||
|
if (signal.exceptionCode == exceptionCode)
|
||||||
|
{
|
||||||
|
name = signal.name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assertFunction(Location("Exception Handler", UINT32_MAX), 2
|
||||||
|
, "%s Exception Code %x"
|
||||||
|
, name
|
||||||
|
, _info->exceptionRecord->exceptionCode
|
||||||
|
) )
|
||||||
|
{
|
||||||
|
exit(kExitFailure, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 /* EXCEPTION_CONTINUE_SEARCH */;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#else // Noop exception handler
|
||||||
|
|
||||||
|
class ExceptionHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExceptionHandler()
|
||||||
|
{
|
||||||
|
BX_TRACE("ExceptionHandler - Noop");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BX_CONFIG_EXCEPTION_HANDLING_*
|
||||||
|
|
||||||
|
ExceptionHandler s_exceptionHandler;
|
||||||
|
|
||||||
} // namespace bx
|
} // namespace bx
|
||||||
|
|||||||
Reference in New Issue
Block a user