summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2012-06-28 18:07:46 +0000
committerDmitry Vyukov <dvyukov@google.com>2012-06-28 18:07:46 +0000
commitfa985a02efa5b840b2683b0a91d36ad05d449d81 (patch)
treecb40fade0accc59203a731aba668f2407dfebde9 /compiler-rt/lib
parentb27564af76871fc4c8f8ba372ea81a37ae67553b (diff)
downloadbcm5719-llvm-fa985a02efa5b840b2683b0a91d36ad05d449d81.tar.gz
bcm5719-llvm-fa985a02efa5b840b2683b0a91d36ad05d449d81.zip
tsan: fix crashes if signal is caught during thread bootstrap or shutdown
llvm-svn: 159361
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors.cc20
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl.h1
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc2
3 files changed, 17 insertions, 6 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
index 50045ade629..e6d323a6a56 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 f45be19e486..71ca5d47a57 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 147e383b63c..68a5c3e2917 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];
OpenPOWER on IntegriCloud