diff options
10 files changed, 127 insertions, 41 deletions
diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index cc8d7b0d249..baddd6c132c 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/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/compiler-rt/lib/interception/interception_linux.h b/compiler-rt/lib/interception/interception_linux.h index 8f7a706fcf4..b2f74d105eb 100644 --- a/compiler-rt/lib/interception/interception_linux.h +++ b/compiler-rt/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/compiler-rt/lib/interception/interception_mac.h b/compiler-rt/lib/interception/interception_mac.h index 5059489831e..e5a35c6971c 100644 --- a/compiler-rt/lib/interception/interception_mac.h +++ b/compiler-rt/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/compiler-rt/lib/interception/interception_win.h b/compiler-rt/lib/interception/interception_win.h index c64af1baffe..f2727c9241d 100644 --- a/compiler-rt/lib/interception/interception_win.h +++ b/compiler-rt/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/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc index 1ef769d0daf..385d6565250 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cc +++ b/compiler-rt/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<SignalCondArg *>(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/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 04c61efdb98..11195ca36a4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/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/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index de352eb009d..1c15b50ba98 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/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/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index 9cc975a0ab9..67970471abb 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/compiler-rt/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/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 41cdefe2c32..563a490bd87 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/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/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index ecb4bbb8779..d72fb94db44 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/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);  | 

