Index: lib/tsan/tests/rtl/tsan_posix.cc =================================================================== --- lib/tsan/tests/rtl/tsan_posix.cc +++ lib/tsan/tests/rtl/tsan_posix.cc @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// #include "tsan_interface.h" +#include "tsan_posix_util.h" #include "tsan_test_util.h" #include "gtest/gtest.h" #include @@ -30,10 +31,10 @@ static void thread_secific_dtor(void *v) { thread_key *k = (thread_key *)v; - EXPECT_EQ(pthread_mutex_lock(k->mtx), 0); + EXPECT_EQ(__interceptor_pthread_mutex_lock(k->mtx), 0); (*k->cnt)++; __tsan_write4(&k->cnt); - EXPECT_EQ(pthread_mutex_unlock(k->mtx), 0); + EXPECT_EQ(__interceptor_pthread_mutex_unlock(k->mtx), 0); if (k->val == 42) { // Okay. } else if (k->val == 43 || k->val == 44) { @@ -55,22 +56,22 @@ pthread_key_t key; EXPECT_EQ(pthread_key_create(&key, thread_secific_dtor), 0); pthread_mutex_t mtx; - EXPECT_EQ(pthread_mutex_init(&mtx, 0), 0); + EXPECT_EQ(__interceptor_pthread_mutex_init(&mtx, 0), 0); pthread_t th[3]; thread_key k1 = thread_key(key, &mtx, 42, &cnt); thread_key k2 = thread_key(key, &mtx, 43, &cnt); thread_key k3 = thread_key(key, &mtx, 44, &cnt); - EXPECT_EQ(pthread_create(&th[0], 0, dtors_thread, &k1), 0); - EXPECT_EQ(pthread_create(&th[1], 0, dtors_thread, &k2), 0); - EXPECT_EQ(pthread_join(th[0], 0), 0); - EXPECT_EQ(pthread_create(&th[2], 0, dtors_thread, &k3), 0); - EXPECT_EQ(pthread_join(th[1], 0), 0); - EXPECT_EQ(pthread_join(th[2], 0), 0); + EXPECT_EQ(__interceptor_pthread_create(&th[0], 0, dtors_thread, &k1), 0); + EXPECT_EQ(__interceptor_pthread_create(&th[1], 0, dtors_thread, &k2), 0); + EXPECT_EQ(__interceptor_pthread_join(th[0], 0), 0); + EXPECT_EQ(__interceptor_pthread_create(&th[2], 0, dtors_thread, &k3), 0); + EXPECT_EQ(__interceptor_pthread_join(th[1], 0), 0); + EXPECT_EQ(__interceptor_pthread_join(th[2], 0), 0); EXPECT_EQ(pthread_key_delete(key), 0); EXPECT_EQ(6, cnt); } -#ifndef __aarch64__ +#if !defined(__aarch64__) && !defined(__APPLE__) static __thread int local_var; static void *local_thread(void *p) { @@ -81,10 +82,10 @@ const int kThreads = 4; pthread_t th[kThreads]; for (int i = 0; i < kThreads; i++) - EXPECT_EQ(pthread_create(&th[i], 0, local_thread, + EXPECT_EQ(__interceptor_pthread_create(&th[i], 0, local_thread, (void*)((long)p - 1)), 0); // NOLINT for (int i = 0; i < kThreads; i++) - EXPECT_EQ(pthread_join(th[i], 0), 0); + EXPECT_EQ(__interceptor_pthread_join(th[i], 0), 0); return 0; } #endif @@ -92,7 +93,9 @@ TEST(Posix, ThreadLocalAccesses) { // The test is failing with high thread count for aarch64. // FIXME: track down the issue and re-enable the test. -#ifndef __aarch64__ +// On Darwin, we're running unit tests without interceptors and __thread is +// using malloc and free, which causes false data race reports. +#if !defined(__aarch64__) && !defined(__APPLE__) local_thread((void*)2); #endif } @@ -106,46 +109,46 @@ static void *cond_thread(void *p) { CondContext &ctx = *static_cast(p); - EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0); EXPECT_EQ(ctx.data, 0); ctx.data = 1; - EXPECT_EQ(pthread_cond_signal(&ctx.c), 0); - EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_cond_signal(&ctx.c), 0); + EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0); - EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0); while (ctx.data != 2) - EXPECT_EQ(pthread_cond_wait(&ctx.c, &ctx.m), 0); - EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_cond_wait(&ctx.c, &ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0); - EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0); ctx.data = 3; EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0); - EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0); return 0; } TEST(Posix, CondBasic) { CondContext ctx; - EXPECT_EQ(pthread_mutex_init(&ctx.m, 0), 0); - EXPECT_EQ(pthread_cond_init(&ctx.c, 0), 0); + EXPECT_EQ(__interceptor_pthread_mutex_init(&ctx.m, 0), 0); + EXPECT_EQ(__interceptor_pthread_cond_init(&ctx.c, 0), 0); ctx.data = 0; pthread_t th; - EXPECT_EQ(pthread_create(&th, 0, cond_thread, &ctx), 0); + EXPECT_EQ(__interceptor_pthread_create(&th, 0, cond_thread, &ctx), 0); - EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0); while (ctx.data != 1) - EXPECT_EQ(pthread_cond_wait(&ctx.c, &ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_cond_wait(&ctx.c, &ctx.m), 0); ctx.data = 2; - EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0); EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0); - EXPECT_EQ(pthread_mutex_lock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0); while (ctx.data != 3) - EXPECT_EQ(pthread_cond_wait(&ctx.c, &ctx.m), 0); - EXPECT_EQ(pthread_mutex_unlock(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_cond_wait(&ctx.c, &ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0); - EXPECT_EQ(pthread_join(th, 0), 0); - EXPECT_EQ(pthread_cond_destroy(&ctx.c), 0); - EXPECT_EQ(pthread_mutex_destroy(&ctx.m), 0); + EXPECT_EQ(__interceptor_pthread_join(th, 0), 0); + EXPECT_EQ(__interceptor_pthread_cond_destroy(&ctx.c), 0); + EXPECT_EQ(__interceptor_pthread_mutex_destroy(&ctx.m), 0); } Index: lib/tsan/tests/rtl/tsan_posix_util.h =================================================================== --- lib/tsan/tests/rtl/tsan_posix_util.h +++ lib/tsan/tests/rtl/tsan_posix_util.h @@ -0,0 +1,77 @@ +//===-- tsan_posix_util.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of ThreadSanitizer (TSan), a race detector. +// +// Test POSIX utils. +//===----------------------------------------------------------------------===// +#ifndef TSAN_POSIX_UTIL_H +#define TSAN_POSIX_UTIL_H + +#include + +#ifdef __APPLE__ +#define __interceptor_memcpy wrap_memcpy +#define __interceptor_memset wrap_memset +#define __interceptor_pthread_create wrap_pthread_create +#define __interceptor_pthread_join wrap_pthread_join +#define __interceptor_pthread_detach wrap_pthread_detach +#define __interceptor_pthread_mutex_init wrap_pthread_mutex_init +#define __interceptor_pthread_mutex_lock wrap_pthread_mutex_lock +#define __interceptor_pthread_mutex_unlock wrap_pthread_mutex_unlock +#define __interceptor_pthread_mutex_destroy wrap_pthread_mutex_destroy +#define __interceptor_pthread_mutex_trylock wrap_pthread_mutex_trylock +#define __interceptor_pthread_rwlock_init wrap_pthread_rwlock_init +#define __interceptor_pthread_rwlock_destroy wrap_pthread_rwlock_destroy +#define __interceptor_pthread_rwlock_trywrlock wrap_pthread_rwlock_trywrlock +#define __interceptor_pthread_rwlock_wrlock wrap_pthread_rwlock_wrlock +#define __interceptor_pthread_rwlock_unlock wrap_pthread_rwlock_unlock +#define __interceptor_pthread_rwlock_rdlock wrap_pthread_rwlock_rdlock +#define __interceptor_pthread_rwlock_tryrdlock wrap_pthread_rwlock_tryrdlock +#define __interceptor_pthread_cond_init wrap_pthread_cond_init +#define __interceptor_pthread_cond_signal wrap_pthread_cond_signal +#define __interceptor_pthread_cond_broadcast wrap_pthread_cond_broadcast +#define __interceptor_pthread_cond_wait wrap_pthread_cond_wait +#define __interceptor_pthread_cond_destroy wrap_pthread_cond_destroy +#endif + +extern "C" void *__interceptor_memcpy(void *, const void *, uptr); +extern "C" void *__interceptor_memset(void *, int, uptr); +extern "C" int __interceptor_pthread_create(pthread_t *thread, + const pthread_attr_t *attr, + void *(*start_routine)(void *), + void *arg); +extern "C" int __interceptor_pthread_join(pthread_t thread, void **value_ptr); +extern "C" int __interceptor_pthread_detach(pthread_t thread); + +extern "C" int __interceptor_pthread_mutex_init( + pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); +extern "C" int __interceptor_pthread_mutex_lock(pthread_mutex_t *mutex); +extern "C" int __interceptor_pthread_mutex_unlock(pthread_mutex_t *mutex); +extern "C" int __interceptor_pthread_mutex_destroy(pthread_mutex_t *mutex); +extern "C" int __interceptor_pthread_mutex_trylock(pthread_mutex_t *mutex); + +extern "C" int __interceptor_pthread_rwlock_init( + pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); +extern "C" int __interceptor_pthread_rwlock_destroy(pthread_rwlock_t *rwlock); +extern "C" int __interceptor_pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); +extern "C" int __interceptor_pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); +extern "C" int __interceptor_pthread_rwlock_unlock(pthread_rwlock_t *rwlock); +extern "C" int __interceptor_pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); +extern "C" int __interceptor_pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); + +extern "C" int __interceptor_pthread_cond_init(pthread_cond_t *cond, + const pthread_condattr_t *attr); +extern "C" int __interceptor_pthread_cond_signal(pthread_cond_t *cond); +extern "C" int __interceptor_pthread_cond_broadcast(pthread_cond_t *cond); +extern "C" int __interceptor_pthread_cond_wait(pthread_cond_t *cond, + pthread_mutex_t *mutex); +extern "C" int __interceptor_pthread_cond_destroy(pthread_cond_t *cond); + +#endif // #ifndef TSAN_POSIX_UTIL_H Index: lib/tsan/tests/rtl/tsan_test_util_posix.cc =================================================================== --- lib/tsan/tests/rtl/tsan_test_util_posix.cc +++ lib/tsan/tests/rtl/tsan_test_util_posix.cc @@ -14,6 +14,7 @@ #include "sanitizer_common/sanitizer_atomic.h" #include "tsan_interface.h" +#include "tsan_posix_util.h" #include "tsan_test_util.h" #include "tsan_report.h" @@ -33,52 +34,6 @@ static __thread bool expect_report_reported; static __thread ReportType expect_report_type; -#ifdef __APPLE__ -#define __interceptor_memcpy wrap_memcpy -#define __interceptor_memset wrap_memset -#define __interceptor_pthread_create wrap_pthread_create -#define __interceptor_pthread_join wrap_pthread_join -#define __interceptor_pthread_detach wrap_pthread_detach -#define __interceptor_pthread_mutex_init wrap_pthread_mutex_init -#define __interceptor_pthread_mutex_lock wrap_pthread_mutex_lock -#define __interceptor_pthread_mutex_unlock wrap_pthread_mutex_unlock -#define __interceptor_pthread_mutex_destroy wrap_pthread_mutex_destroy -#define __interceptor_pthread_mutex_trylock wrap_pthread_mutex_trylock -#define __interceptor_pthread_rwlock_init wrap_pthread_rwlock_init -#define __interceptor_pthread_rwlock_destroy wrap_pthread_rwlock_destroy -#define __interceptor_pthread_rwlock_trywrlock wrap_pthread_rwlock_trywrlock -#define __interceptor_pthread_rwlock_wrlock wrap_pthread_rwlock_wrlock -#define __interceptor_pthread_rwlock_unlock wrap_pthread_rwlock_unlock -#define __interceptor_pthread_rwlock_rdlock wrap_pthread_rwlock_rdlock -#define __interceptor_pthread_rwlock_tryrdlock wrap_pthread_rwlock_tryrdlock -#endif - -extern "C" void *__interceptor_memcpy(void *, const void *, uptr); -extern "C" void *__interceptor_memset(void *, int, uptr); -extern "C" int __interceptor_pthread_create(pthread_t *thread, - const pthread_attr_t *attr, - void *(*start_routine)(void *), - void *arg); -extern "C" int __interceptor_pthread_join(pthread_t thread, void **value_ptr); -extern "C" int __interceptor_pthread_detach(pthread_t thread); - -extern "C" int __interceptor_pthread_mutex_init( - pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); -extern "C" int __interceptor_pthread_mutex_lock(pthread_mutex_t *mutex); -extern "C" int __interceptor_pthread_mutex_unlock(pthread_mutex_t *mutex); -extern "C" int __interceptor_pthread_mutex_destroy(pthread_mutex_t *mutex); -extern "C" int __interceptor_pthread_mutex_trylock(pthread_mutex_t *mutex); - -extern "C" int __interceptor_pthread_rwlock_init( - pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); -extern "C" int __interceptor_pthread_rwlock_destroy(pthread_rwlock_t *rwlock); -extern "C" int __interceptor_pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); -extern "C" int __interceptor_pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); -extern "C" int __interceptor_pthread_rwlock_unlock(pthread_rwlock_t *rwlock); -extern "C" int __interceptor_pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); -extern "C" int __interceptor_pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); - - static void *BeforeInitThread(void *param) { (void)param; return 0;