From bdbabce2063e0ae1d0b19821c7df6cb39d5c2b44 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Thu, 1 Oct 2020 23:36:30 +0200 Subject: [PATCH] Fix ThreadSanitizer support by removing detaching of main thread upon program termination --- runtime/druntime | 2 +- tests/lit.site.cfg.in | 1 + tests/sanitizers/lit.local.cfg | 8 +++++--- tests/sanitizers/tsan_noerror.d | 5 +---- tests/sanitizers/tsan_tiny_race.d | 20 ++++++++------------ tests/sanitizers/tsan_tiny_race_TLS.d | 23 ++++++++++------------- 6 files changed, 26 insertions(+), 33 deletions(-) diff --git a/runtime/druntime b/runtime/druntime index c96906789b2..23513bfca56 160000 --- a/runtime/druntime +++ b/runtime/druntime @@ -1 +1 @@ -Subproject commit c96906789b234d6e76ce7c591102808a2fceb937 +Subproject commit 23513bfca561dfc32a601df9710c92ac31e03386 diff --git a/tests/lit.site.cfg.in b/tests/lit.site.cfg.in index cb51035a768..4784e001187 100644 --- a/tests/lit.site.cfg.in +++ b/tests/lit.site.cfg.in @@ -33,6 +33,7 @@ config.ldc_host_arch = "@LLVM_NATIVE_ARCH@" config.ldc_with_lld = @LDC_WITH_LLD@ config.spirv_enabled = @LLVM_SPIRV_FOUND@ config.rt_supports_sanitizers = @RT_SUPPORT_SANITIZERS@ +config.shared_rt_libs_only = "@BUILD_SHARED_LIBS@" == "ON" config.name = 'LDC' diff --git a/tests/sanitizers/lit.local.cfg b/tests/sanitizers/lit.local.cfg index bcd933d19e2..4b5dfe4e40f 100644 --- a/tests/sanitizers/lit.local.cfg +++ b/tests/sanitizers/lit.local.cfg @@ -2,14 +2,16 @@ import os import platform import re -# Add "ASan" and "Fuzzer" feature if the runtime library is available. +# Add "ASan", "TSan" and "Fuzzer" feature if the runtime library is available. +sys = platform.system() for file in os.listdir(config.ldc2_lib_dir): m = re.match('.*asan.*', file) if m is not None: config.available_features.add('ASan') continue - # FreeBSD TSan needs https://reviews.llvm.org/D85292 - if platform.system() != 'FreeBSD': + # FreeBSD TSan needs https://reviews.llvm.org/D85292, + # Linux TSan currently only works with static druntime. + if (sys != 'FreeBSD') and not (sys == 'Linux' and config.shared_rt_libs_only): m = re.match('.*tsan.*', file) if m is not None: config.available_features.add('TSan') diff --git a/tests/sanitizers/tsan_noerror.d b/tests/sanitizers/tsan_noerror.d index 1c21b0fb9d7..f8a4191cae5 100644 --- a/tests/sanitizers/tsan_noerror.d +++ b/tests/sanitizers/tsan_noerror.d @@ -1,10 +1,7 @@ // Test that a simple program passes ThreadSanitizer without error // REQUIRES: TSan - -// XFAIL: * -// Druntime does not yet work with ThreadSanitizer. -// See Github issue 3519 (https://github.com/ldc-developers/ldc/issues/3519) +// REQUIRES: atleast_llvm800 // RUN: %ldc -fsanitize=thread %s -of=%t%exe // RUN: %t%exe diff --git a/tests/sanitizers/tsan_tiny_race.d b/tests/sanitizers/tsan_tiny_race.d index 7bd0326af43..0d301fbbe51 100644 --- a/tests/sanitizers/tsan_tiny_race.d +++ b/tests/sanitizers/tsan_tiny_race.d @@ -1,35 +1,31 @@ // Test that ThreadSanitizer+LDC works on a very basic testcase. -// Note that -betterC is used, to avoid relying on druntime for this test. // REQUIRES: TSan // REQUIRES: atleast_llvm800 -// RUN: %ldc -betterC -g -fsanitize=thread %s -of=%t%exe +// RUN: %ldc -g -fsanitize=thread %s -of=%t%exe // RUN: %deflake 20 %t%exe | FileCheck %s // CHECK: WARNING: ThreadSanitizer: data race -import core.sys.posix.pthread; +import core.thread; shared int global; -extern(C) -void *thread1(void *x) { +void thread1() { barrier_wait(&barrier); -// CHECK-DAG: thread1{{.*}}[[@LINE+1]] +// CHECK-DAG: 7thread1{{.*}}[[@LINE+1]] global = 42; - return x; } -extern(C) int main() { barrier_init(&barrier, 2); - pthread_t t; - pthread_create(&t, null, &thread1, null); -// CHECK-DAG: main{{.*}}[[@LINE+1]] + auto t = new Thread(&thread1); + t.start(); +// CHECK-DAG: _Dmain{{.*}}[[@LINE+1]] global = 43; barrier_wait(&barrier); - pthread_join(t, null); + t.join(); return global; } diff --git a/tests/sanitizers/tsan_tiny_race_TLS.d b/tests/sanitizers/tsan_tiny_race_TLS.d index 0fbd616911f..70f4a51f3b9 100644 --- a/tests/sanitizers/tsan_tiny_race_TLS.d +++ b/tests/sanitizers/tsan_tiny_race_TLS.d @@ -1,34 +1,29 @@ // Test that ThreadSanitizer+LDC works on a very basic testcase. -// Note that -betterC is used, to avoid relying on druntime for this test. // REQUIRES: TSan // REQUIRES: atleast_llvm800 -// RUN: %ldc -betterC -g -fsanitize=thread %s -of=%t%exe +// RUN: %ldc -g -fsanitize=thread %s -of=%t%exe // RUN: %deflake 20 %t%exe | FileCheck %s // CHECK: WARNING: ThreadSanitizer: data race -import core.sys.posix.pthread; +import core.thread; -extern(C) -void *thread1(void *x) { +void thread1(ref int x) nothrow { barrier_wait(&barrier); -// CHECK-DAG: thread1{{.*}}[[@LINE+1]] - *cast(int*)x = 42; - return x; +// CHECK-DAG: 7thread1{{.*}}[[@LINE+1]] + x = 42; } -extern(C) int main() { int tls_variable; barrier_init(&barrier, 2); - pthread_t t; - pthread_create(&t, null, &thread1, &tls_variable); -// CHECK-DAG: main{{.*}}[[@LINE+1]] + auto tid = createLowLevelThread(() { thread1(tls_variable); }); +// CHECK-DAG: _Dmain{{.*}}[[@LINE+1]] tls_variable = 43; barrier_wait(&barrier); - pthread_join(t, null); + joinLowLevelThread(tid); return 0; } @@ -45,6 +40,8 @@ alias __c_unsigned = uint; // Default instance of the barrier, but a test can declare more manually. __gshared invisible_barrier_t barrier; +nothrow: + extern (C) { // These functions reside inside the tsan library. void __tsan_testonly_barrier_init(invisible_barrier_t *barrier, __c_unsigned count);