diff options
Diffstat (limited to 'lib/tsan/lit_tests')
102 files changed, 989 insertions, 154 deletions
diff --git a/lib/tsan/lit_tests/CMakeLists.txt b/lib/tsan/lit_tests/CMakeLists.txt index 53e5015d1bc4..1f2fbf98e080 100644 --- a/lib/tsan/lit_tests/CMakeLists.txt +++ b/lib/tsan/lit_tests/CMakeLists.txt @@ -8,7 +8,7 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg ) -if(COMPILER_RT_CAN_EXECUTE_TESTS) +if(COMPILER_RT_CAN_EXECUTE_TESTS AND CAN_TARGET_x86_64) # Run TSan output tests only if we're sure we can produce working binaries. set(TSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} @@ -25,7 +25,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS) DEPENDS ${TSAN_TEST_DEPS} ) set_target_properties(check-tsan PROPERTIES FOLDER "TSan unittests") -elseif(LLVM_INCLUDE_TESTS) +elseif(LLVM_INCLUDE_TESTS AND CAN_TARGET_x86_64) # Otherwise run only TSan unit tests (they are linked using the # host compiler). add_lit_testsuite(check-tsan "Running ThreadSanitizer tests" diff --git a/lib/tsan/lit_tests/Unit/lit.cfg b/lib/tsan/lit_tests/Unit/lit.cfg index 0a0dbbfa5495..36585df1c671 100644 --- a/lib/tsan/lit_tests/Unit/lit.cfg +++ b/lib/tsan/lit_tests/Unit/lit.cfg @@ -5,17 +5,12 @@ import os def get_required_attr(config, attr_name): attr_value = getattr(config, attr_name, None) if not attr_value: - lit.fatal("No attribute %r in test configuration! You may need to run " - "tests from your build directory or add this attribute " - "to lit.site.cfg " % attr_name) + lit_config.fatal( + "No attribute %r in test configuration! You may need to run " + "tests from your build directory or add this attribute " + "to lit.site.cfg " % attr_name) return attr_value -# Setup attributes common for all compiler-rt projects. -compiler_rt_src_root = get_required_attr(config, 'compiler_rt_src_root') -compiler_rt_lit_unit_cfg = os.path.join(compiler_rt_src_root, "lib", - "lit.common.unit.cfg") -lit.load_config(config, compiler_rt_lit_unit_cfg) - # Setup config name. config.name = 'ThreadSanitizer-Unit' @@ -26,11 +21,3 @@ config.test_exec_root = os.path.join(llvm_obj_root, "projects", "compiler-rt", "lib", "tsan", "tests") config.test_source_root = config.test_exec_root - -# Get path to external LLVM symbolizer to run ThreadSanitizer unit tests. -llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) -if llvm_tools_dir: - llvm_symbolizer_path = os.path.join(llvm_tools_dir, "llvm-symbolizer") - config.environment['TSAN_OPTIONS'] = ("external_symbolizer_path=" + - llvm_symbolizer_path) - diff --git a/lib/tsan/lit_tests/Unit/lit.site.cfg.in b/lib/tsan/lit_tests/Unit/lit.site.cfg.in index 6eedc2180876..3701a2cad74c 100644 --- a/lib/tsan/lit_tests/Unit/lit.site.cfg.in +++ b/lib/tsan/lit_tests/Unit/lit.site.cfg.in @@ -1,20 +1,8 @@ ## Autogenerated by LLVM/Clang configuration. # Do not edit! -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_build_mode = "@LLVM_BUILD_MODE@" +# Load common config for all compiler-rt unit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.unit.configured") -# LLVM tools dir can be passed in lit parameters, so try to -# apply substitution. -try: - config.llvm_tools_dir = config.llvm_tools_dir % lit.params - config.llvm_build_mode = config.llvm_build_mode % lit.params -except KeyError,e: - key, = e.args - lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key)) - -# Let the main config do the real work. -lit.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/Unit/lit.cfg") +# Load tool-specific config that would do the real work. +lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/Unit/lit.cfg") diff --git a/lib/tsan/lit_tests/allocator_returns_null.cc b/lib/tsan/lit_tests/allocator_returns_null.cc new file mode 100644 index 000000000000..4b5eb5504c27 --- /dev/null +++ b/lib/tsan/lit_tests/allocator_returns_null.cc @@ -0,0 +1,64 @@ +// Test the behavior of malloc/calloc/realloc when the allocation size is huge. +// By default (allocator_may_return_null=0) the process shoudl crash. +// With allocator_may_return_null=1 the allocator should return 0. +// +// RUN: %clangxx_tsan -O0 %s -o %t +// RUN: not %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH +// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH +// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH +// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH + +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <assert.h> +#include <limits> +int main(int argc, char **argv) { + volatile size_t size = std::numeric_limits<size_t>::max() - 10000; + assert(argc == 2); + char *x = 0; + if (!strcmp(argv[1], "malloc")) { + fprintf(stderr, "malloc:\n"); + x = (char*)malloc(size); + } + if (!strcmp(argv[1], "calloc")) { + fprintf(stderr, "calloc:\n"); + x = (char*)calloc(size / 4, 4); + } + + if (!strcmp(argv[1], "calloc-overflow")) { + fprintf(stderr, "calloc-overflow:\n"); + volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max(); + size_t kArraySize = 4096; + volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; + x = (char*)calloc(kArraySize, kArraySize2); + } + + if (!strcmp(argv[1], "realloc")) { + fprintf(stderr, "realloc:\n"); + x = (char*)realloc(0, size); + } + if (!strcmp(argv[1], "realloc-after-malloc")) { + fprintf(stderr, "realloc-after-malloc:\n"); + char *t = (char*)malloc(100); + *t = 42; + x = (char*)realloc(t, size); + assert(*t == 42); + } + fprintf(stderr, "x: %p\n", x); + return x != 0; +} +// CHECK-mCRASH: malloc: +// CHECK-mCRASH: ThreadSanitizer's allocator is terminating the process +// CHECK-cCRASH: calloc: +// CHECK-cCRASH: ThreadSanitizer's allocator is terminating the process +// CHECK-coCRASH: calloc-overflow: +// CHECK-coCRASH: ThreadSanitizer's allocator is terminating the process +// CHECK-rCRASH: realloc: +// CHECK-rCRASH: ThreadSanitizer's allocator is terminating the process +// CHECK-mrCRASH: realloc-after-malloc: +// CHECK-mrCRASH: ThreadSanitizer's allocator is terminating the process + diff --git a/lib/tsan/lit_tests/atomic_free.cc b/lib/tsan/lit_tests/atomic_free.cc index ba9bd5ac4aed..87d559362af4 100644 --- a/lib/tsan/lit_tests/atomic_free.cc +++ b/lib/tsan/lit_tests/atomic_free.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/atomic_free2.cc b/lib/tsan/lit_tests/atomic_free2.cc index 5517bf7ce902..961ff38c843b 100644 --- a/lib/tsan/lit_tests/atomic_free2.cc +++ b/lib/tsan/lit_tests/atomic_free2.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/atomic_race.cc b/lib/tsan/lit_tests/atomic_race.cc index 360b81238889..0dfe4d93df6e 100644 --- a/lib/tsan/lit_tests/atomic_race.cc +++ b/lib/tsan/lit_tests/atomic_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/atomic_stack.cc b/lib/tsan/lit_tests/atomic_stack.cc index 50f6a8a889ca..841f74b891ab 100644 --- a/lib/tsan/lit_tests/atomic_stack.cc +++ b/lib/tsan/lit_tests/atomic_stack.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/cond.c b/lib/tsan/lit_tests/cond.c new file mode 100644 index 000000000000..52c87a413eb7 --- /dev/null +++ b/lib/tsan/lit_tests/cond.c @@ -0,0 +1,53 @@ +// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// CHECK-NOT: WARNING: ThreadSanitizer: data race +// CHECK-NOT: ThreadSanitizer WARNING: double lock +// CHECK-NOT: ThreadSanitizer WARNING: mutex unlock by another thread +// CHECK: OK + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> + +pthread_mutex_t m; +pthread_cond_t c; +int x; + +void *thr1(void *p) { + int i; + + for (i = 0; i < 10; i += 2) { + pthread_mutex_lock(&m); + while (x != i) + pthread_cond_wait(&c, &m); + x = i + 1; + pthread_cond_signal(&c); + pthread_mutex_unlock(&m); + } + return 0; +} + +void *thr2(void *p) { + int i; + + for (i = 1; i < 10; i += 2) { + pthread_mutex_lock(&m); + while (x != i) + pthread_cond_wait(&c, &m); + x = i + 1; + pthread_mutex_unlock(&m); + pthread_cond_broadcast(&c); + } + return 0; +} + +int main() { + pthread_t th1, th2; + + pthread_mutex_init(&m, 0); + pthread_cond_init(&c, 0); + pthread_create(&th1, 0, thr1, 0); + pthread_create(&th2, 0, thr2, 0); + pthread_join(th1, 0); + pthread_join(th2, 0); + fprintf(stderr, "OK\n"); +} diff --git a/lib/tsan/lit_tests/cond_race.cc b/lib/tsan/lit_tests/cond_race.cc new file mode 100644 index 000000000000..1e2acb243279 --- /dev/null +++ b/lib/tsan/lit_tests/cond_race.cc @@ -0,0 +1,36 @@ +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// CHECK: ThreadSanitizer: data race +// CHECK: pthread_cond_signal + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> + +struct Ctx { + pthread_mutex_t m; + pthread_cond_t c; + bool done; +}; + +void *thr(void *p) { + Ctx *c = (Ctx*)p; + pthread_mutex_lock(&c->m); + c->done = true; + pthread_mutex_unlock(&c->m); + pthread_cond_signal(&c->c); + return 0; +} + +int main() { + Ctx *c = new Ctx(); + pthread_mutex_init(&c->m, 0); + pthread_cond_init(&c->c, 0); + pthread_t th; + pthread_create(&th, 0, thr, c); + pthread_mutex_lock(&c->m); + while (!c->done) + pthread_cond_wait(&c->c, &c->m); + pthread_mutex_unlock(&c->m); + delete c; + pthread_join(th, 0); +} diff --git a/lib/tsan/lit_tests/cond_version.c b/lib/tsan/lit_tests/cond_version.c new file mode 100644 index 000000000000..1f966bfacb8d --- /dev/null +++ b/lib/tsan/lit_tests/cond_version.c @@ -0,0 +1,44 @@ +// RUN: %clang_tsan -O1 %s -o %t -lrt && %t 2>&1 | FileCheck %s +// Test that pthread_cond is properly intercepted, +// previously there were issues with versioned symbols. +// CHECK: OK + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <time.h> +#include <errno.h> + +int main() { + typedef unsigned long long u64; + pthread_mutex_t m; + pthread_cond_t c; + pthread_condattr_t at; + struct timespec ts0, ts1, ts2; + int res; + u64 sleep; + + pthread_mutex_init(&m, 0); + pthread_condattr_init(&at); + pthread_condattr_setclock(&at, CLOCK_MONOTONIC); + pthread_cond_init(&c, &at); + + clock_gettime(CLOCK_MONOTONIC, &ts0); + ts1 = ts0; + ts1.tv_sec += 2; + + pthread_mutex_lock(&m); + do { + res = pthread_cond_timedwait(&c, &m, &ts1); + } while (res == 0); + pthread_mutex_unlock(&m); + + clock_gettime(CLOCK_MONOTONIC, &ts2); + sleep = (u64)ts2.tv_sec * 1000000000 + ts2.tv_nsec - + ((u64)ts0.tv_sec * 1000000000 + ts0.tv_nsec); + if (res != ETIMEDOUT) + exit(printf("bad return value %d, want %d\n", res, ETIMEDOUT)); + if (sleep < 1000000000) + exit(printf("bad sleep duration %lluns, want %dns\n", sleep, 1000000000)); + fprintf(stderr, "OK\n"); +} diff --git a/lib/tsan/lit_tests/deep_stack1.cc b/lib/tsan/lit_tests/deep_stack1.cc new file mode 100644 index 000000000000..3048aa8745bb --- /dev/null +++ b/lib/tsan/lit_tests/deep_stack1.cc @@ -0,0 +1,44 @@ +// RUN: %clangxx_tsan -O1 %s -o %t -DORDER1 && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t -DORDER2 && not %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +volatile int X; +volatile int N; +void (*volatile F)(); + +static void foo() { + if (--N == 0) + X = 42; + else + F(); +} + +void *Thread(void *p) { +#ifdef ORDER1 + sleep(1); +#endif + F(); + return 0; +} + +int main() { + N = 50000; + F = foo; + pthread_t t; + pthread_attr_t a; + pthread_attr_init(&a); + pthread_attr_setstacksize(&a, N * 256 + (1 << 20)); + pthread_create(&t, &a, Thread, 0); +#ifdef ORDER2 + sleep(1); +#endif + X = 43; + pthread_join(t, 0); +} + +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK: #100 foo +// We must output suffucuently large stack (at least 100 frames) + diff --git a/lib/tsan/lit_tests/default_options.cc b/lib/tsan/lit_tests/default_options.cc new file mode 100644 index 000000000000..62c6c028f9e4 --- /dev/null +++ b/lib/tsan/lit_tests/default_options.cc @@ -0,0 +1,32 @@ +// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> + +extern "C" const char *__tsan_default_options() { + return "report_bugs=0"; +} + +int Global; + +void *Thread1(void *x) { + Global = 42; + return NULL; +} + +void *Thread2(void *x) { + Global = 43; + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + fprintf(stderr, "DONE\n"); + return 0; +} + +// CHECK-NOT: WARNING: ThreadSanitizer: data race +// CHECK: DONE diff --git a/lib/tsan/lit_tests/fd_close_norace2.cc b/lib/tsan/lit_tests/fd_close_norace2.cc new file mode 100644 index 000000000000..b42b334a27c0 --- /dev/null +++ b/lib/tsan/lit_tests/fd_close_norace2.cc @@ -0,0 +1,30 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +int pipes[2]; + +void *Thread(void *x) { + // wait for shutown signal + while (read(pipes[0], &x, 1) != 1) { + } + close(pipes[0]); + close(pipes[1]); + return 0; +} + +int main() { + if (pipe(pipes)) + return 1; + pthread_t t; + pthread_create(&t, 0, Thread, 0); + // send shutdown signal + while (write(pipes[1], &t, 1) != 1) { + } + pthread_join(t, 0); + printf("OK\n"); +} + +// CHECK-NOT: WARNING: ThreadSanitizer: data race +// CHECK: OK diff --git a/lib/tsan/lit_tests/fd_location.cc b/lib/tsan/lit_tests/fd_location.cc index 35f9aabb0377..2b1e9c56e361 100644 --- a/lib/tsan/lit_tests/fd_location.cc +++ b/lib/tsan/lit_tests/fd_location.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/fd_pipe_race.cc b/lib/tsan/lit_tests/fd_pipe_race.cc index dfdb7795aae6..4dd2b77861ab 100644 --- a/lib/tsan/lit_tests/fd_pipe_race.cc +++ b/lib/tsan/lit_tests/fd_pipe_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/fd_stdout_race.cc b/lib/tsan/lit_tests/fd_stdout_race.cc index 6581fc503a1b..4b512bb78874 100644 --- a/lib/tsan/lit_tests/fd_stdout_race.cc +++ b/lib/tsan/lit_tests/fd_stdout_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/free_race.c b/lib/tsan/lit_tests/free_race.c index ff71a4d2116b..d1db9fece90a 100644 --- a/lib/tsan/lit_tests/free_race.c +++ b/lib/tsan/lit_tests/free_race.c @@ -1,4 +1,7 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t +// RUN: not %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOZUPP +// RUN: TSAN_OPTIONS="suppressions=%s.supp print_suppressions=1" %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUPP + #include <pthread.h> #include <stdlib.h> #include <stdio.h> @@ -34,11 +37,13 @@ int main() { return 0; } -// CHECK: WARNING: ThreadSanitizer: heap-use-after-free -// CHECK: Write of size 4 at {{.*}} by main thread{{.*}}: -// CHECK: #0 Thread2 -// CHECK: #1 main -// CHECK: Previous write of size 8 at {{.*}} by thread T1{{.*}}: -// CHECK: #0 free -// CHECK: #{{(1|2)}} Thread1 -// CHECK: SUMMARY: ThreadSanitizer: heap-use-after-free{{.*}}Thread2 +// CHECK-NOZUPP: WARNING: ThreadSanitizer: heap-use-after-free +// CHECK-NOZUPP: Write of size 4 at {{.*}} by main thread{{.*}}: +// CHECK-NOZUPP: #0 Thread2 +// CHECK-NOZUPP: #1 main +// CHECK-NOZUPP: Previous write of size 8 at {{.*}} by thread T1{{.*}}: +// CHECK-NOZUPP: #0 free +// CHECK-NOZUPP: #{{(1|2)}} Thread1 +// CHECK-NOZUPP: SUMMARY: ThreadSanitizer: heap-use-after-free{{.*}}Thread2 +// CHECK-SUPP: ThreadSanitizer: Matched 1 suppressions +// CHECK-SUPP: 1 race:^Thread2$ diff --git a/lib/tsan/lit_tests/free_race.c.supp b/lib/tsan/lit_tests/free_race.c.supp new file mode 100644 index 000000000000..f5d6a4969a41 --- /dev/null +++ b/lib/tsan/lit_tests/free_race.c.supp @@ -0,0 +1,2 @@ +# Suppression for a use-after-free in free_race.c +race:^Thread2$ diff --git a/lib/tsan/lit_tests/free_race2.c b/lib/tsan/lit_tests/free_race2.c index f20774b2d8d4..2b9a41927a47 100644 --- a/lib/tsan/lit_tests/free_race2.c +++ b/lib/tsan/lit_tests/free_race2.c @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <stdlib.h> void __attribute__((noinline)) foo(int *mem) { diff --git a/lib/tsan/lit_tests/global_race.cc b/lib/tsan/lit_tests/global_race.cc index 0892d07da2cb..ac2016155575 100644 --- a/lib/tsan/lit_tests/global_race.cc +++ b/lib/tsan/lit_tests/global_race.cc @@ -1,25 +1,42 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stddef.h> int GlobalData[10]; +int x; +namespace XXX { + struct YYY { + static int ZZZ[10]; + }; + int YYY::ZZZ[10]; +} void *Thread(void *a) { GlobalData[2] = 42; + x = 1; + XXX::YYY::ZZZ[0] = 1; return 0; } int main() { fprintf(stderr, "addr=%p\n", GlobalData); + fprintf(stderr, "addr2=%p\n", &x); + fprintf(stderr, "addr3=%p\n", XXX::YYY::ZZZ); pthread_t t; pthread_create(&t, 0, Thread, 0); GlobalData[2] = 43; + x = 0; + XXX::YYY::ZZZ[0] = 0; pthread_join(t, 0); } // CHECK: addr=[[ADDR:0x[0-9,a-f]+]] +// CHECK: addr2=[[ADDR2:0x[0-9,a-f]+]] +// CHECK: addr3=[[ADDR3:0x[0-9,a-f]+]] +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK: Location is global 'GlobalData' of size 40 at [[ADDR]] ({{.*}}+0x{{[0-9,a-f]+}}) +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK: Location is global 'x' of size 4 at [[ADDR2]] ({{.*}}+0x{{[0-9,a-f]+}}) // CHECK: WARNING: ThreadSanitizer: data race -// Requires llvm-symbolizer, so disabled for now. -// CHECK0: Location is global 'GlobalData' of size 40 at [[ADDR]] -// CHECK0: (global_race.cc.exe+0x[0-9,a-f]+) +// CHECK: Location is global 'XXX::YYY::ZZZ' of size 40 at [[ADDR3]] ({{.*}}+0x{{[0-9,a-f]+}}) diff --git a/lib/tsan/lit_tests/halt_on_error.cc b/lib/tsan/lit_tests/halt_on_error.cc new file mode 100644 index 000000000000..fddaffff29aa --- /dev/null +++ b/lib/tsan/lit_tests/halt_on_error.cc @@ -0,0 +1,25 @@ +// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS halt_on_error=1" not %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> + +int X; + +void *Thread(void *x) { + X = 42; + return 0; +} + +int main() { + fprintf(stderr, "BEFORE\n"); + pthread_t t; + pthread_create(&t, 0, Thread, 0); + X = 43; + pthread_join(t, 0); + fprintf(stderr, "AFTER\n"); + return 0; +} + +// CHECK: BEFORE +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK-NOT: AFTER + diff --git a/lib/tsan/lit_tests/heap_race.cc b/lib/tsan/lit_tests/heap_race.cc index 297f8dbdec7d..cc2c1fee532b 100644 --- a/lib/tsan/lit_tests/heap_race.cc +++ b/lib/tsan/lit_tests/heap_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stddef.h> diff --git a/lib/tsan/lit_tests/ignore_free.cc b/lib/tsan/lit_tests/ignore_free.cc new file mode 100644 index 000000000000..60369cc1baa5 --- /dev/null +++ b/lib/tsan/lit_tests/ignore_free.cc @@ -0,0 +1,35 @@ +// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +extern "C" { +void AnnotateIgnoreReadsBegin(const char *f, int l); +void AnnotateIgnoreReadsEnd(const char *f, int l); +void AnnotateIgnoreWritesBegin(const char *f, int l); +void AnnotateIgnoreWritesEnd(const char *f, int l); +} + +void *Thread(void *p) { + *(int*)p = 42; + return 0; +} + +int main() { + int *p = new int(0); + pthread_t t; + pthread_create(&t, 0, Thread, p); + sleep(1); + AnnotateIgnoreReadsBegin(__FILE__, __LINE__); + AnnotateIgnoreWritesBegin(__FILE__, __LINE__); + free(p); + AnnotateIgnoreReadsEnd(__FILE__, __LINE__); + AnnotateIgnoreWritesEnd(__FILE__, __LINE__); + pthread_join(t, 0); + fprintf(stderr, "OK\n"); + return 0; +} + +// CHECK-NOT: WARNING: ThreadSanitizer: data race +// CHECK: OK diff --git a/lib/tsan/lit_tests/ignore_lib0.cc b/lib/tsan/lit_tests/ignore_lib0.cc new file mode 100644 index 000000000000..ea0f061e609d --- /dev/null +++ b/lib/tsan/lit_tests/ignore_lib0.cc @@ -0,0 +1,30 @@ +// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib0.so +// RUN: %clangxx_tsan -O1 %s -L%T -lignore_lib0 -o %t +// RUN: echo running w/o suppressions: +// RUN: LD_LIBRARY_PATH=%T not %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOSUPP +// RUN: echo running with suppressions: +// RUN: LD_LIBRARY_PATH=%T TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP + +// Tests that interceptors coming from a library specified in called_from_lib +// suppression are ignored. + +#ifndef LIB + +extern "C" void libfunc(); + +int main() { + libfunc(); +} + +#else // #ifdef LIB + +#include "ignore_lib_lib.h" + +#endif // #ifdef LIB + +// CHECK-NOSUPP: WARNING: ThreadSanitizer: data race +// CHECK-NOSUPP: OK + +// CHECK-WITHSUPP-NOT: WARNING: ThreadSanitizer: data race +// CHECK-WITHSUPP: OK + diff --git a/lib/tsan/lit_tests/ignore_lib0.cc.supp b/lib/tsan/lit_tests/ignore_lib0.cc.supp new file mode 100644 index 000000000000..7728c926b7de --- /dev/null +++ b/lib/tsan/lit_tests/ignore_lib0.cc.supp @@ -0,0 +1,2 @@ +called_from_lib:/libignore_lib0.so + diff --git a/lib/tsan/lit_tests/ignore_lib1.cc b/lib/tsan/lit_tests/ignore_lib1.cc new file mode 100644 index 000000000000..c4f2e7344135 --- /dev/null +++ b/lib/tsan/lit_tests/ignore_lib1.cc @@ -0,0 +1,42 @@ +// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib1.so +// RUN: %clangxx_tsan -O1 %s -o %t +// RUN: echo running w/o suppressions: +// RUN: not %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOSUPP +// RUN: echo running with suppressions: +// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP + +// Tests that interceptors coming from a dynamically loaded library specified +// in called_from_lib suppression are ignored. + +#ifndef LIB + +#include <dlfcn.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <libgen.h> +#include <string> + +int main(int argc, char **argv) { + std::string lib = std::string(dirname(argv[0])) + "/libignore_lib1.so"; + void *h = dlopen(lib.c_str(), RTLD_GLOBAL | RTLD_NOW); + if (h == 0) + exit(printf("failed to load the library (%d)\n", errno)); + void (*f)() = (void(*)())dlsym(h, "libfunc"); + if (f == 0) + exit(printf("failed to find the func (%d)\n", errno)); + f(); +} + +#else // #ifdef LIB + +#include "ignore_lib_lib.h" + +#endif // #ifdef LIB + +// CHECK-NOSUPP: WARNING: ThreadSanitizer: data race +// CHECK-NOSUPP: OK + +// CHECK-WITHSUPP-NOT: WARNING: ThreadSanitizer: data race +// CHECK-WITHSUPP: OK + diff --git a/lib/tsan/lit_tests/ignore_lib1.cc.supp b/lib/tsan/lit_tests/ignore_lib1.cc.supp new file mode 100644 index 000000000000..9f4119ec0bc4 --- /dev/null +++ b/lib/tsan/lit_tests/ignore_lib1.cc.supp @@ -0,0 +1,2 @@ +called_from_lib:/libignore_lib1.so$ + diff --git a/lib/tsan/lit_tests/ignore_lib2.cc b/lib/tsan/lit_tests/ignore_lib2.cc new file mode 100644 index 000000000000..97f9419e4d89 --- /dev/null +++ b/lib/tsan/lit_tests/ignore_lib2.cc @@ -0,0 +1,33 @@ +// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib2_0.so +// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib2_1.so +// RUN: %clangxx_tsan -O1 %s -o %t +// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" not %t 2>&1 | FileCheck %s + +// Tests that called_from_lib suppression matched against 2 libraries +// causes program crash (this is not supported). + +#ifndef LIB + +#include <dlfcn.h> +#include <stdio.h> +#include <libgen.h> +#include <string> + +int main(int argc, char **argv) { + std::string lib0 = std::string(dirname(argv[0])) + "/libignore_lib2_0.so"; + std::string lib1 = std::string(dirname(argv[0])) + "/libignore_lib2_1.so"; + dlopen(lib0.c_str(), RTLD_GLOBAL | RTLD_NOW); + dlopen(lib1.c_str(), RTLD_GLOBAL | RTLD_NOW); + fprintf(stderr, "OK\n"); +} + +#else // #ifdef LIB + +extern "C" void libfunc() { +} + +#endif // #ifdef LIB + +// CHECK: ThreadSanitizer: called_from_lib suppression 'ignore_lib2' is matched against 2 libraries +// CHECK-NOT: OK + diff --git a/lib/tsan/lit_tests/ignore_lib2.cc.supp b/lib/tsan/lit_tests/ignore_lib2.cc.supp new file mode 100644 index 000000000000..1419c71c67ef --- /dev/null +++ b/lib/tsan/lit_tests/ignore_lib2.cc.supp @@ -0,0 +1,2 @@ +called_from_lib:ignore_lib2 + diff --git a/lib/tsan/lit_tests/ignore_lib3.cc b/lib/tsan/lit_tests/ignore_lib3.cc new file mode 100644 index 000000000000..8f237fcc81fd --- /dev/null +++ b/lib/tsan/lit_tests/ignore_lib3.cc @@ -0,0 +1,33 @@ +// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib3.so +// RUN: %clangxx_tsan -O1 %s -o %t +// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" not %t 2>&1 | FileCheck %s + +// Tests that unloading of a library matched against called_from_lib suppression +// causes program crash (this is not supported). + +#ifndef LIB + +#include <dlfcn.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <libgen.h> +#include <string> + +int main(int argc, char **argv) { + std::string lib = std::string(dirname(argv[0])) + "/libignore_lib3.so"; + void *h = dlopen(lib.c_str(), RTLD_GLOBAL | RTLD_NOW); + dlclose(h); + fprintf(stderr, "OK\n"); +} + +#else // #ifdef LIB + +extern "C" void libfunc() { +} + +#endif // #ifdef LIB + +// CHECK: ThreadSanitizer: library {{.*}} that was matched against called_from_lib suppression 'ignore_lib3.so' is unloaded +// CHECK-NOT: OK + diff --git a/lib/tsan/lit_tests/ignore_lib3.cc.supp b/lib/tsan/lit_tests/ignore_lib3.cc.supp new file mode 100644 index 000000000000..975dbcef99fe --- /dev/null +++ b/lib/tsan/lit_tests/ignore_lib3.cc.supp @@ -0,0 +1,2 @@ +called_from_lib:ignore_lib3.so + diff --git a/lib/tsan/lit_tests/ignore_lib_lib.h b/lib/tsan/lit_tests/ignore_lib_lib.h new file mode 100644 index 000000000000..2bfe84dfc0ec --- /dev/null +++ b/lib/tsan/lit_tests/ignore_lib_lib.h @@ -0,0 +1,25 @@ +#include <pthread.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +void *volatile mem; +volatile int len; + +void *Thread(void *p) { + while ((p = __atomic_load_n(&mem, __ATOMIC_ACQUIRE)) == 0) + usleep(100); + memset(p, 0, len); + return 0; +} + +extern "C" void libfunc() { + pthread_t t; + pthread_create(&t, 0, Thread, 0); + len = 10; + __atomic_store_n(&mem, malloc(len), __ATOMIC_RELEASE); + pthread_join(t, 0); + free(mem); + fprintf(stderr, "OK\n"); +} diff --git a/lib/tsan/lit_tests/ignore_malloc.cc b/lib/tsan/lit_tests/ignore_malloc.cc new file mode 100644 index 000000000000..63bd4241b59e --- /dev/null +++ b/lib/tsan/lit_tests/ignore_malloc.cc @@ -0,0 +1,38 @@ +// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +extern "C" { +void AnnotateIgnoreReadsBegin(const char *f, int l); +void AnnotateIgnoreReadsEnd(const char *f, int l); +void AnnotateIgnoreWritesBegin(const char *f, int l); +void AnnotateIgnoreWritesEnd(const char *f, int l); +} + +int *g; + +void *Thread(void *a) { + int *p = 0; + while ((p = __atomic_load_n(&g, __ATOMIC_RELAXED)) == 0) + usleep(100); + *p = 42; + return 0; +} + +int main() { + pthread_t t; + pthread_create(&t, 0, Thread, 0); + AnnotateIgnoreWritesBegin(__FILE__, __LINE__); + int *p = new int(0); + AnnotateIgnoreWritesEnd(__FILE__, __LINE__); + __atomic_store_n(&g, p, __ATOMIC_RELAXED); + pthread_join(t, 0); + delete p; + fprintf(stderr, "OK\n"); + return 0; +} + +// CHECK-NOT: WARNING: ThreadSanitizer: data race +// CHECK: OK diff --git a/lib/tsan/lit_tests/ignore_sync.cc b/lib/tsan/lit_tests/ignore_sync.cc new file mode 100644 index 000000000000..67f2d906d9c7 --- /dev/null +++ b/lib/tsan/lit_tests/ignore_sync.cc @@ -0,0 +1,30 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> + +extern "C" void AnnotateIgnoreSyncBegin(const char*, int); +extern "C" void AnnotateIgnoreSyncEnd(const char*, int); + +int Global; +pthread_mutex_t Mutex = PTHREAD_MUTEX_INITIALIZER; + +void *Thread(void *x) { + AnnotateIgnoreSyncBegin(0, 0); + pthread_mutex_lock(&Mutex); + Global++; + pthread_mutex_unlock(&Mutex); + AnnotateIgnoreSyncEnd(0, 0); + return 0; +} + +int main() { + pthread_t t; + pthread_create(&t, 0, Thread, 0); + pthread_mutex_lock(&Mutex); + Global++; + pthread_mutex_unlock(&Mutex); + pthread_join(t, 0); +} + +// CHECK: WARNING: ThreadSanitizer: data race + diff --git a/lib/tsan/lit_tests/inlined_memcpy_race.cc b/lib/tsan/lit_tests/inlined_memcpy_race.cc index 6efe5a956e9d..5dda36e4b9e7 100644 --- a/lib/tsan/lit_tests/inlined_memcpy_race.cc +++ b/lib/tsan/lit_tests/inlined_memcpy_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stddef.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/java.h b/lib/tsan/lit_tests/java.h index 04094197edb7..7aa0bca32cec 100644 --- a/lib/tsan/lit_tests/java.h +++ b/lib/tsan/lit_tests/java.h @@ -5,6 +5,7 @@ extern "C" { typedef unsigned long jptr; // NOLINT +void __tsan_java_preinit(const char *libjvm_path); void __tsan_java_init(jptr heap_begin, jptr heap_size); int __tsan_java_fini(); void __tsan_java_alloc(jptr ptr, jptr size); diff --git a/lib/tsan/lit_tests/java_lock_rec_race.cc b/lib/tsan/lit_tests/java_lock_rec_race.cc index 61626aaddc0d..a868e260c86d 100644 --- a/lib/tsan/lit_tests/java_lock_rec_race.cc +++ b/lib/tsan/lit_tests/java_lock_rec_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include "java.h" #include <unistd.h> diff --git a/lib/tsan/lit_tests/java_race.cc b/lib/tsan/lit_tests/java_race.cc index 722bb6e8d09c..4841a7db0a9c 100644 --- a/lib/tsan/lit_tests/java_race.cc +++ b/lib/tsan/lit_tests/java_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include "java.h" void *Thread(void *p) { diff --git a/lib/tsan/lit_tests/java_race_move.cc b/lib/tsan/lit_tests/java_race_move.cc index bb63ea985c58..6da8a106483c 100644 --- a/lib/tsan/lit_tests/java_race_move.cc +++ b/lib/tsan/lit_tests/java_race_move.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include "java.h" jptr varaddr; diff --git a/lib/tsan/lit_tests/lit.cfg b/lib/tsan/lit_tests/lit.cfg index d483d2fcbdc6..c4193639f493 100644 --- a/lib/tsan/lit_tests/lit.cfg +++ b/lib/tsan/lit_tests/lit.cfg @@ -2,12 +2,15 @@ import os +import lit.util + def get_required_attr(config, attr_name): attr_value = getattr(config, attr_name, None) if not attr_value: - lit.fatal("No attribute %r in test configuration! You may need to run " - "tests from your build directory or add this attribute " - "to lit.site.cfg " % attr_name) + lit_config.fatal( + "No attribute %r in test configuration! You may need to run " + "tests from your build directory or add this attribute " + "to lit.site.cfg " % attr_name) return attr_value # Setup config name. @@ -17,9 +20,9 @@ config.name = 'ThreadSanitizer' config.test_source_root = os.path.dirname(__file__) def DisplayNoConfigMessage(): - lit.fatal("No site specific configuration available! " + - "Try running your test from the build tree or running " + - "make check-tsan") + lit_config.fatal("No site specific configuration available! " + + "Try running your test from the build tree or running " + + "make check-tsan") # Figure out LLVM source root. llvm_src_root = getattr(config, 'llvm_src_root', None) @@ -27,9 +30,9 @@ if llvm_src_root is None: # We probably haven't loaded the site-specific configuration: the user # is likely trying to run a test file directly, and the site configuration # wasn't created by the build system. - tsan_site_cfg = lit.params.get('tsan_site_config', None) + tsan_site_cfg = lit_config.params.get('tsan_site_config', None) if (tsan_site_cfg) and (os.path.exists(tsan_site_cfg)): - lit.load_config(config, tsan_site_cfg) + lit_config.load_config(config, tsan_site_cfg) raise SystemExit # Try to guess the location of site-specific configuration using llvm-config @@ -45,25 +48,11 @@ if llvm_src_root is None: if (not tsan_site_cfg) or (not os.path.exists(tsan_site_cfg)): DisplayNoConfigMessage() - lit.load_config(config, tsan_site_cfg) + lit_config.load_config(config, tsan_site_cfg) raise SystemExit -# Setup attributes common for all compiler-rt projects. -compiler_rt_src_root = get_required_attr(config, 'compiler_rt_src_root') -compiler_rt_lit_cfg = os.path.join(compiler_rt_src_root, "lib", - "lit.common.cfg") -if (not compiler_rt_lit_cfg) or (not os.path.exists(compiler_rt_lit_cfg)): - lit.fatal("Can't find common compiler-rt lit config at: %r" - % compiler_rt_lit_cfg) -lit.load_config(config, compiler_rt_lit_cfg) - # Setup environment variables for running ThreadSanitizer. tsan_options = "atexit_sleep_ms=0" -# Get path to external LLVM symbolizer to run ThreadSanitizer output tests. -llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) -if llvm_tools_dir: - llvm_symbolizer_path = os.path.join(llvm_tools_dir, "llvm-symbolizer") - tsan_options += " " + "external_symbolizer_path=" + llvm_symbolizer_path config.environment['TSAN_OPTIONS'] = tsan_options @@ -73,8 +62,9 @@ clang_tsan_cflags = ("-fsanitize=thread " + "-g " + "-Wall " + "-lpthread " - + "-ldl ") -clang_tsan_cxxflags = "-ccc-cxx " + clang_tsan_cflags + + "-ldl " + + "-m64 ") +clang_tsan_cxxflags = "--driver-mode=g++ " + clang_tsan_cflags config.substitutions.append( ("%clangxx_tsan ", (" " + config.clang + " " + clang_tsan_cxxflags + " ")) ) config.substitutions.append( ("%clang_tsan ", (" " + config.clang + " " + diff --git a/lib/tsan/lit_tests/lit.site.cfg.in b/lib/tsan/lit_tests/lit.site.cfg.in index 07b521af061f..b0e427446eaa 100644 --- a/lib/tsan/lit_tests/lit.site.cfg.in +++ b/lib/tsan/lit_tests/lit.site.cfg.in @@ -1,20 +1,8 @@ ## Autogenerated by LLVM/Clang configuration. # Do not edit! -config.clang = "@LLVM_BINARY_DIR@/bin/clang" -config.host_os = "@HOST_OS@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.target_triple = "@TARGET_TRIPLE@" +# Load common config for all compiler-rt lit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.configured") -# LLVM tools dir can be passed in lit parameters, so try to -# apply substitution. -try: - config.llvm_tools_dir = config.llvm_tools_dir % lit.params -except KeyError,e: - key, = e.args - lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key)) - -# Let the main config do the real work. -lit.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg") +# Load tool-specific config that would do the real work. +lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg") diff --git a/lib/tsan/lit_tests/load_shared_lib.cc b/lib/tsan/lit_tests/load_shared_lib.cc index dd6fa0964f4a..d60cd5700a8a 100644 --- a/lib/tsan/lit_tests/load_shared_lib.cc +++ b/lib/tsan/lit_tests/load_shared_lib.cc @@ -4,7 +4,7 @@ // RUN: %clangxx_tsan -O1 %p/SharedLibs/load_shared_lib-so.cc \ // RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <dlfcn.h> #include <pthread.h> diff --git a/lib/tsan/lit_tests/longjmp3.cc b/lib/tsan/lit_tests/longjmp3.cc index 87fabd0b3be2..ae2cfd05fe1a 100644 --- a/lib/tsan/lit_tests/longjmp3.cc +++ b/lib/tsan/lit_tests/longjmp3.cc @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stdlib.h> diff --git a/lib/tsan/lit_tests/longjmp4.cc b/lib/tsan/lit_tests/longjmp4.cc index a8764dda5a6b..6b0526ef3a66 100644 --- a/lib/tsan/lit_tests/longjmp4.cc +++ b/lib/tsan/lit_tests/longjmp4.cc @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stdlib.h> diff --git a/lib/tsan/lit_tests/malloc_overflow.cc b/lib/tsan/lit_tests/malloc_overflow.cc index 19423c5f93f1..afbebc8bec44 100644 --- a/lib/tsan/lit_tests/malloc_overflow.cc +++ b/lib/tsan/lit_tests/malloc_overflow.cc @@ -1,4 +1,5 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t +// RUN: TSAN_OPTIONS=allocator_may_return_null=1 %t 2>&1 | FileCheck %s #include <stdio.h> #include <stdlib.h> diff --git a/lib/tsan/lit_tests/malloc_stack.cc b/lib/tsan/lit_tests/malloc_stack.cc index c185623ff5ca..3603497ef311 100644 --- a/lib/tsan/lit_tests/malloc_stack.cc +++ b/lib/tsan/lit_tests/malloc_stack.cc @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/memcpy_race.cc b/lib/tsan/lit_tests/memcpy_race.cc index 857728ba0540..8f39113674d6 100644 --- a/lib/tsan/lit_tests/memcpy_race.cc +++ b/lib/tsan/lit_tests/memcpy_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stddef.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/mop_with_offset.cc b/lib/tsan/lit_tests/mop_with_offset.cc index 0c11ef6b9187..2b6a4ff50aaf 100644 --- a/lib/tsan/lit_tests/mop_with_offset.cc +++ b/lib/tsan/lit_tests/mop_with_offset.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stddef.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/mop_with_offset2.cc b/lib/tsan/lit_tests/mop_with_offset2.cc index ee0d64a0afbf..037c4db5f524 100644 --- a/lib/tsan/lit_tests/mop_with_offset2.cc +++ b/lib/tsan/lit_tests/mop_with_offset2.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stddef.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/mutex_destroy_locked.cc b/lib/tsan/lit_tests/mutex_destroy_locked.cc index 27a04248b172..9b020d31b94c 100644 --- a/lib/tsan/lit_tests/mutex_destroy_locked.cc +++ b/lib/tsan/lit_tests/mutex_destroy_locked.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/mutex_robust.cc b/lib/tsan/lit_tests/mutex_robust.cc new file mode 100644 index 000000000000..b826616076ae --- /dev/null +++ b/lib/tsan/lit_tests/mutex_robust.cc @@ -0,0 +1,36 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> + +pthread_mutex_t m; + +void *thr(void *p) { + pthread_mutex_lock(&m); + return 0; +} + +int main() { + pthread_mutexattr_t a; + pthread_mutexattr_init(&a); + pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST); + pthread_mutex_init(&m, &a); + pthread_t th; + pthread_create(&th, 0, thr, 0); + sleep(1); + if (pthread_mutex_lock(&m) != EOWNERDEAD) { + fprintf(stderr, "not EOWNERDEAD\n"); + exit(1); + } + pthread_join(th, 0); + fprintf(stderr, "DONE\n"); +} + +// This is a correct code, and tsan must not bark. +// CHECK-NOT: WARNING: ThreadSanitizer +// CHECK-NOT: EOWNERDEAD +// CHECK: DONE +// CHECK-NOT: WARNING: ThreadSanitizer + diff --git a/lib/tsan/lit_tests/mutex_robust2.cc b/lib/tsan/lit_tests/mutex_robust2.cc new file mode 100644 index 000000000000..5bd7ff682d1b --- /dev/null +++ b/lib/tsan/lit_tests/mutex_robust2.cc @@ -0,0 +1,41 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> + +pthread_mutex_t m; +int x; + +void *thr(void *p) { + pthread_mutex_lock(&m); + x = 42; + return 0; +} + +int main() { + pthread_mutexattr_t a; + pthread_mutexattr_init(&a); + pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST); + pthread_mutex_init(&m, &a); + pthread_t th; + pthread_create(&th, 0, thr, 0); + sleep(1); + if (pthread_mutex_trylock(&m) != EOWNERDEAD) { + fprintf(stderr, "not EOWNERDEAD\n"); + exit(1); + } + x = 43; + pthread_join(th, 0); + fprintf(stderr, "DONE\n"); +} + +// This is a false positive, tsan must not bark at the data race. +// But currently it does. +// CHECK-NOT: WARNING: ThreadSanitizer WARNING: double lock of mutex +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK-NOT: EOWNERDEAD +// CHECK: DONE +// CHECK-NOT: WARNING: ThreadSanitizer + diff --git a/lib/tsan/lit_tests/mutexset1.cc b/lib/tsan/lit_tests/mutexset1.cc index f32a770ab075..ca87a7ba047d 100644 --- a/lib/tsan/lit_tests/mutexset1.cc +++ b/lib/tsan/lit_tests/mutexset1.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/mutexset2.cc b/lib/tsan/lit_tests/mutexset2.cc index 15d230332512..9ccf952b0050 100644 --- a/lib/tsan/lit_tests/mutexset2.cc +++ b/lib/tsan/lit_tests/mutexset2.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/mutexset3.cc b/lib/tsan/lit_tests/mutexset3.cc index 6ac7ad15e4f9..272ddafb3c4a 100644 --- a/lib/tsan/lit_tests/mutexset3.cc +++ b/lib/tsan/lit_tests/mutexset3.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/mutexset4.cc b/lib/tsan/lit_tests/mutexset4.cc index 75684cf9ae5b..be751fa92bf0 100644 --- a/lib/tsan/lit_tests/mutexset4.cc +++ b/lib/tsan/lit_tests/mutexset4.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/mutexset5.cc b/lib/tsan/lit_tests/mutexset5.cc index 6e75810aff22..e013edb4656a 100644 --- a/lib/tsan/lit_tests/mutexset5.cc +++ b/lib/tsan/lit_tests/mutexset5.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/mutexset6.cc b/lib/tsan/lit_tests/mutexset6.cc index 4b19a12e0434..f5e6e66becf8 100644 --- a/lib/tsan/lit_tests/mutexset6.cc +++ b/lib/tsan/lit_tests/mutexset6.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/mutexset7.cc b/lib/tsan/lit_tests/mutexset7.cc index 3ec1b5202983..51451b215490 100644 --- a/lib/tsan/lit_tests/mutexset7.cc +++ b/lib/tsan/lit_tests/mutexset7.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/mutexset8.cc b/lib/tsan/lit_tests/mutexset8.cc index 6db63f7d16db..8822b050e939 100644 --- a/lib/tsan/lit_tests/mutexset8.cc +++ b/lib/tsan/lit_tests/mutexset8.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/oob_race.cc b/lib/tsan/lit_tests/oob_race.cc index 2e7f0593fd8d..9d8e2220d9a5 100644 --- a/lib/tsan/lit_tests/oob_race.cc +++ b/lib/tsan/lit_tests/oob_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/race_on_barrier.c b/lib/tsan/lit_tests/race_on_barrier.c index 3e76f8bf5e20..3c0199dec22e 100644 --- a/lib/tsan/lit_tests/race_on_barrier.c +++ b/lib/tsan/lit_tests/race_on_barrier.c @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stddef.h> diff --git a/lib/tsan/lit_tests/race_on_barrier2.c b/lib/tsan/lit_tests/race_on_barrier2.c index 46a4f50b133d..62773d43e66e 100644 --- a/lib/tsan/lit_tests/race_on_barrier2.c +++ b/lib/tsan/lit_tests/race_on_barrier2.c @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stddef.h> diff --git a/lib/tsan/lit_tests/race_on_heap.cc b/lib/tsan/lit_tests/race_on_heap.cc index 35434eac1850..a84c0de96558 100644 --- a/lib/tsan/lit_tests/race_on_heap.cc +++ b/lib/tsan/lit_tests/race_on_heap.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdlib.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/race_on_mutex.c b/lib/tsan/lit_tests/race_on_mutex.c index aff32f9bb1a2..e66341414831 100644 --- a/lib/tsan/lit_tests/race_on_mutex.c +++ b/lib/tsan/lit_tests/race_on_mutex.c @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stddef.h> diff --git a/lib/tsan/lit_tests/race_on_mutex2.c b/lib/tsan/lit_tests/race_on_mutex2.c index 84bef75a3449..80c395e1f9ce 100644 --- a/lib/tsan/lit_tests/race_on_mutex2.c +++ b/lib/tsan/lit_tests/race_on_mutex2.c @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stddef.h> diff --git a/lib/tsan/lit_tests/race_on_read.cc b/lib/tsan/lit_tests/race_on_read.cc index 7d226814816e..4ca4b25bfa81 100644 --- a/lib/tsan/lit_tests/race_on_read.cc +++ b/lib/tsan/lit_tests/race_on_read.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/race_on_write.cc b/lib/tsan/lit_tests/race_on_write.cc index f1b0bb1cbd6e..8a56c8464b91 100644 --- a/lib/tsan/lit_tests/race_on_write.cc +++ b/lib/tsan/lit_tests/race_on_write.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/race_with_finished_thread.cc b/lib/tsan/lit_tests/race_with_finished_thread.cc index a267290e661e..c713c67a398e 100644 --- a/lib/tsan/lit_tests/race_with_finished_thread.cc +++ b/lib/tsan/lit_tests/race_with_finished_thread.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stddef.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/signal_errno.cc b/lib/tsan/lit_tests/signal_errno.cc index 8181555f6f63..2febca38294e 100644 --- a/lib/tsan/lit_tests/signal_errno.cc +++ b/lib/tsan/lit_tests/signal_errno.cc @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stdlib.h> diff --git a/lib/tsan/lit_tests/signal_malloc.cc b/lib/tsan/lit_tests/signal_malloc.cc index 4dbc2f78ab17..ef180b8a25b6 100644 --- a/lib/tsan/lit_tests/signal_malloc.cc +++ b/lib/tsan/lit_tests/signal_malloc.cc @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <stdio.h> #include <stdlib.h> #include <signal.h> diff --git a/lib/tsan/lit_tests/sigsuspend.cc b/lib/tsan/lit_tests/sigsuspend.cc new file mode 100644 index 000000000000..78d507fa0af5 --- /dev/null +++ b/lib/tsan/lit_tests/sigsuspend.cc @@ -0,0 +1,38 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +#include <assert.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> +#include <stdio.h> + +static bool signal_handler_ran = false; + +void do_nothing_signal_handler(int signum) { + write(1, "HANDLER\n", 8); + signal_handler_ran = true; +} + +int main() { + const int kSignalToTest = SIGSYS; + assert(SIG_ERR != signal(kSignalToTest, do_nothing_signal_handler)); + sigset_t empty_set; + assert(0 == sigemptyset(&empty_set)); + sigset_t one_signal = empty_set; + assert(0 == sigaddset(&one_signal, kSignalToTest)); + sigset_t old_set; + assert(0 == sigprocmask(SIG_BLOCK, &one_signal, &old_set)); + raise(kSignalToTest); + assert(!signal_handler_ran); + sigset_t all_but_one; + assert(0 == sigfillset(&all_but_one)); + assert(0 == sigdelset(&all_but_one, kSignalToTest)); + sigsuspend(&all_but_one); + assert(signal_handler_ran); + + // Restore the original set. + assert(0 == sigprocmask(SIG_SETMASK, &old_set, NULL)); + printf("DONE"); +} + +// CHECK: HANDLER +// CHECK: DONE diff --git a/lib/tsan/lit_tests/simple_race.c b/lib/tsan/lit_tests/simple_race.c index 44aff897406a..80a83e01a294 100644 --- a/lib/tsan/lit_tests/simple_race.c +++ b/lib/tsan/lit_tests/simple_race.c @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/simple_race.cc b/lib/tsan/lit_tests/simple_race.cc index 99cf228ac2f2..47854cfd9a3e 100644 --- a/lib/tsan/lit_tests/simple_race.cc +++ b/lib/tsan/lit_tests/simple_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/simple_stack.c b/lib/tsan/lit_tests/simple_stack.c index 4539cb7c1f37..a447e2880447 100644 --- a/lib/tsan/lit_tests/simple_stack.c +++ b/lib/tsan/lit_tests/simple_stack.c @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/simple_stack2.cc b/lib/tsan/lit_tests/simple_stack2.cc index bf27a15ffad5..7a034c4cd6ed 100644 --- a/lib/tsan/lit_tests/simple_stack2.cc +++ b/lib/tsan/lit_tests/simple_stack2.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/sleep_sync.cc b/lib/tsan/lit_tests/sleep_sync.cc index c3d47d311749..217a52a097ce 100644 --- a/lib/tsan/lit_tests/sleep_sync.cc +++ b/lib/tsan/lit_tests/sleep_sync.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/sleep_sync2.cc b/lib/tsan/lit_tests/sleep_sync2.cc index d9961bccc808..e22999279f9f 100644 --- a/lib/tsan/lit_tests/sleep_sync2.cc +++ b/lib/tsan/lit_tests/sleep_sync2.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/stack_race.cc b/lib/tsan/lit_tests/stack_race.cc index beeb57353bf3..7fabce22a85c 100644 --- a/lib/tsan/lit_tests/stack_race.cc +++ b/lib/tsan/lit_tests/stack_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stddef.h> diff --git a/lib/tsan/lit_tests/stack_race2.cc b/lib/tsan/lit_tests/stack_race2.cc index 5bdf1bd664a1..c759ec92774f 100644 --- a/lib/tsan/lit_tests/stack_race2.cc +++ b/lib/tsan/lit_tests/stack_race2.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stddef.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/static_init3.cc b/lib/tsan/lit_tests/static_init3.cc index 40fd4b940f55..70a3c16878ca 100644 --- a/lib/tsan/lit_tests/static_init3.cc +++ b/lib/tsan/lit_tests/static_init3.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdlib.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/suppress_same_address.cc b/lib/tsan/lit_tests/suppress_same_address.cc index 174d1cc8fcb3..c516f89529f3 100644 --- a/lib/tsan/lit_tests/suppress_same_address.cc +++ b/lib/tsan/lit_tests/suppress_same_address.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> int X; diff --git a/lib/tsan/lit_tests/suppress_same_stacks.cc b/lib/tsan/lit_tests/suppress_same_stacks.cc index 32bff9d50071..f0ab8b30435e 100644 --- a/lib/tsan/lit_tests/suppress_same_stacks.cc +++ b/lib/tsan/lit_tests/suppress_same_stacks.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> volatile int N; // Prevent loop unrolling. diff --git a/lib/tsan/lit_tests/suppressions_global.cc b/lib/tsan/lit_tests/suppressions_global.cc new file mode 100644 index 000000000000..181cb56cf2e6 --- /dev/null +++ b/lib/tsan/lit_tests/suppressions_global.cc @@ -0,0 +1,29 @@ +// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> + +int RacyGlobal; + +void *Thread1(void *x) { + RacyGlobal = 42; + return NULL; +} + +void *Thread2(void *x) { + RacyGlobal = 43; + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + printf("OK\n"); + return 0; +} + +// CHECK-NOT: failed to open suppressions file +// CHECK-NOT: WARNING: ThreadSanitizer: data race + diff --git a/lib/tsan/lit_tests/suppressions_global.cc.supp b/lib/tsan/lit_tests/suppressions_global.cc.supp new file mode 100644 index 000000000000..5fa8a2e43a93 --- /dev/null +++ b/lib/tsan/lit_tests/suppressions_global.cc.supp @@ -0,0 +1,2 @@ +race:RacyGlobal + diff --git a/lib/tsan/lit_tests/suppressions_race.cc b/lib/tsan/lit_tests/suppressions_race.cc new file mode 100644 index 000000000000..c88e69bec6a3 --- /dev/null +++ b/lib/tsan/lit_tests/suppressions_race.cc @@ -0,0 +1,31 @@ +// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +int Global; + +void *Thread1(void *x) { + sleep(1); + Global = 42; + return NULL; +} + +void *Thread2(void *x) { + Global = 43; + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + printf("OK\n"); + return 0; +} + +// CHECK-NOT: failed to open suppressions file +// CHECK-NOT: WARNING: ThreadSanitizer: data race + diff --git a/lib/tsan/lit_tests/suppressions_race.cc.supp b/lib/tsan/lit_tests/suppressions_race.cc.supp new file mode 100644 index 000000000000..cbdba76ea93a --- /dev/null +++ b/lib/tsan/lit_tests/suppressions_race.cc.supp @@ -0,0 +1,2 @@ +race:Thread1 + diff --git a/lib/tsan/lit_tests/suppressions_race2.cc b/lib/tsan/lit_tests/suppressions_race2.cc new file mode 100644 index 000000000000..57146f96a428 --- /dev/null +++ b/lib/tsan/lit_tests/suppressions_race2.cc @@ -0,0 +1,31 @@ +// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +int Global; + +void *Thread1(void *x) { + Global = 42; + return NULL; +} + +void *Thread2(void *x) { + sleep(1); + Global = 43; + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + printf("OK\n"); + return 0; +} + +// CHECK-NOT: failed to open suppressions file +// CHECK-NOT: WARNING: ThreadSanitizer: data race + diff --git a/lib/tsan/lit_tests/suppressions_race2.cc.supp b/lib/tsan/lit_tests/suppressions_race2.cc.supp new file mode 100644 index 000000000000..b3c4dbc59363 --- /dev/null +++ b/lib/tsan/lit_tests/suppressions_race2.cc.supp @@ -0,0 +1,2 @@ +race:Thread2 + diff --git a/lib/tsan/lit_tests/test_output.sh b/lib/tsan/lit_tests/test_output.sh index 1eedf6eb20a3..79e773aa2c98 100755 --- a/lib/tsan/lit_tests/test_output.sh +++ b/lib/tsan/lit_tests/test_output.sh @@ -13,7 +13,7 @@ BLACKLIST=$ROOTDIR/lit_tests/Helpers/blacklist.txt # TODO: add testing for all of -O0...-O3 CFLAGS="-fsanitize=thread -fsanitize-blacklist=$BLACKLIST -fPIE -O1 -g -Wall" -LDFLAGS="-pie -lpthread -ldl $ROOTDIR/rtl/libtsan.a" +LDFLAGS="-pie -lpthread -ldl -lrt -Wl,--whole-archive $ROOTDIR/rtl/libtsan.a -Wl,--no-whole-archive" test_file() { SRC=$1 @@ -40,6 +40,10 @@ if [ "$1" == "" ]; then echo TEST $c is not supported continue fi + if [ "`grep "TSAN_OPTIONS" $c`" ]; then + echo SKIPPING $c -- requires TSAN_OPTIONS + continue + fi COMPILER=$CXX case $c in *.c) COMPILER=$CC diff --git a/lib/tsan/lit_tests/thread_leak3.c b/lib/tsan/lit_tests/thread_leak3.c index 3577164cad4a..5f447dbdbdf3 100644 --- a/lib/tsan/lit_tests/thread_leak3.c +++ b/lib/tsan/lit_tests/thread_leak3.c @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/thread_leak5.c b/lib/tsan/lit_tests/thread_leak5.c index fc72b149ec25..329f7233a38a 100644 --- a/lib/tsan/lit_tests/thread_leak5.c +++ b/lib/tsan/lit_tests/thread_leak5.c @@ -1,4 +1,4 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/thread_name.cc b/lib/tsan/lit_tests/thread_name.cc index 37f308ffbc0c..646ab5836241 100644 --- a/lib/tsan/lit_tests/thread_name.cc +++ b/lib/tsan/lit_tests/thread_name.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/thread_name2.cc b/lib/tsan/lit_tests/thread_name2.cc new file mode 100644 index 000000000000..8c5cb741f61f --- /dev/null +++ b/lib/tsan/lit_tests/thread_name2.cc @@ -0,0 +1,32 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +int Global; + +void *Thread1(void *x) { + sleep(1); + Global++; + return 0; +} + +void *Thread2(void *x) { + pthread_setname_np(pthread_self(), "foobar2"); + Global--; + return 0; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], 0, Thread1, 0); + pthread_create(&t[1], 0, Thread2, 0); + pthread_setname_np(t[0], "foobar1"); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); +} + +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK: Thread T1 'foobar1' +// CHECK: Thread T2 'foobar2' + diff --git a/lib/tsan/lit_tests/tiny_race.c b/lib/tsan/lit_tests/tiny_race.c index 44cc1332f2ab..f77e1606c1dd 100644 --- a/lib/tsan/lit_tests/tiny_race.c +++ b/lib/tsan/lit_tests/tiny_race.c @@ -1,15 +1,21 @@ -// RUN: %clang_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> +#include <unistd.h> + int Global; + void *Thread1(void *x) { + sleep(1); Global = 42; return x; } + int main() { pthread_t t; - pthread_create(&t, NULL, Thread1, NULL); + pthread_create(&t, 0, Thread1, 0); Global = 43; - pthread_join(t, NULL); + pthread_join(t, 0); return Global; } + // CHECK: WARNING: ThreadSanitizer: data race diff --git a/lib/tsan/lit_tests/tls_race.cc b/lib/tsan/lit_tests/tls_race.cc index bed6aafaacfc..3cbcc9dbba42 100644 --- a/lib/tsan/lit_tests/tls_race.cc +++ b/lib/tsan/lit_tests/tls_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stddef.h> diff --git a/lib/tsan/lit_tests/tls_race2.cc b/lib/tsan/lit_tests/tls_race2.cc index 110abaa6a9df..136087065c12 100644 --- a/lib/tsan/lit_tests/tls_race2.cc +++ b/lib/tsan/lit_tests/tls_race2.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stddef.h> #include <unistd.h> diff --git a/lib/tsan/lit_tests/unaligned_race.cc b/lib/tsan/lit_tests/unaligned_race.cc index 18bed8555cc5..6ac87b577ec5 100644 --- a/lib/tsan/lit_tests/unaligned_race.cc +++ b/lib/tsan/lit_tests/unaligned_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <stdio.h> #include <stdlib.h> diff --git a/lib/tsan/lit_tests/vptr_harmful_race.cc b/lib/tsan/lit_tests/vptr_harmful_race.cc index 76d31c00ad4f..0105c4cedd99 100644 --- a/lib/tsan/lit_tests/vptr_harmful_race.cc +++ b/lib/tsan/lit_tests/vptr_harmful_race.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <semaphore.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/vptr_harmful_race2.cc b/lib/tsan/lit_tests/vptr_harmful_race2.cc index d7e1d19a11bd..378790c62340 100644 --- a/lib/tsan/lit_tests/vptr_harmful_race2.cc +++ b/lib/tsan/lit_tests/vptr_harmful_race2.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <semaphore.h> #include <stdio.h> diff --git a/lib/tsan/lit_tests/write_in_reader_lock.cc b/lib/tsan/lit_tests/write_in_reader_lock.cc index db8bac32b6e4..e872fe3ff960 100644 --- a/lib/tsan/lit_tests/write_in_reader_lock.cc +++ b/lib/tsan/lit_tests/write_in_reader_lock.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> #include <unistd.h> |