diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -161,7 +161,6 @@ namespace __tsan { struct SignalDesc { bool armed; - bool sigaction; __sanitizer_siginfo siginfo; ucontext_t ctx; }; @@ -1934,8 +1933,8 @@ namespace __tsan { static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire, - bool sigact, int sig, - __sanitizer_siginfo *info, void *uctx) { + int sig, __sanitizer_siginfo *info, + void *uctx) { __sanitizer_sigaction *sigactions = interceptor_ctx()->sigactions; if (acquire) Acquire(thr, 0, (uptr)&sigactions[sig]); @@ -1958,14 +1957,11 @@ // This code races with sigaction. Be careful to not read sa_sigaction twice. // Also need to remember pc for reporting before the call, // because the handler can reset it. - volatile uptr pc = - sigact ? (uptr)sigactions[sig].sigaction : (uptr)sigactions[sig].handler; - if (pc != sig_dfl && pc != sig_ign) { - if (sigact) - ((__sanitizer_sigactionhandler_ptr)pc)(sig, info, uctx); - else - ((__sanitizer_sighandler_ptr)pc)(sig); - } + volatile uptr pc = (sigactions[sig].sa_flags & SA_SIGINFO) + ? (uptr)sigactions[sig].sigaction + : (uptr)sigactions[sig].handler; + if (pc != sig_dfl && pc != sig_ign) + ((__sanitizer_sigactionhandler_ptr)pc)(sig, info, uctx); if (!ctx->after_multithreaded_fork) { thr->ignore_reads_and_writes = ignore_reads_and_writes; if (ignore_reads_and_writes) @@ -2010,8 +2006,8 @@ SignalDesc *signal = &sctx->pending_signals[sig]; if (signal->armed) { signal->armed = false; - CallUserSignalHandler(thr, false, true, signal->sigaction, sig, - &signal->siginfo, &signal->ctx); + CallUserSignalHandler(thr, false, true, sig, &signal->siginfo, + &signal->ctx); } } res = REAL(pthread_sigmask)(SIG_SETMASK, &sctx->oldset, 0); @@ -2028,9 +2024,7 @@ (sctx && sig == sctx->int_signal_send); } -void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig, - __sanitizer_siginfo *info, - void *ctx) { +void sighandler(int sig, __sanitizer_siginfo *info, void *ctx) { cur_thread_init(); ThreadState *thr = cur_thread(); ThreadSignalContext *sctx = SigCtx(thr); @@ -2048,7 +2042,7 @@ atomic_fetch_add(&thr->in_signal_handler, 1, memory_order_relaxed); if (sctx && atomic_load(&sctx->in_blocking_func, memory_order_relaxed)) { atomic_store(&sctx->in_blocking_func, 0, memory_order_relaxed); - CallUserSignalHandler(thr, sync, true, sigact, sig, info, ctx); + CallUserSignalHandler(thr, sync, true, sig, info, ctx); atomic_store(&sctx->in_blocking_func, 1, memory_order_relaxed); } else { // Be very conservative with when we do acquire in this case. @@ -2057,7 +2051,7 @@ // SIGSYS looks relatively safe -- it's synchronous and can actually // need some global state. bool acq = (sig == SIGSYS); - CallUserSignalHandler(thr, sync, acq, sigact, sig, info, ctx); + CallUserSignalHandler(thr, sync, acq, sig, info, ctx); } atomic_fetch_add(&thr->in_signal_handler, -1, memory_order_relaxed); return; @@ -2068,23 +2062,12 @@ SignalDesc *signal = &sctx->pending_signals[sig]; if (signal->armed == false) { signal->armed = true; - signal->sigaction = sigact; - if (info) - internal_memcpy(&signal->siginfo, info, sizeof(*info)); - if (ctx) - internal_memcpy(&signal->ctx, ctx, sizeof(signal->ctx)); + internal_memcpy(&signal->siginfo, info, sizeof(*info)); + internal_memcpy(&signal->ctx, ctx, sizeof(signal->ctx)); atomic_store(&sctx->have_pending_signals, 1, memory_order_relaxed); } } -static void rtl_sighandler(int sig) { - rtl_generic_sighandler(false, sig, 0, 0); -} - -static void rtl_sigaction(int sig, __sanitizer_siginfo *info, void *ctx) { - rtl_generic_sighandler(true, sig, info, ctx); -} - TSAN_INTERCEPTOR(int, raise, int sig) { SCOPED_TSAN_INTERCEPTOR(raise, sig); ThreadSignalContext *sctx = SigCtx(thr); @@ -2420,7 +2403,7 @@ int sigaction_impl(int sig, const __sanitizer_sigaction *act, __sanitizer_sigaction *old) { // Note: if we call REAL(sigaction) directly for any reason without proxying - // the signal handler through rtl_sigaction, very bad things will happen. + // the signal handler through sighandler, very bad things will happen. // The handler will run synchronously and corrupt tsan per-thread state. SCOPED_INTERCEPTOR_RAW(sigaction, sig, act, old); if (sig <= 0 || sig >= kSigCount) { @@ -2448,22 +2431,15 @@ #endif internal_memcpy(&newact, act, sizeof(newact)); internal_sigfillset(&newact.sa_mask); - if ((uptr)act->handler != sig_ign && (uptr)act->handler != sig_dfl) { - if (newact.sa_flags & SA_SIGINFO) - newact.sigaction = rtl_sigaction; - else - newact.handler = rtl_sighandler; - } + newact.sa_flags |= SA_SIGINFO; + if ((uptr)act->handler != sig_ign && (uptr)act->handler != sig_dfl) + newact.sigaction = sighandler; ReleaseStore(thr, pc, (uptr)&sigactions[sig]); act = &newact; } int res = REAL(sigaction)(sig, act, old); - if (res == 0 && old) { - uptr cb = (uptr)old->sigaction; - if (cb == (uptr)rtl_sigaction || cb == (uptr)rtl_sighandler) { - internal_memcpy(old, &old_stored, sizeof(*old)); - } - } + if (res == 0 && old && old->sigaction == sighandler) + internal_memcpy(old, &old_stored, sizeof(*old)); return res; }