From e07dc7d1fe1d77e0c836f3149b17b56cd2ba8e59 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 3 Oct 2013 14:00:46 +0000 Subject: [PATCH] tsan: intercept _exit so that we can override exit status llvm-svn: 191898 --- compiler-rt/lib/tsan/rtl/tsan_flags.h | 3 ++ compiler-rt/lib/tsan/rtl/tsan_interceptors.cc | 30 ++++++++++++------- compiler-rt/lib/tsan/rtl/tsan_stat.cc | 1 + compiler-rt/lib/tsan/rtl/tsan_stat.h | 1 + 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.h b/compiler-rt/lib/tsan/rtl/tsan_flags.h index 238982bf2a32..86e1a2cb0639 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.h +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.h @@ -75,6 +75,9 @@ struct Flags { int flush_memory_ms; // Flush symbolizer caches every X ms. int flush_symbolizer_ms; + // Resident memory limit in MB to aim at. + // If the process consumes more memory, then TSan will flush shadow memory. + int memory_limit_mb; // Stops on start until __tsan_resume() is called (for debugging). bool stop_on_start; // Controls whether RunningOnValgrind() returns true or false. diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index c4bde58f1423..eebdf3e50151 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -1958,8 +1958,27 @@ static void syscall_post_fork(uptr pc, int res) { syscall_post_fork(GET_CALLER_PC(), res) #include "sanitizer_common/sanitizer_common_syscalls.inc" +TSAN_INTERCEPTOR(void, _exit, int status) { + ThreadState * thr = cur_thread(); + int status1 = Finalize(thr); + REAL(fflush)(0); + if (status == 0) + status = status1; + REAL(_exit)(status); +} + namespace __tsan { +static void finalize(void *arg) { + ThreadState * thr = cur_thread(); + uptr pc = 0; + atexit_ctx->exit(thr, pc); + int status = Finalize(thr); + REAL(fflush)(0); + if (status) + REAL(_exit)(status); +} + void ProcessPendingSignals(ThreadState *thr) { CHECK_EQ(thr->in_rtl, 0); SignalContext *sctx = SigCtx(thr); @@ -2009,16 +2028,6 @@ void ProcessPendingSignals(ThreadState *thr) { thr->in_signal_handler = false; } -static void finalize(void *arg) { - ThreadState * thr = cur_thread(); - uptr pc = 0; - atexit_ctx->exit(thr, pc); - int status = Finalize(cur_thread()); - REAL(fflush)(0); - if (status) - _exit(status); -} - static void unreachable() { Printf("FATAL: ThreadSanitizer: unreachable called\n"); Die(); @@ -2199,6 +2208,7 @@ void InitializeInterceptors() { TSAN_INTERCEPT(dlclose); TSAN_INTERCEPT(on_exit); TSAN_INTERCEPT(__cxa_atexit); + TSAN_INTERCEPT(_exit); // Need to setup it, because interceptors check that the function is resolved. // But atexit is emitted directly into the module, so can't be resolved. diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.cc b/compiler-rt/lib/tsan/rtl/tsan_stat.cc index 96d5ee48623a..4fa91a69de39 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_stat.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_stat.cc @@ -142,6 +142,7 @@ void StatOutput(u64 *stat) { name[StatInt_strcasecmp] = " strcasecmp "; name[StatInt_strncasecmp] = " strncasecmp "; name[StatInt_atexit] = " atexit "; + name[StatInt__exit] = " _exit "; name[StatInt___cxa_guard_acquire] = " __cxa_guard_acquire "; name[StatInt___cxa_guard_release] = " __cxa_guard_release "; name[StatInt___cxa_guard_abort] = " __cxa_guard_abort "; diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.h b/compiler-rt/lib/tsan/rtl/tsan_stat.h index 43c6b1cca424..b97aee80a37c 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_stat.h +++ b/compiler-rt/lib/tsan/rtl/tsan_stat.h @@ -139,6 +139,7 @@ enum StatType { StatInt_strstr, StatInt_strdup, StatInt_atexit, + StatInt__exit, StatInt___cxa_guard_acquire, StatInt___cxa_guard_release, StatInt___cxa_guard_abort,