RFC: Call the previously-set sigaction in fastmem handler if it's not our address

This "fixes" the android crash handler, so it now correctly shows a
backtrace and other debug info on crash instead of scary kernel messages
on arm64
This commit is contained in:
Jonathan Hamilton 2017-09-05 17:13:30 -07:00
parent b96e4a2bce
commit 7925de66b2
1 changed files with 41 additions and 6 deletions

View File

@ -232,6 +232,9 @@ void UninstallExceptionHandler()
#elif defined(_POSIX_VERSION) && !defined(_M_GENERIC) #elif defined(_POSIX_VERSION) && !defined(_M_GENERIC)
static struct sigaction old_sa_segv;
static struct sigaction old_sa_bus;
static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context) static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context)
{ {
if (sig != SIGSEGV && sig != SIGBUS) if (sig != SIGSEGV && sig != SIGBUS)
@ -264,10 +267,38 @@ static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context)
)) ))
{ {
// retry and crash // retry and crash
signal(SIGSEGV, SIG_DFL); // According to the sigaction man page, if sa_flags "SA_SIGINFO" is set to the sigaction
#ifdef __APPLE__ // function pointer, otherwise sa_handler contains one of:
signal(SIGBUS, SIG_DFL); // SIG_DEF: The 'default' action is performed
#endif // SIG_IGN: The signal is ignored
// Any other value is a function pointer to a signal handler
struct sigaction* old_sa;
if (sig == SIGSEGV)
{
old_sa = &old_sa_segv;
}
else
{
old_sa = &old_sa_bus;
}
if (old_sa->sa_flags & SA_SIGINFO)
{
old_sa->sa_sigaction(sig, info, raw_context);
return;
}
if (old_sa->sa_handler == SIG_DFL)
{
signal(sig, SIG_DFL);
return;
}
if (old_sa->sa_handler == SIG_IGN)
{
// Ignore signal
return;
}
old_sa->sa_handler(sig);
} }
} }
@ -288,9 +319,9 @@ void InstallExceptionHandler()
sa.sa_sigaction = &sigsegv_handler; sa.sa_sigaction = &sigsegv_handler;
sa.sa_flags = SA_SIGINFO; sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sigaction(SIGSEGV, &sa, nullptr); sigaction(SIGSEGV, &sa, &old_sa_segv);
#ifdef __APPLE__ #ifdef __APPLE__
sigaction(SIGBUS, &sa, nullptr); sigaction(SIGBUS, &sa, &old_sa_bus);
#endif #endif
} }
@ -302,6 +333,10 @@ void UninstallExceptionHandler()
{ {
free(old_stack.ss_sp); free(old_stack.ss_sp);
} }
sigaction(SIGSEGV, &old_sa_segv, nullptr);
#ifdef __APPLE__
sigaction(SIGBUS, &old_sa_bus, nullptr);
#endif
} }
#else // _M_GENERIC or unsupported platform #else // _M_GENERIC or unsupported platform