diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index 50045ade6292..e6d323a6a560 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -113,7 +113,7 @@ struct SignalContext { static SignalContext *SigCtx(ThreadState *thr) { SignalContext *ctx = (SignalContext*)thr->signal_ctx; - if (ctx == 0) { + if (ctx == 0 && thr->is_alive) { ScopedInRtl in_rtl; ctx = (SignalContext*)internal_alloc( MBlockSignal, sizeof(*ctx)); @@ -682,10 +682,12 @@ static void thread_finalize(void *v) { { ScopedInRtl in_rtl; ThreadState *thr = cur_thread(); - SignalContext *sctx = thr->signal_ctx; ThreadFinish(thr); - if (sctx) + SignalContext *sctx = thr->signal_ctx; + if (sctx) { + thr->signal_ctx = 0; internal_free(sctx); + } } } @@ -1285,8 +1287,9 @@ static void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig, ThreadState *thr = cur_thread(); SignalContext *sctx = SigCtx(thr); // Don't mess with synchronous signals. - if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGABRT || - sig == SIGFPE || sig == SIGPIPE || sig == sctx->int_signal_send) { + if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || + sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || + (sctx && sig == sctx->int_signal_send)) { CHECK(thr->in_rtl == 0 || thr->in_rtl == 1); int in_rtl = thr->in_rtl; thr->in_rtl = 0; @@ -1302,6 +1305,8 @@ static void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig, return; } + if (sctx == 0) + return; SignalDesc *signal = &sctx->pending_signals[sig]; if (signal->armed == false) { signal->armed = true; @@ -1356,6 +1361,7 @@ TSAN_INTERCEPTOR(sighandler_t, signal, int sig, sighandler_t h) { TSAN_INTERCEPTOR(int, raise, int sig) { SCOPED_TSAN_INTERCEPTOR(raise, sig); SignalContext *sctx = SigCtx(thr); + CHECK_NE(sctx, 0); int prev = sctx->int_signal_send; sctx->int_signal_send = sig; int res = REAL(raise)(sig); @@ -1367,6 +1373,7 @@ TSAN_INTERCEPTOR(int, raise, int sig) { TSAN_INTERCEPTOR(int, kill, int pid, int sig) { SCOPED_TSAN_INTERCEPTOR(kill, pid, sig); SignalContext *sctx = SigCtx(thr); + CHECK_NE(sctx, 0); int prev = sctx->int_signal_send; if (pid == GetPid()) { sctx->int_signal_send = sig; @@ -1382,6 +1389,7 @@ TSAN_INTERCEPTOR(int, kill, int pid, int sig) { TSAN_INTERCEPTOR(int, pthread_kill, void *tid, int sig) { SCOPED_TSAN_INTERCEPTOR(pthread_kill, tid, sig); SignalContext *sctx = SigCtx(thr); + CHECK_NE(sctx, 0); int prev = sctx->int_signal_send; if (tid == pthread_self()) { sctx->int_signal_send = sig; @@ -1397,7 +1405,7 @@ TSAN_INTERCEPTOR(int, pthread_kill, void *tid, int sig) { static void process_pending_signals(ThreadState *thr) { CHECK_EQ(thr->in_rtl, 0); SignalContext *sctx = SigCtx(thr); - if (sctx->pending_signal_count == 0 || thr->in_signal_handler) + if (sctx == 0 || sctx->pending_signal_count == 0 || thr->in_signal_handler) return; thr->in_signal_handler = true; sctx->pending_signal_count = 0; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index f45be19e486e..71ca5d47a575 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -233,6 +233,7 @@ struct ThreadState { u64 stat[StatCnt]; const int tid; int in_rtl; + bool is_alive; const uptr stk_addr; const uptr stk_size; const uptr tls_addr; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc index 147e383b63cb..68a5c3e29172 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc @@ -173,6 +173,7 @@ void ThreadStart(ThreadState *thr, int tid) { DPrintf("#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx " "tls_addr=%zx tls_size=%zx\n", tid, (uptr)tctx->epoch0, stk_addr, stk_size, tls_addr, tls_size); + thr->is_alive = true; } void ThreadFinish(ThreadState *thr) { @@ -189,6 +190,7 @@ void ThreadFinish(ThreadState *thr) { MemoryResetRange(thr, /*pc=*/ 5, thr_end, thr->tls_addr + thr->tls_size - thr_end); } + thr->is_alive = false; Context *ctx = CTX(); Lock l(&ctx->thread_mtx); ThreadContext *tctx = ctx->threads[thr->tid];