summaryrefslogtreecommitdiff
path: root/lib/tsan/tests
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tsan/tests')
-rw-r--r--lib/tsan/tests/CMakeLists.txt6
-rw-r--r--lib/tsan/tests/rtl/tsan_posix.cc69
-rw-r--r--lib/tsan/tests/rtl/tsan_posix_util.h77
-rw-r--r--lib/tsan/tests/rtl/tsan_test_util_posix.cc53
-rw-r--r--lib/tsan/tests/unit/tsan_mman_test.cc8
5 files changed, 126 insertions, 87 deletions
diff --git a/lib/tsan/tests/CMakeLists.txt b/lib/tsan/tests/CMakeLists.txt
index d1b1e9611a78..4587e47ba904 100644
--- a/lib/tsan/tests/CMakeLists.txt
+++ b/lib/tsan/tests/CMakeLists.txt
@@ -12,6 +12,10 @@ set(TSAN_UNITTEST_CFLAGS
-I${COMPILER_RT_SOURCE_DIR}/lib/tsan/rtl
-DGTEST_HAS_RTTI=0)
+if(APPLE)
+ list(APPEND TSAN_UNITTEST_CFLAGS ${DARWIN_osx_CFLAGS})
+endif()
+
set(TSAN_RTL_HEADERS)
foreach (header ${TSAN_HEADERS})
list(APPEND TSAN_RTL_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
@@ -78,7 +82,7 @@ macro(add_tsan_unittest testname)
add_compiler_rt_test(TsanUnitTests "${testname}-${arch}-Test"
OBJECTS ${TEST_OBJECTS}
DEPS ${TEST_DEPS}
- LINK_FLAGS ${TARGET_LINK_FLAGS}
+ LINK_FLAGS ${TARGET_LINK_FLAGS} ${DARWIN_osx_LINKFLAGS}
-lc++)
endif()
endforeach()
diff --git a/lib/tsan/tests/rtl/tsan_posix.cc b/lib/tsan/tests/rtl/tsan_posix.cc
index e1a61b5e43f1..9c0e013e5735 100644
--- a/lib/tsan/tests/rtl/tsan_posix.cc
+++ b/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 <pthread.h>
@@ -30,10 +31,10 @@ struct thread_key {
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 @@ TEST(Posix, ThreadSpecificDtors) {
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 @@ static void *local_thread(void *p) {
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 @@ static void *local_thread(void *p) {
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 @@ struct CondContext {
static void *cond_thread(void *p) {
CondContext &ctx = *static_cast<CondContext*>(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);
}
diff --git a/lib/tsan/tests/rtl/tsan_posix_util.h b/lib/tsan/tests/rtl/tsan_posix_util.h
new file mode 100644
index 000000000000..340693ebb8a0
--- /dev/null
+++ b/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 <pthread.h>
+
+#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
diff --git a/lib/tsan/tests/rtl/tsan_test_util_posix.cc b/lib/tsan/tests/rtl/tsan_test_util_posix.cc
index c8be088d266f..834a271aa8c0 100644
--- a/lib/tsan/tests/rtl/tsan_test_util_posix.cc
+++ b/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;
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;
@@ -105,11 +60,11 @@ bool OnReport(const ReportDesc *rep, bool suppressed) {
if (rep->typ != expect_report_type) {
printf("Expected report of type %d, got type %d\n",
(int)expect_report_type, (int)rep->typ);
- EXPECT_FALSE("Wrong report type");
+ EXPECT_TRUE(false) << "Wrong report type";
return false;
}
} else {
- EXPECT_FALSE("Unexpected report");
+ EXPECT_TRUE(false) << "Unexpected report";
return false;
}
expect_report_reported = true;
@@ -368,7 +323,7 @@ void ScopedThread::Impl::HandleEvent(Event *ev) {
}
if (expect_report && !expect_report_reported) {
printf("Missed expected report of type %d\n", (int)ev->report_type);
- EXPECT_FALSE("Missed expected race");
+ EXPECT_TRUE(false) << "Missed expected race";
}
expect_report = false;
}
diff --git a/lib/tsan/tests/unit/tsan_mman_test.cc b/lib/tsan/tests/unit/tsan_mman_test.cc
index 609141c59294..60dea3d43240 100644
--- a/lib/tsan/tests/unit/tsan_mman_test.cc
+++ b/lib/tsan/tests/unit/tsan_mman_test.cc
@@ -53,9 +53,9 @@ TEST(Mman, UserRealloc) {
uptr pc = 0;
{
void *p = user_realloc(thr, pc, 0, 0);
- // Strictly saying this is incorrect, realloc(NULL, N) is equivalent to
- // malloc(N), thus must return non-NULL pointer.
- EXPECT_EQ(p, (void*)0);
+ // Realloc(NULL, N) is equivalent to malloc(N), thus must return
+ // non-NULL pointer.
+ EXPECT_NE(p, (void*)0);
}
{
void *p = user_realloc(thr, pc, 0, 100);
@@ -68,7 +68,7 @@ TEST(Mman, UserRealloc) {
EXPECT_NE(p, (void*)0);
memset(p, 0xde, 100);
void *p2 = user_realloc(thr, pc, p, 0);
- EXPECT_EQ(p2, (void*)0);
+ EXPECT_NE(p2, (void*)0);
}
{
void *p = user_realloc(thr, pc, 0, 100);