Added Linux/signal exception handling.

This commit is contained in:
Branimir Karadžić
2025-08-23 09:20:41 -07:00
parent d858859d17
commit d2b8b1aab5
8 changed files with 146 additions and 28 deletions

View File

@@ -22,6 +22,15 @@
# include <cxxabi.h> // abi::__cxa_demangle
#endif // BX_CONFIG_CALLSTACK_*
#ifndef BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
# define BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS 0 \
| (BX_PLATFORM_LINUX && !BX_CRT_NONE)
#endif // BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
#if BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
# include <signal.h>
#endif // BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
#if BX_CRT_NONE
# include <bx/crt0.h>
#elif BX_PLATFORM_ANDROID
@@ -283,6 +292,9 @@ namespace bx
int32_t total = write(_writer, _err, "Callstack (%d):\n", _num);
constexpr uint32_t kWidth = 40;
total += write(_writer, _err, "\t #: %-*s Line: PC --- Function ---\n", kWidth, "File ---");
CallbackData cbData;
for (uint32_t ii = 0; ii < _num && _err->isOk(); ++ii)
@@ -311,13 +323,12 @@ namespace bx
demangledName = "???";
}
constexpr uint32_t width = 40;
const StringView fn = strTail(cbData.fileName, width);
const StringView fn = strTail(cbData.fileName, kWidth);
total += write(_writer, _err
, "\t%2d: %-*S % 5d: %p %S\n"
, ii
, width
, kWidth
, &fn
, cbData.line
, _stack[ii]
@@ -363,4 +374,89 @@ namespace bx
writeCallstack(getDebugOut(), stack, num, ErrorIgnore{});
}
#if BX_CONFIG_EXCEPTION_HANDLING_USE_SIGNALS
struct Signal
{
int32_t signalId;
const char* name;
};
static const Signal s_signal[] =
{ // Linux
{ /* 4 */ SIGILL, "SIGILL - Illegal instruction signal." },
{ /* 6 */ SIGABRT, "SIGABRT - Abort signal." },
{ /* 8 */ SIGFPE, "SIGFPE - Floating point error signal." },
{ /* 11 */ SIGSEGV, "SIGSEGV - Segmentation violation signal." },
};
class ExceptionHandler
{
public:
ExceptionHandler()
{
stack_t stack;
stack.ss_sp = s_stack;
stack.ss_size = sizeof(s_stack);
stack.ss_flags = 0;
sigaltstack(&stack, &m_oldStack);
struct sigaction sa;
sa.sa_handler = NULL;
sa.sa_sigaction = signalActionHandler;
sa.sa_mask = { 0 };
sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
sa.sa_restorer = NULL;
for (uint32_t ii = 0; ii < BX_COUNTOF(s_signal); ++ii)
{
sigaction(s_signal[ii].signalId, &sa, &m_oldSignalAction[ii]);
}
}
~ExceptionHandler()
{
}
static void signalActionHandler(int32_t _signalId, siginfo_t* _info, void* _context)
{
BX_UNUSED(_context);
const char* name = "Unknown signal?";
for (uint32_t ii = 0; ii < BX_COUNTOF(s_signal); ++ii)
{
const Signal& signal = s_signal[ii];
if (signal.signalId == _signalId)
{
name = signal.name;
break;
}
}
if (assertFunction(Location("Exception Handler", -1), 2
, "%s SIGNAL %d, ERRNO %d, CODE %d"
, name
, _info->si_signo
, _info->si_errno
, _info->si_code
) )
{
exit(kExitFailure, false);
}
}
static constexpr uint32_t kExceptionStackSize = 64<<10;
static char s_stack[kExceptionStackSize];
stack_t m_oldStack;
struct sigaction m_oldSignalAction[BX_COUNTOF(s_signal)];
};
char ExceptionHandler::s_stack[kExceptionStackSize];
static ExceptionHandler s_exceptionHandler;
#endif // BX_PLATFORM_LINUX
} // namespace bx