From 5b8c497cecdf6669f3c92214fb17f0e95023c527 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Sat, 23 May 2026 01:17:58 +0300 Subject: [PATCH] #4320 Bugsplat fails to catch thread crashes on Apple Silicon --- indra/llcommon/llapp.cpp | 4 ++-- indra/llcommon/llthread.cpp | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index f92bb98ba6..45800683b4 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -324,7 +324,6 @@ void LLApp::setupErrorHandling(bool second_instance) #else // ! LL_WINDOWS -#if ! defined(LL_BUGSPLAT) // // Start up signal handling. // @@ -332,7 +331,6 @@ void LLApp::setupErrorHandling(bool second_instance) // thread, asynchronous signals can be delivered to any thread (in theory) // setup_signals(); -#endif // ! LL_BUGSPLAT #endif // ! LL_WINDOWS } @@ -508,7 +506,9 @@ void setup_signals() { // // Set up signal handlers that may result in program termination + // Related: restoreErrorTrap // + // TODO: add tests that generate signals struct sigaction act; act.sa_sigaction = default_unix_signal_handler; sigemptyset( &act.sa_mask ); diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 8c12ee7f12..ea025e772b 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -174,6 +174,24 @@ void LLThread::threadRun() // this is the first point at which we're actually running in the new thread mID = currentID(); +#if !LL_WINDOWS + // On Unix platforms, make sure this thread's signal mask does not block + // crash signals. Signal dispositions are process-wide, but the signal mask + // is maintained per-thread, explicitly unblock these signals. + // This is critical on ARM64 macOS where thread crashes may not be properly + // captured by BugSplat if crash signals remain blocked in the thread mask. + // The signal handlers were installed process-wide in setupErrorHandling(). + sigset_t signals; + sigemptyset(&signals); + sigaddset(&signals, SIGSEGV); + sigaddset(&signals, SIGBUS); + sigaddset(&signals, SIGILL); + sigaddset(&signals, SIGFPE); + sigaddset(&signals, SIGSYS); + // Unblock crash signals for this thread + pthread_sigmask(SIG_UNBLOCK, &signals, nullptr); +#endif + // for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder());