summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2013-10-16 08:20:31 +0000
committerAlexey Samsonov <samsonov@google.com>2013-10-16 08:20:31 +0000
commit5e2d3776a314629680921abd1d55d89d95a2da90 (patch)
tree86524a10e4ad7c9d05e8006cb67f822f283c2a1a
parente852e41d345c4be4ca28962cbc6c6d59717759c7 (diff)
downloadcompiler-rt-5e2d3776a314629680921abd1d55d89d95a2da90.tar.gz
compiler-rt-5e2d3776a314629680921abd1d55d89d95a2da90.tar.bz2
compiler-rt-5e2d3776a314629680921abd1d55d89d95a2da90.tar.xz
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
-rw-r--r--lib/interception/interception.h6
-rw-r--r--lib/interception/interception_linux.h9
-rw-r--r--lib/interception/interception_mac.h1
-rw-r--r--lib/interception/interception_win.h3
-rw-r--r--lib/msan/tests/msan_test.cc33
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc69
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h3
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.cc1
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.h1
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc42
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<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/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);