diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -23,10 +23,6 @@ // COMMON_INTERCEPTOR_SET_THREAD_NAME // COMMON_INTERCEPTOR_DLOPEN // COMMON_INTERCEPTOR_ON_EXIT -// COMMON_INTERCEPTOR_MUTEX_PRE_LOCK -// COMMON_INTERCEPTOR_MUTEX_POST_LOCK -// COMMON_INTERCEPTOR_MUTEX_UNLOCK -// COMMON_INTERCEPTOR_MUTEX_REPAIR // COMMON_INTERCEPTOR_SET_PTHREAD_NAME // COMMON_INTERCEPTOR_HANDLE_RECVMSG // COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED @@ -223,26 +219,6 @@ #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {} #endif -#ifndef COMMON_INTERCEPTOR_MUTEX_PRE_LOCK -#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) {} -#endif - -#ifndef COMMON_INTERCEPTOR_MUTEX_POST_LOCK -#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) {} -#endif - -#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK -#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {} -#endif - -#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR -#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {} -#endif - -#ifndef COMMON_INTERCEPTOR_MUTEX_INVALID -#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {} -#endif - #ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg)) #endif @@ -4475,90 +4451,13 @@ #define INIT__EXIT #endif -#if SANITIZER_INTERCEPT_PTHREAD_MUTEX -INTERCEPTOR(int, pthread_mutex_lock, void *m) { - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); - COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m); - int res = REAL(pthread_mutex_lock)(m); - if (res == errno_EOWNERDEAD) - COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m); - if (res == 0 || res == errno_EOWNERDEAD) - COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m); - if (res == errno_EINVAL) - COMMON_INTERCEPTOR_MUTEX_INVALID(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); - int res = REAL(pthread_mutex_unlock)(m); - if (res == errno_EINVAL) - COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); - return res; -} - -#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock) -#define INIT_PTHREAD_MUTEX_UNLOCK \ - COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock) -#else -#define INIT_PTHREAD_MUTEX_LOCK -#define INIT_PTHREAD_MUTEX_UNLOCK -#endif - -#if SANITIZER_INTERCEPT___PTHREAD_MUTEX -INTERCEPTOR(int, __pthread_mutex_lock, void *m) { - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_lock, m); - COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m); - int res = REAL(__pthread_mutex_lock)(m); - if (res == errno_EOWNERDEAD) - COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m); - if (res == 0 || res == errno_EOWNERDEAD) - COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m); - if (res == errno_EINVAL) - COMMON_INTERCEPTOR_MUTEX_INVALID(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); - int res = REAL(__pthread_mutex_unlock)(m); - if (res == errno_EINVAL) - COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); - return res; -} - -#define INIT___PTHREAD_MUTEX_LOCK \ - COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock) -#define INIT___PTHREAD_MUTEX_UNLOCK \ - COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock) -#else -#define INIT___PTHREAD_MUTEX_LOCK -#define INIT___PTHREAD_MUTEX_UNLOCK -#endif - #if SANITIZER_INTERCEPT___LIBC_MUTEX -INTERCEPTOR(int, __libc_mutex_lock, void *m) -ALIAS(WRAPPER_NAME(pthread_mutex_lock)); - -INTERCEPTOR(int, __libc_mutex_unlock, void *m) -ALIAS(WRAPPER_NAME(pthread_mutex_unlock)); - INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate) ALIAS(WRAPPER_NAME(pthread_setcancelstate)); -#define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock) -#define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock) #define INIT___LIBC_THR_SETCANCELSTATE \ COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate) #else -#define INIT___LIBC_MUTEX_LOCK -#define INIT___LIBC_MUTEX_UNLOCK #define INIT___LIBC_THR_SETCANCELSTATE #endif @@ -10604,12 +10503,6 @@ INIT_PTHREAD_SIGMASK; INIT_BACKTRACE; INIT__EXIT; - INIT_PTHREAD_MUTEX_LOCK; - INIT_PTHREAD_MUTEX_UNLOCK; - INIT___PTHREAD_MUTEX_LOCK; - INIT___PTHREAD_MUTEX_UNLOCK; - INIT___LIBC_MUTEX_LOCK; - INIT___LIBC_MUTEX_UNLOCK; INIT___LIBC_THR_SETCANCELSTATE; INIT_GETMNTENT; INIT_GETMNTENT_R; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -396,8 +396,6 @@ #define SANITIZER_INTERCEPT__EXIT \ (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC || SI_SOLARIS) -#define SANITIZER_INTERCEPT_PTHREAD_MUTEX SI_POSIX -#define SANITIZER_INTERCEPT___PTHREAD_MUTEX SI_GLIBC #define SANITIZER_INTERCEPT___LIBC_MUTEX SI_NETBSD #define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \ (SI_FREEBSD || SI_NETBSD || SI_GLIBC || SI_SOLARIS) diff --git a/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_posix.cpp --- a/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_posix.cpp @@ -1333,6 +1333,19 @@ return res; } +TSAN_INTERCEPTOR(int, pthread_mutex_lock, void *m) { + SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock, m); + MutexPreLock(thr, pc, (uptr)m); + int res = REAL(pthread_mutex_lock)(m); + if (res == errno_EOWNERDEAD) + MutexRepair(thr, pc, (uptr)m); + if (res == 0 || res == errno_EOWNERDEAD) + MutexPostLock(thr, pc, (uptr)m); + if (res == errno_EINVAL) + MutexInvalidAccess(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); @@ -1354,6 +1367,15 @@ } #endif +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); + if (res == errno_EINVAL) + MutexInvalidAccess(thr, pc, (uptr)m); + return res; +} + #if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) { SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared); @@ -2427,26 +2449,6 @@ #define COMMON_INTERCEPTOR_ON_EXIT(ctx) \ OnExit(((TsanInterceptorContext *) ctx)->thr) -#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) \ - MutexPreLock(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - -#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) \ - MutexPostLock(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - -#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \ - MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - -#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) \ - MutexRepair(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - -#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) \ - MutexInvalidAccess(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - #define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ off) \ do { \ @@ -2825,8 +2827,10 @@ 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); diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -1353,6 +1353,19 @@ return res; } +TSAN_INTERCEPTOR(int, pthread_mutex_lock, void *m) { + SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock, m); + MutexPreLock(thr, pc, (uptr)m); + int res = REAL(pthread_mutex_lock)(m); + if (res == errno_EOWNERDEAD) + MutexRepair(thr, pc, (uptr)m); + if (res == 0 || res == errno_EOWNERDEAD) + MutexPostLock(thr, pc, (uptr)m); + if (res == errno_EINVAL) + MutexInvalidAccess(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); @@ -1374,6 +1387,43 @@ } #endif +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); + if (res == errno_EINVAL) + MutexInvalidAccess(thr, pc, (uptr)m); + return res; +} + +#if SANITIZER_GLIBC +# if !__GLIBC_PREREQ(2, 34) +// glibc 2.34 applies a non-default version for the two functions. They are no +// longer expected to be intercepted by programs. +TSAN_INTERCEPTOR(int, __pthread_mutex_lock, void *m) { + SCOPED_TSAN_INTERCEPTOR(__pthread_mutex_lock, m); + MutexPreLock(thr, pc, (uptr)m); + int res = REAL(__pthread_mutex_lock)(m); + if (res == errno_EOWNERDEAD) + MutexRepair(thr, pc, (uptr)m); + if (res == 0 || res == errno_EOWNERDEAD) + MutexPostLock(thr, pc, (uptr)m); + if (res == errno_EINVAL) + MutexInvalidAccess(thr, pc, (uptr)m); + 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); + if (res == errno_EINVAL) + MutexInvalidAccess(thr, pc, (uptr)m); + return res; +} +# endif +#endif + #if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) { SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared); @@ -2470,26 +2520,6 @@ #define COMMON_INTERCEPTOR_ON_EXIT(ctx) \ OnExit(((TsanInterceptorContext *) ctx)->thr) -#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) \ - MutexPreLock(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - -#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) \ - MutexPostLock(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - -#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \ - MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - -#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) \ - MutexRepair(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - -#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) \ - MutexInvalidAccess(((TsanInterceptorContext *)ctx)->thr, \ - ((TsanInterceptorContext *)ctx)->pc, (uptr)m) - #define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ off) \ do { \ @@ -2786,7 +2816,9 @@ TSAN_INTERCEPTOR_NETBSD_ALIAS(int, cond_destroy, void *c) TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_init, void *m, void *a) TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_destroy, void *m) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_lock, void *m) TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_trylock, void *m) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_unlock, void *m) TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_init, void *m, void *a) TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_destroy, void *m) TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_rdlock, void *m) @@ -2888,8 +2920,16 @@ 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); +#if SANITIZER_GLIBC +# if !__GLIBC_PREREQ(2, 34) + TSAN_INTERCEPT(__pthread_mutex_lock); + TSAN_INTERCEPT(__pthread_mutex_unlock); +# endif +#endif TSAN_INTERCEPT(pthread_spin_init); TSAN_INTERCEPT(pthread_spin_destroy); @@ -3034,7 +3074,9 @@ TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(cond_destroy); TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_init); TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_destroy); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_lock); TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_trylock); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_unlock); TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_init); TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_destroy); TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_rdlock);