[compiler-rt] r287026 - [tsan] Call pthread interceptors directly in TSan RTL unit tests

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 15 13:00:56 PST 2016


Author: kuba.brecka
Date: Tue Nov 15 15:00:55 2016
New Revision: 287026

URL: http://llvm.org/viewvc/llvm-project?rev=287026&view=rev
Log:
[tsan] Call pthread interceptors directly in TSan RTL unit tests

On Darwin, we're running the TSan unit tests without interceptors. To make sure TSan observes all the pthread events (thread creating, thread join, condvar signal, etc.) in tsan_posix.cc, we should call the pthread interceptors directly, as we already do in tsan_test_util_posix.cc. This fixes some flaky failures on Darwin bots.

Differential Revision: https://reviews.llvm.org/D26639


Added:
    compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix_util.h
Modified:
    compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix.cc
    compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_posix.cc

Modified: compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix.cc?rev=287026&r1=287025&r2=287026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix.cc (original)
+++ compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix.cc Tue Nov 15 15:00:55 2016
@@ -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);
 }

Added: compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix_util.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix_util.h?rev=287026&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix_util.h (added)
+++ compiler-rt/trunk/lib/tsan/tests/rtl/tsan_posix_util.h Tue Nov 15 15:00:55 2016
@@ -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

Modified: compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_posix.cc?rev=287026&r1=287025&r2=287026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_posix.cc (original)
+++ compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_posix.cc Tue Nov 15 15:00:55 2016
@@ -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;




More information about the llvm-commits mailing list