Don't block certain error signals on background threads

Previously fish attempted to block all signals on background threads, so
that they would be delivered to the main thread. But on Mac, SIGSEGV
and probably some others just get silently dropped, leading to potential
infinite loops instead of crashing. So stop blocking these signals.

With this change the null-deref in #7837 will properly crash instead of
spinning.
This commit is contained in:
ridiculousfish 2021-03-21 14:50:37 -07:00
parent 43cc99e1ba
commit a7c37e4af4

View file

@ -397,11 +397,18 @@ void iothread_perform_on_main(void_function_t &&func) {
}
bool make_detached_pthread(void *(*func)(void *), void *param) {
// The spawned thread inherits our signal mask. We don't want the thread to ever receive signals
// on the spawned thread, so temporarily block all signals, spawn the thread, and then restore
// it.
// The spawned thread inherits our signal mask. Temporarily block signals, spawn the thread, and
// then restore it. But we must not block SIGBUS, SIGFPE, SIGILL, or SIGSEGV; that's undefined
// (#7837). Conservatively don't try to mask SIGKILL or SIGSTOP either; that's ignored on Linux
// but maybe has an effect elsewhere.
sigset_t new_set, saved_set;
sigfillset(&new_set);
sigdelset(&new_set, SIGILL); // bad jump
sigdelset(&new_set, SIGFPE); // divide by zero
sigdelset(&new_set, SIGBUS); // unaligned memory access
sigdelset(&new_set, SIGSEGV); // bad memory access
sigdelset(&new_set, SIGSTOP); // unblockable
sigdelset(&new_set, SIGKILL); // unblockable
DIE_ON_FAILURE(pthread_sigmask(SIG_BLOCK, &new_set, &saved_set));
// Spawn a thread. If this fails, it means there's already a bunch of threads; it is very