Run exception handlers on an alternate stack on Linux.

*Completely untested.*  Someone please test.
This commit is contained in:
comex 2014-09-07 19:10:02 -04:00
parent bd4e75e69a
commit 7b0fdb52cd
4 changed files with 28 additions and 0 deletions

View File

@ -86,4 +86,7 @@ void InstallExceptionHandler()
sigemptyset(&sa.sa_mask);
sigaction(SIGSEGV, &sa, nullptr);
}
void UninstallExceptionHandler() {}
} // namespace

View File

@ -277,6 +277,10 @@ static void CpuThread()
if (!_CoreParameter.bCPUThread)
g_video_backend->Video_Cleanup();
#if _M_X86_64 || _M_ARM_32
EMM::UninstallExceptionHandler();
#endif
return;
}

View File

@ -11,4 +11,5 @@ namespace EMM
{
typedef u32 EAddr;
void InstallExceptionHandler();
void UninstallExceptionHandler();
}

View File

@ -125,6 +125,8 @@ void InstallExceptionHandler()
handlerInstalled = true;
}
void UninstallExceptionHandler() {}
#elif defined(__APPLE__)
void CheckKR(const char* name, kern_return_t kr)
@ -243,6 +245,8 @@ void InstallExceptionHandler()
CheckKR("mach_port_request_notification", mach_port_request_notification(mach_task_self(), port, MACH_NOTIFY_NO_SENDERS, 0, port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous));
}
void UninstallExceptionHandler() {}
#elif defined(_POSIX_VERSION)
static void sigsegv_handler(int sig, siginfo_t *info, void *raw_context)
@ -273,6 +277,12 @@ static void sigsegv_handler(int sig, siginfo_t *info, void *raw_context)
void InstallExceptionHandler()
{
stack_t signal_stack;
signal_stack.ss_sp = malloc(SIGSTKSZ);
signal_stack.ss_size = SIGSTKSZ;
signal_stack.ss_flags = 0;
if (sigaltstack(&signal_stack, nullptr))
PanicAlert("sigaltstack failed");
struct sigaction sa;
sa.sa_handler = nullptr;
sa.sa_sigaction = &sigsegv_handler;
@ -281,6 +291,16 @@ void InstallExceptionHandler()
sigaction(SIGSEGV, &sa, nullptr);
}
void UninstallExceptionHandler()
{
stack_t signal_stack, old_stack;
signal_stack.ss_flags = SS_DISABLE;
if (!sigaltstack(&signal_stack, &old_stack) &&
!(old_stack.ss_flags & SS_DISABLE))
{
free(old_stack.ss_sp);
}
}
#else
#error Unsupported x86_64 platform! Report this if you support sigaction