[compiler-rt] r252731 - [tsan] Add TSan unit test support for OS X

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 11 06:53:57 PST 2015


Author: kuba.brecka
Date: Wed Nov 11 08:53:57 2015
New Revision: 252731

URL: http://llvm.org/viewvc/llvm-project?rev=252731&view=rev
Log:
[tsan] Add TSan unit test support for OS X

This patch enables building and running TSan unit tests on OS X.

Differential Revision: http://reviews.llvm.org/D14546


Modified:
    compiler-rt/trunk/cmake/Modules/CompilerRTCompile.cmake
    compiler-rt/trunk/cmake/config-ix.cmake
    compiler-rt/trunk/lib/tsan/CMakeLists.txt
    compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt
    compiler-rt/trunk/lib/tsan/tests/rtl/CMakeLists.txt
    compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test.cc
    compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util.h
    compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_linux.cc
    compiler-rt/trunk/lib/tsan/tests/unit/tsan_clock_test.cc

Modified: compiler-rt/trunk/cmake/Modules/CompilerRTCompile.cmake
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/Modules/CompilerRTCompile.cmake?rev=252731&r1=252730&r2=252731&view=diff
==============================================================================
--- compiler-rt/trunk/cmake/Modules/CompilerRTCompile.cmake (original)
+++ compiler-rt/trunk/cmake/Modules/CompilerRTCompile.cmake Wed Nov 11 08:53:57 2015
@@ -24,19 +24,6 @@ function(translate_msvc_cflags out_flags
   set(${out_flags} "${clang_flags}" PARENT_SCOPE)
 endfunction()
 
-if (APPLE)
-  # On Darwin if /usr/include doesn't exist, the user probably has Xcode but not
-  # the command line tools. If this is the case, we need to find the OS X
-  # sysroot to pass to clang.
-  if(NOT EXISTS /usr/include)
-    execute_process(COMMAND xcodebuild -version -sdk macosx Path
-       OUTPUT_VARIABLE OSX_SYSROOT
-       ERROR_QUIET
-       OUTPUT_STRIP_TRAILING_WHITESPACE)
-    set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}")
-  endif()
-endif()
-
 # Compile a source into an object file with COMPILER_RT_TEST_COMPILER using
 # a provided compile flags and dependenices.
 # clang_compile(<object> <source>

Modified: compiler-rt/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/config-ix.cmake?rev=252731&r1=252730&r2=252731&view=diff
==============================================================================
--- compiler-rt/trunk/cmake/config-ix.cmake (original)
+++ compiler-rt/trunk/cmake/config-ix.cmake Wed Nov 11 08:53:57 2015
@@ -279,6 +279,17 @@ set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86}
 if(APPLE)
   include(CompilerRTDarwinUtils)
 
+  # On Darwin if /usr/include doesn't exist, the user probably has Xcode but not
+  # the command line tools. If this is the case, we need to find the OS X
+  # sysroot to pass to clang.
+  if(NOT EXISTS /usr/include)
+    execute_process(COMMAND xcodebuild -version -sdk macosx Path
+       OUTPUT_VARIABLE OSX_SYSROOT
+       ERROR_QUIET
+       OUTPUT_STRIP_TRAILING_WHITESPACE)
+    set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}")
+  endif()
+
   option(COMPILER_RT_ENABLE_IOS "Enable building for iOS - Experimental" Off)
 
   find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx)

Modified: compiler-rt/trunk/lib/tsan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/CMakeLists.txt?rev=252731&r1=252730&r2=252731&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/tsan/CMakeLists.txt Wed Nov 11 08:53:57 2015
@@ -87,6 +87,12 @@ set(TSAN_HEADERS
 set(TSAN_RUNTIME_LIBRARIES)
 add_custom_target(tsan)
 
+add_compiler_rt_object_libraries(RTTsan_dynamic 
+  OS ${TSAN_SUPPORTED_OS}
+  ARCHS ${TSAN_SUPPORTED_ARCH}
+  SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES}
+  CFLAGS ${TSAN_RTL_CFLAGS})
+
 if(APPLE)
   add_compiler_rt_runtime(clang_rt.tsan
     SHARED

Modified: compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt?rev=252731&r1=252730&r2=252731&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt Wed Nov 11 08:53:57 2015
@@ -33,8 +33,7 @@ macro(tsan_compile obj_list source arch)
 endmacro()
 
 macro(add_tsan_unittest testname)
-  # Build unit tests only for 64-bit Linux.
-  if(UNIX AND NOT APPLE)
+  if(UNIX)
     foreach(arch ${TSAN_SUPPORTED_ARCH})
       cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN})
       set(TEST_OBJECTS)
@@ -46,15 +45,38 @@ macro(add_tsan_unittest testname)
       if(NOT COMPILER_RT_STANDALONE_BUILD)
         list(APPEND TEST_DEPS tsan)
       endif()
-      # FIXME: Looks like we should link TSan with just-built runtime,
-      # and not rely on -fsanitize=thread, as these tests are essentially
-      # unit tests.
-      add_compiler_rt_test(TsanUnitTests ${testname}
-              OBJECTS ${TEST_OBJECTS}
-              DEPS ${TEST_DEPS}
-              LINK_FLAGS ${TARGET_LINK_FLAGS}
-                         -fsanitize=thread
-                         -lstdc++ -lm)
+      if(NOT APPLE)
+        # FIXME: Looks like we should link TSan with just-built runtime,
+        # and not rely on -fsanitize=thread, as these tests are essentially
+        # unit tests.
+        add_compiler_rt_test(TsanUnitTests ${testname}
+                OBJECTS ${TEST_OBJECTS}
+                DEPS ${TEST_DEPS}
+                LINK_FLAGS ${TARGET_LINK_FLAGS}
+                           -fsanitize=thread
+                           -lstdc++ -lm)
+      else()
+        set(TSAN_TEST_RUNTIME_OBJECTS
+          $<TARGET_OBJECTS:RTTsan_dynamic.osx>
+          $<TARGET_OBJECTS:RTInterception.osx>
+          $<TARGET_OBJECTS:RTSanitizerCommon.osx>
+          $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
+          $<TARGET_OBJECTS:RTUbsan.osx>)
+        set(TSAN_TEST_RUNTIME RTTsanTest.${testname}.${arch})
+        add_library(${TSAN_TEST_RUNTIME} STATIC ${TSAN_TEST_RUNTIME_OBJECTS})
+        set_target_properties(${TSAN_TEST_RUNTIME} PROPERTIES
+          ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+        list(APPEND TEST_OBJECTS lib${TSAN_TEST_RUNTIME}.a)
+        list(APPEND TEST_DEPS ${TSAN_TEST_RUNTIME})
+        # Intentionally do *not* link with `-fsanitize=thread`. We already link
+        # against a static version of the runtime, and we don't want the dynamic
+        # one.
+        add_compiler_rt_test(TsanUnitTests "${testname}-${arch}-Test"
+                OBJECTS ${TEST_OBJECTS}
+                DEPS ${TEST_DEPS}
+                LINK_FLAGS ${TARGET_LINK_FLAGS}
+                           -lc++)
+      endif()
     endforeach()
   endif()
 endmacro()

Modified: compiler-rt/trunk/lib/tsan/tests/rtl/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/rtl/CMakeLists.txt?rev=252731&r1=252730&r2=252731&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/rtl/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/tsan/tests/rtl/CMakeLists.txt Wed Nov 11 08:53:57 2015
@@ -7,7 +7,7 @@ set(TSAN_RTL_TEST_SOURCES
   tsan_test.cc
   tsan_thread.cc)
 
-if(UNIX AND NOT APPLE)
+if(UNIX)
   list(APPEND TSAN_RTL_TEST_SOURCES tsan_test_util_linux.cc)
 endif()
 

Modified: compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test.cc?rev=252731&r1=252730&r2=252731&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test.cc (original)
+++ compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test.cc Wed Nov 11 08:53:57 2015
@@ -47,6 +47,13 @@ int run_tests(int argc, char **argv) {
 
 const char *argv0;
 
+#ifdef __APPLE__
+// On Darwin, turns off symbolication and crash logs to make tests faster.
+extern "C" const char* __tsan_default_options() {
+  return "symbolize=false:abort_on_error=0";
+}
+#endif
+
 int main(int argc, char **argv) {
   argv0 = argv[0];
   return run_tests(argc, argv);

Modified: compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util.h?rev=252731&r1=252730&r2=252731&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util.h (original)
+++ compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util.h Wed Nov 11 08:53:57 2015
@@ -31,7 +31,15 @@ class MemLoc {
 
 class Mutex {
  public:
-  enum Type { Normal, Spin, RW };
+  enum Type {
+    Normal,
+    RW,
+#ifndef APPLE
+    Spin
+#else
+    Spin = Normal
+#endif
+  };
 
   explicit Mutex(Type type = Normal);
   ~Mutex();

Modified: compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_linux.cc?rev=252731&r1=252730&r2=252731&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_linux.cc (original)
+++ compiler-rt/trunk/lib/tsan/tests/rtl/tsan_test_util_linux.cc Wed Nov 11 08:53:57 2015
@@ -1,4 +1,3 @@
-
 //===-- tsan_test_util_linux.cc -------------------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
@@ -10,7 +9,7 @@
 //
 // This file is a part of ThreadSanitizer (TSan), a race detector.
 //
-// Test utils, Linux and FreeBSD implementation.
+// Test utils, Linux, FreeBSD and Darwin implementation.
 //===----------------------------------------------------------------------===//
 
 #include "sanitizer_common/sanitizer_atomic.h"
@@ -34,8 +33,20 @@ static __thread bool expect_report;
 static __thread bool expect_report_reported;
 static __thread ReportType expect_report_type;
 
-extern "C" void *__interceptor_memcpy(void*, const void*, uptr);
-extern "C" void *__interceptor_memset(void*, int, uptr);
+#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
+#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);
 
 static void *BeforeInitThread(void *param) {
   (void)param;
@@ -52,8 +63,8 @@ void TestMutexBeforeInit() {
   pthread_mutex_unlock(&mtx);
   pthread_mutex_destroy(&mtx);
   pthread_t thr;
-  pthread_create(&thr, 0, BeforeInitThread, 0);
-  pthread_join(thr, 0);
+  __interceptor_pthread_create(&thr, 0, BeforeInitThread, 0);
+  __interceptor_pthread_join(thr, 0);
   atexit(AtExit);
 }
 
@@ -106,8 +117,10 @@ void Mutex::Init() {
   alive_ = true;
   if (type_ == Normal)
     CHECK_EQ(pthread_mutex_init((pthread_mutex_t*)mtx_, 0), 0);
+#ifndef __APPLE__
   else if (type_ == Spin)
     CHECK_EQ(pthread_spin_init((pthread_spinlock_t*)mtx_, 0), 0);
+#endif
   else if (type_ == RW)
     CHECK_EQ(pthread_rwlock_init((pthread_rwlock_t*)mtx_, 0), 0);
   else
@@ -127,8 +140,10 @@ void Mutex::Destroy() {
   alive_ = false;
   if (type_ == Normal)
     CHECK_EQ(pthread_mutex_destroy((pthread_mutex_t*)mtx_), 0);
+#ifndef __APPLE__
   else if (type_ == Spin)
     CHECK_EQ(pthread_spin_destroy((pthread_spinlock_t*)mtx_), 0);
+#endif
   else if (type_ == RW)
     CHECK_EQ(pthread_rwlock_destroy((pthread_rwlock_t*)mtx_), 0);
 }
@@ -137,8 +152,10 @@ void Mutex::Lock() {
   CHECK(alive_);
   if (type_ == Normal)
     CHECK_EQ(pthread_mutex_lock((pthread_mutex_t*)mtx_), 0);
+#ifndef __APPLE__
   else if (type_ == Spin)
     CHECK_EQ(pthread_spin_lock((pthread_spinlock_t*)mtx_), 0);
+#endif
   else if (type_ == RW)
     CHECK_EQ(pthread_rwlock_wrlock((pthread_rwlock_t*)mtx_), 0);
 }
@@ -147,8 +164,10 @@ bool Mutex::TryLock() {
   CHECK(alive_);
   if (type_ == Normal)
     return pthread_mutex_trylock((pthread_mutex_t*)mtx_) == 0;
+#ifndef __APPLE__
   else if (type_ == Spin)
     return pthread_spin_trylock((pthread_spinlock_t*)mtx_) == 0;
+#endif
   else if (type_ == RW)
     return pthread_rwlock_trywrlock((pthread_rwlock_t*)mtx_) == 0;
   return false;
@@ -158,8 +177,10 @@ void Mutex::Unlock() {
   CHECK(alive_);
   if (type_ == Normal)
     CHECK_EQ(pthread_mutex_unlock((pthread_mutex_t*)mtx_), 0);
+#ifndef __APPLE__
   else if (type_ == Spin)
     CHECK_EQ(pthread_spin_unlock((pthread_spinlock_t*)mtx_), 0);
+#endif
   else if (type_ == RW)
     CHECK_EQ(pthread_rwlock_unlock((pthread_rwlock_t*)mtx_), 0);
 }
@@ -263,7 +284,7 @@ void ScopedThread::Impl::HandleEvent(Eve
       }
     }
     CHECK_NE(tsan_mop, 0);
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__APPLE__)
     const int ErrCode = ESOCKTNOSUPPORT;
 #else
     const int ErrCode = ECHRNG;
@@ -327,7 +348,7 @@ void *ScopedThread::Impl::ScopedThreadCa
   for (;;) {
     Event* ev = (Event*)atomic_load(&impl->event, memory_order_acquire);
     if (ev == 0) {
-      pthread_yield();
+      sched_yield();
       continue;
     }
     if (ev->type == Event::SHUTDOWN) {
@@ -348,7 +369,7 @@ void ScopedThread::Impl::send(Event *e)
     CHECK_EQ(atomic_load(&event, memory_order_relaxed), 0);
     atomic_store(&event, (uintptr_t)e, memory_order_release);
     while (atomic_load(&event, memory_order_acquire) != 0)
-      pthread_yield();
+      sched_yield();
   }
 }
 
@@ -362,7 +383,7 @@ ScopedThread::ScopedThread(bool detached
     pthread_attr_init(&attr);
     pthread_attr_setdetachstate(&attr, detached);
     pthread_attr_setstacksize(&attr, 64*1024);
-    pthread_create(&impl_->thread, &attr,
+    __interceptor_pthread_create(&impl_->thread, &attr,
         ScopedThread::Impl::ScopedThreadCallback, impl_);
   }
 }
@@ -372,7 +393,7 @@ ScopedThread::~ScopedThread() {
     Event event(Event::SHUTDOWN);
     impl_->send(&event);
     if (!impl_->detached)
-      pthread_join(impl_->thread, 0);
+      __interceptor_pthread_join(impl_->thread, 0);
   }
   delete impl_;
 }

Modified: compiler-rt/trunk/lib/tsan/tests/unit/tsan_clock_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/unit/tsan_clock_test.cc?rev=252731&r1=252730&r2=252731&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/unit/tsan_clock_test.cc (original)
+++ compiler-rt/trunk/lib/tsan/tests/unit/tsan_clock_test.cc Wed Nov 11 08:53:57 2015
@@ -13,6 +13,7 @@
 #include "tsan_clock.h"
 #include "tsan_rtl.h"
 #include "gtest/gtest.h"
+#include <sys/time.h>
 #include <time.h>
 
 namespace __tsan {
@@ -416,9 +417,9 @@ static bool ClockFuzzer(bool printing) {
 }
 
 TEST(Clock, Fuzzer) {
-  timespec ts;
-  clock_gettime(CLOCK_MONOTONIC, &ts);
-  int seed = ts.tv_sec + ts.tv_nsec;
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  int seed = tv.tv_sec + tv.tv_usec;
   printf("seed=%d\n", seed);
   srand(seed);
   if (!ClockFuzzer(false)) {




More information about the llvm-commits mailing list