forked from OSchip/llvm-project
tsan: fix crashes if signal is caught during thread bootstrap or shutdown
llvm-svn: 159361
This commit is contained in:
parent
b27564af76
commit
fa985a02ef
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue