This commit is contained in:
Jordan Woyak 2025-11-15 14:52:22 -06:00 committed by GitHub
commit 3718d548ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -258,73 +258,51 @@ bool IsExceptionHandlerSupported()
#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_segv;
#if defined(__APPLE__)
static struct sigaction old_sa_bus; static struct sigaction old_sa_bus;
#endif
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
#if defined(__APPLE__)
&& sig != SIGBUS
#endif
)
{ {
// We are not interested in other signals - handle it as usual. // We are not interested in other signals - handle it as usual.
return; return;
} }
ucontext_t* context = (ucontext_t*)raw_context; auto* const context = static_cast<ucontext_t*>(raw_context);
int sicode = info->si_code; const int sicode = info->si_code;
if (sicode != SEGV_MAPERR && sicode != SEGV_ACCERR) if (sicode != SEGV_MAPERR && sicode != SEGV_ACCERR)
{ {
// Huh? Return. // Huh? Return.
return; return;
} }
uintptr_t bad_address = (uintptr_t)info->si_addr; const auto bad_address = reinterpret_cast<uintptr_t>(info->si_addr);
// Get all the information we can out of the context. // Get all the information we can out of the context.
#ifdef __OpenBSD__ #ifdef __OpenBSD__
ucontext_t* ctx = context; SContext* const ctx = context;
#elif defined(__APPLE__)
// `uc_mcontext` is already a pointer here.
SContext* const ctx = context->uc_mcontext;
#else #else
mcontext_t* ctx = &context->uc_mcontext; SContext* const ctx = &context->uc_mcontext;
#endif #endif
// assume it's not a write if (Core::System::GetInstance().GetJitInterface().HandleFault(bad_address, ctx))
if (!Core::System::GetInstance().GetJitInterface().HandleFault(bad_address, return;
#ifdef __APPLE__
*ctx // If JIT didn't handle the signal, restore the original handler and invoke it.
#else const auto& old_sa =
ctx #if defined(__APPLE__)
(sig == SIGBUS) ? old_sa_bus :
#endif #endif
)) old_sa_segv;
{
// retry and crash
// 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; sigaction(sig, &old_sa, nullptr);
if (sig == SIGSEGV) raise(sig);
{
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);
}
} }
void InstallExceptionHandler() void InstallExceptionHandler()
@ -337,10 +315,9 @@ void InstallExceptionHandler()
#endif #endif
signal_stack.ss_size = SIGSTKSZ; signal_stack.ss_size = SIGSTKSZ;
signal_stack.ss_flags = 0; signal_stack.ss_flags = 0;
if (sigaltstack(&signal_stack, nullptr)) if (sigaltstack(&signal_stack, nullptr) != 0)
PanicAlertFmt("sigaltstack failed"); PanicAlertFmt("sigaltstack failed: {}", Common::LastStrerrorString());
struct sigaction sa; struct sigaction sa{};
sa.sa_handler = nullptr;
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);
@ -352,7 +329,8 @@ void InstallExceptionHandler()
void UninstallExceptionHandler() void UninstallExceptionHandler()
{ {
stack_t signal_stack, old_stack; stack_t signal_stack;
stack_t old_stack;
signal_stack.ss_flags = SS_DISABLE; signal_stack.ss_flags = SS_DISABLE;
if (!sigaltstack(&signal_stack, &old_stack) && !(old_stack.ss_flags & SS_DISABLE)) if (!sigaltstack(&signal_stack, &old_stack) && !(old_stack.ss_flags & SS_DISABLE))
{ {