From 7925de66b266166c2b3ac43a88745db23c7cd25c Mon Sep 17 00:00:00 2001 From: Jonathan Hamilton Date: Tue, 5 Sep 2017 17:13:30 -0700 Subject: [PATCH] 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 --- Source/Core/Core/MemTools.cpp | 47 ++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/MemTools.cpp b/Source/Core/Core/MemTools.cpp index 92101bd8b433..5f1facaf3cb2 100644 --- a/Source/Core/Core/MemTools.cpp +++ b/Source/Core/Core/MemTools.cpp @@ -232,6 +232,9 @@ void UninstallExceptionHandler() #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) { if (sig != SIGSEGV && sig != SIGBUS) @@ -264,10 +267,38 @@ static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context) )) { // retry and crash - signal(SIGSEGV, SIG_DFL); -#ifdef __APPLE__ - signal(SIGBUS, SIG_DFL); -#endif + // According to the sigaction man page, if sa_flags "SA_SIGINFO" is set to the sigaction + // function pointer, otherwise sa_handler contains one of: + // SIG_DEF: The 'default' action is performed + // 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_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); - sigaction(SIGSEGV, &sa, nullptr); + sigaction(SIGSEGV, &sa, &old_sa_segv); #ifdef __APPLE__ - sigaction(SIGBUS, &sa, nullptr); + sigaction(SIGBUS, &sa, &old_sa_bus); #endif } @@ -302,6 +333,10 @@ void UninstallExceptionHandler() { 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