From 5e2d3776a314629680921abd1d55d89d95a2da90 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Wed, 16 Oct 2013 08:20:31 +0000 Subject: Make some pthread_mutex_* and pthread_cond_* interceptors common. Reviewers: eugenis, dvyukov Reviewed By: dvyukov CC: llvm-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1937 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@192774 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/interception/interception.h | 6 ++ lib/interception/interception_linux.h | 9 ++- lib/interception/interception_mac.h | 1 + lib/interception/interception_win.h | 3 + lib/msan/tests/msan_test.cc | 33 +++++++++++ .../sanitizer_common_interceptors.inc | 69 +++++++++++++++++++++- .../sanitizer_platform_interceptors.h | 3 + .../sanitizer_platform_limits_posix.cc | 1 + .../sanitizer_platform_limits_posix.h | 1 + lib/tsan/rtl/tsan_interceptors.cc | 42 ++----------- 10 files changed, 127 insertions(+), 41 deletions(-) diff --git a/lib/interception/interception.h b/lib/interception/interception.h index cc8d7b0d..baddd6c1 100644 --- a/lib/interception/interception.h +++ b/lib/interception/interception.h @@ -238,12 +238,18 @@ typedef unsigned long uptr; // NOLINT #if defined(__linux__) # include "interception_linux.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX(func) +# define INTERCEPT_FUNCTION_VER(func, symver) \ + INTERCEPT_FUNCTION_VER_LINUX(func, symver) #elif defined(__APPLE__) # include "interception_mac.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func) +# define INTERCEPT_FUNCTION_VER(func, symver) \ + INTERCEPT_FUNCTION_VER_MAC(func, symver) #else // defined(_WIN32) # include "interception_win.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_WIN(func) +# define INTERCEPT_FUNCTION_VER(func, symver) \ + INTERCEPT_FUNCTION_VER_WIN(func, symver) #endif #undef INCLUDED_FROM_INTERCEPTION_LIB diff --git a/lib/interception/interception_linux.h b/lib/interception/interception_linux.h index 8f7a706f..b2f74d10 100644 --- a/lib/interception/interception_linux.h +++ b/lib/interception/interception_linux.h @@ -35,9 +35,12 @@ void *GetFuncAddrVer(const char *func_name, const char *ver); (::__interception::uptr)&WRAP(func)) #if !defined(__ANDROID__) // android does not have dlvsym -#define INTERCEPT_FUNCTION_VER(func, symver) \ - ::__interception::real_##func = (func##_f)(unsigned long) \ - ::__interception::GetFuncAddrVer(#func, #symver) +# define INTERCEPT_FUNCTION_VER_LINUX(func, symver) \ + ::__interception::real_##func = (func##_f)(unsigned long) \ + ::__interception::GetFuncAddrVer(#func, #symver) +#else +# define INTERCEPT_FUNCTION_VER_LINUX(func, symver) \ + INTERCEPT_FUNCTION_LINUX(func) #endif // !defined(__ANDROID__) #endif // INTERCEPTION_LINUX_H diff --git a/lib/interception/interception_mac.h b/lib/interception/interception_mac.h index 50594898..e5a35c69 100644 --- a/lib/interception/interception_mac.h +++ b/lib/interception/interception_mac.h @@ -22,6 +22,7 @@ #define INTERCEPTION_MAC_H #define INTERCEPT_FUNCTION_MAC(func) +#define INTERCEPT_FUNCTION_VER_MAC(func, symver) #endif // INTERCEPTION_MAC_H #endif // __APPLE__ diff --git a/lib/interception/interception_win.h b/lib/interception/interception_win.h index c64af1ba..f2727c92 100644 --- a/lib/interception/interception_win.h +++ b/lib/interception/interception_win.h @@ -41,5 +41,8 @@ bool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func); (::__interception::uptr*)&REAL(func)) #endif +#define INTERCEPT_FUNCTION_VER_WIN(func, symver) \ + INTERCEPT_FUNCTION_WIN(func) + #endif // INTERCEPTION_WIN_H #endif // _WIN32 diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index 1ef769d0..385d6565 100644 --- a/lib/msan/tests/msan_test.cc +++ b/lib/msan/tests/msan_test.cc @@ -2309,6 +2309,39 @@ TEST(MemorySanitizer, pthread_key_create) { assert(!res); } +namespace { +struct SignalCondArg { + pthread_cond_t* cond; + pthread_mutex_t* mu; +}; + +void *SignalCond(void *param) { + SignalCondArg *arg = reinterpret_cast(param); + pthread_mutex_lock(arg->mu); + pthread_cond_signal(arg->cond); + pthread_mutex_unlock(arg->mu); + return 0; +} +} // namespace + +TEST(MemorySanitizer, pthread_cond_wait) { + pthread_cond_t cond; + pthread_mutex_t mu; + SignalCondArg args = {&cond, &mu}; + pthread_cond_init(&cond, 0); + pthread_mutex_init(&mu, 0); + + pthread_mutex_lock(&mu); + pthread_t thr; + pthread_create(&thr, 0, SignalCond, &args); + int res = pthread_cond_wait(&cond, &mu); + assert(!res); + pthread_join(thr, 0); + pthread_mutex_unlock(&mu); + pthread_mutex_destroy(&mu); + pthread_cond_destroy(&cond); +} + TEST(MemorySanitizer, posix_memalign) { void *p; EXPECT_POISONED(p); diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 04c61efd..11195ca3 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -21,6 +21,8 @@ // COMMON_INTERCEPTOR_FD_ACCESS // COMMON_INTERCEPTOR_SET_THREAD_NAME // COMMON_INTERCEPTOR_ON_EXIT +// COMMON_INTERCEPTOR_MUTEX_LOCK +// COMMON_INTERCEPTOR_MUTEX_UNLOCK //===----------------------------------------------------------------------===// #include "interception/interception.h" #include "sanitizer_platform_interceptors.h" @@ -32,11 +34,19 @@ #endif // _WIN32 #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE -# define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) +#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) #endif #ifndef COMMON_INTERCEPTOR_FD_ACCESS -# define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) +#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) +#endif + +#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK +#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) +#endif + +#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK +#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) #endif #if SANITIZER_INTERCEPT_STRCMP @@ -2191,6 +2201,57 @@ INTERCEPTOR(void, _exit, int status) { #define INIT__EXIT #endif +#if SANITIZER_INTERCEPT_PHTREAD_MUTEX +INTERCEPTOR(int, pthread_mutex_lock, void *m) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); + int res = REAL(pthread_mutex_lock)(m); + if (res == 0) + COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); + return res; +} + +INTERCEPTOR(int, pthread_mutex_unlock, void *m) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); + COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); + return REAL(pthread_mutex_unlock)(m); +} + +#define INIT_PTHREAD_MUTEX_LOCK INTERCEPT_FUNCTION(pthread_mutex_lock) +#define INIT_PTHREAD_MUTEX_UNLOCK INTERCEPT_FUNCTION(pthread_mutex_unlock) +#else +#define INIT_PTHREAD_MUTEX_LOCK +#define INIT_PTHREAD_MUTEX_UNLOCK +#endif + +#if SANITIZER_INTERCEPT_PTHREAD_COND +INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_wait, c, m); + COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); + COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); + int res = REAL(pthread_cond_wait)(c, m); + COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); + return res; +} + +INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_init, c, a); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, c, pthread_cond_t_sz); + return REAL(pthread_cond_init)(c, a); +} + +#define INIT_PTHREAD_COND_WAIT \ + INTERCEPT_FUNCTION_VER(pthread_cond_wait, GLIBC_2.3.2) +#define INIT_PTHREAD_COND_INIT \ + INTERCEPT_FUNCTION_VER(pthread_cond_init, GLIBC_2.3.2) +#else +#define INIT_PTHREAD_COND_WAIT +#define INIT_PTHREAD_COND_INIT +#endif + #define SANITIZER_COMMON_INTERCEPTORS_INIT \ INIT_STRCMP; \ INIT_STRNCMP; \ @@ -2269,4 +2330,8 @@ INTERCEPTOR(void, _exit, int status) { INIT_SIGPROCMASK; \ INIT_BACKTRACE; \ INIT__EXIT; \ + INIT_PTHREAD_MUTEX_LOCK; \ + INIT_PTHREAD_MUTEX_UNLOCK; \ + INIT_PTHREAD_COND_WAIT; \ + INIT_PTHREAD_COND_INIT; \ /**/ diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h index de352eb0..1c15b50b 100644 --- a/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -129,4 +129,7 @@ # define SANITIZER_INTERCEPT__EXIT SI_LINUX +# define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_NOT_WINDOWS +# define SANITIZER_INTERCEPT_PTHREAD_COND SI_NOT_WINDOWS + #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index 9cc975a0..67970471 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -124,6 +124,7 @@ namespace __sanitizer { unsigned struct_sigaction_sz = sizeof(struct sigaction); unsigned struct_itimerval_sz = sizeof(struct itimerval); unsigned pthread_t_sz = sizeof(pthread_t); + unsigned pthread_cond_t_sz = sizeof(pthread_cond_t); unsigned pid_t_sz = sizeof(pid_t); unsigned timeval_sz = sizeof(timeval); unsigned uid_t_sz = sizeof(uid_t); diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 41cdefe2..563a490b 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -28,6 +28,7 @@ namespace __sanitizer { extern unsigned siginfo_t_sz; extern unsigned struct_itimerval_sz; extern unsigned pthread_t_sz; + extern unsigned pthread_cond_t_sz; extern unsigned pid_t_sz; extern unsigned timeval_sz; extern unsigned uid_t_sz; diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index ecb4bbb8..d72fb94d 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -946,15 +946,6 @@ TSAN_INTERCEPTOR(int, pthread_mutex_destroy, void *m) { return res; } -TSAN_INTERCEPTOR(int, pthread_mutex_lock, void *m) { - SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock, m); - int res = REAL(pthread_mutex_lock)(m); - if (res == 0) { - MutexLock(thr, pc, (uptr)m); - } - return res; -} - TSAN_INTERCEPTOR(int, pthread_mutex_trylock, void *m) { SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock, m); int res = REAL(pthread_mutex_trylock)(m); @@ -973,13 +964,6 @@ TSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) { return res; } -TSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) { - SCOPED_TSAN_INTERCEPTOR(pthread_mutex_unlock, m); - MutexUnlock(thr, pc, (uptr)m); - int res = REAL(pthread_mutex_unlock)(m); - return res; -} - TSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) { SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared); int res = REAL(pthread_spin_init)(m, pshared); @@ -1102,13 +1086,6 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_unlock, void *m) { return res; } -TSAN_INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { - SCOPED_TSAN_INTERCEPTOR(pthread_cond_init, c, a); - MemoryWrite(thr, pc, (uptr)c, kSizeLog1); - int res = REAL(pthread_cond_init)(c, a); - return res; -} - TSAN_INTERCEPTOR(int, pthread_cond_destroy, void *c) { SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy, c); MemoryWrite(thr, pc, (uptr)c, kSizeLog1); @@ -1130,15 +1107,6 @@ TSAN_INTERCEPTOR(int, pthread_cond_broadcast, void *c) { return res; } -TSAN_INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { - SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait, c, m); - MutexUnlock(thr, pc, (uptr)m); - MemoryRead(thr, pc, (uptr)c, kSizeLog1); - int res = REAL(pthread_cond_wait)(c, m); - MutexLock(thr, pc, (uptr)m); - return res; -} - TSAN_INTERCEPTOR(int, pthread_cond_timedwait, void *c, void *m, void *abstime) { SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait, c, m, abstime); @@ -1910,6 +1878,12 @@ struct TsanInterceptorContext { #define COMMON_INTERCEPTOR_BLOCK_REAL(name) BLOCK_REAL(name) #define COMMON_INTERCEPTOR_ON_EXIT(ctx) \ OnExit(((TsanInterceptorContext *) ctx)->thr) +#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) \ + MutexLock(((TsanInterceptorContext *)ctx)->thr, \ + ((TsanInterceptorContext *)ctx)->pc, (uptr)m) +#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \ + MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \ + ((TsanInterceptorContext *)ctx)->pc, (uptr)m) #include "sanitizer_common/sanitizer_common_interceptors.inc" #define TSAN_SYSCALL() \ @@ -2097,10 +2071,8 @@ void InitializeInterceptors() { TSAN_INTERCEPT(pthread_mutex_init); TSAN_INTERCEPT(pthread_mutex_destroy); - TSAN_INTERCEPT(pthread_mutex_lock); TSAN_INTERCEPT(pthread_mutex_trylock); TSAN_INTERCEPT(pthread_mutex_timedlock); - TSAN_INTERCEPT(pthread_mutex_unlock); TSAN_INTERCEPT(pthread_spin_init); TSAN_INTERCEPT(pthread_spin_destroy); @@ -2118,11 +2090,9 @@ void InitializeInterceptors() { TSAN_INTERCEPT(pthread_rwlock_timedwrlock); TSAN_INTERCEPT(pthread_rwlock_unlock); - INTERCEPT_FUNCTION_VER(pthread_cond_init, GLIBC_2.3.2); INTERCEPT_FUNCTION_VER(pthread_cond_destroy, GLIBC_2.3.2); INTERCEPT_FUNCTION_VER(pthread_cond_signal, GLIBC_2.3.2); INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, GLIBC_2.3.2); - INTERCEPT_FUNCTION_VER(pthread_cond_wait, GLIBC_2.3.2); INTERCEPT_FUNCTION_VER(pthread_cond_timedwait, GLIBC_2.3.2); TSAN_INTERCEPT(pthread_barrier_init); -- cgit v1.2.3