diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-26 19:24:20 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-26 19:24:20 +0000 |
commit | 2953104c9a262728031dc518429d15b969dd6028 (patch) | |
tree | d4fff23823637f2256cedf634a2be262862ea90f /test | |
parent | f351c8a560ddc5b5df9ee5ba4ccc1cfb9029146d (diff) |
Notes
Diffstat (limited to 'test')
29 files changed, 387 insertions, 164 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index addc579973bbb..7685fb3f426f1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -41,47 +41,49 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS) if(COMPILER_RT_BUILD_BUILTINS) add_subdirectory(builtins) endif() - if(COMPILER_RT_HAS_ASAN) - add_subdirectory(asan) - endif() - if(COMPILER_RT_HAS_DFSAN) - add_subdirectory(dfsan) - endif() - if (COMPILER_RT_HAS_INTERCEPTION) - add_subdirectory(interception) - endif() - if(COMPILER_RT_HAS_LSAN) - add_subdirectory(lsan) - endif() - if(COMPILER_RT_HAS_MSAN) - add_subdirectory(msan) - endif() - if(COMPILER_RT_HAS_PROFILE) - add_subdirectory(profile) - endif() - if(COMPILER_RT_HAS_SANITIZER_COMMON) - add_subdirectory(sanitizer_common) - endif() - if(COMPILER_RT_HAS_TSAN) - add_subdirectory(tsan) - endif() - if(COMPILER_RT_HAS_UBSAN) - add_subdirectory(ubsan) - endif() - # CFI tests require diagnostic mode, which is implemented in UBSan. - if(COMPILER_RT_HAS_UBSAN) - add_subdirectory(cfi) - endif() - if(COMPILER_RT_HAS_SAFESTACK) - add_subdirectory(safestack) - endif() - if(COMPILER_RT_HAS_ESAN) - add_subdirectory(esan) - endif() - if(COMPILER_RT_HAS_SCUDO) - add_subdirectory(scudo) + if(COMPILER_RT_BUILD_SANITIZERS) + if(COMPILER_RT_HAS_ASAN) + add_subdirectory(asan) + endif() + if(COMPILER_RT_HAS_DFSAN) + add_subdirectory(dfsan) + endif() + if (COMPILER_RT_HAS_INTERCEPTION) + add_subdirectory(interception) + endif() + if(COMPILER_RT_HAS_LSAN) + add_subdirectory(lsan) + endif() + if(COMPILER_RT_HAS_MSAN) + add_subdirectory(msan) + endif() + if(COMPILER_RT_HAS_PROFILE) + add_subdirectory(profile) + endif() + if(COMPILER_RT_HAS_SANITIZER_COMMON) + add_subdirectory(sanitizer_common) + endif() + if(COMPILER_RT_HAS_TSAN) + add_subdirectory(tsan) + endif() + if(COMPILER_RT_HAS_UBSAN) + add_subdirectory(ubsan) + endif() + # CFI tests require diagnostic mode, which is implemented in UBSan. + if(COMPILER_RT_HAS_UBSAN) + add_subdirectory(cfi) + endif() + if(COMPILER_RT_HAS_SAFESTACK) + add_subdirectory(safestack) + endif() + if(COMPILER_RT_HAS_ESAN) + add_subdirectory(esan) + endif() + if(COMPILER_RT_HAS_SCUDO) + add_subdirectory(scudo) + endif() endif() - if(COMPILER_RT_HAS_XRAY) + if(COMPILER_RT_BUILD_XRAY AND COMPILER_RT_HAS_XRAY) add_subdirectory(xray) endif() endif() diff --git a/test/asan/TestCases/Linux/read_binary_name_regtest.c b/test/asan/TestCases/Linux/read_binary_name_regtest.c index b09096c89cb7d..41302567752ca 100644 --- a/test/asan/TestCases/Linux/read_binary_name_regtest.c +++ b/test/asan/TestCases/Linux/read_binary_name_regtest.c @@ -3,6 +3,7 @@ // This test uses seccomp-BPF to restrict the readlink() system call and makes // sure ASan is still able to // RUN: not ls /usr/include/linux/seccomp.h || ( %clang_asan %s -o %t && not %run %t 2>&1 | FileCheck %s ) +// REQUIRES: shell // UNSUPPORTED: android #include <errno.h> diff --git a/test/asan/TestCases/Linux/textdomain.c b/test/asan/TestCases/Linux/textdomain.c new file mode 100644 index 0000000000000..31e5139c9f7c4 --- /dev/null +++ b/test/asan/TestCases/Linux/textdomain.c @@ -0,0 +1,10 @@ +// RUN: %clang_asan -O0 -g %s -o %t +// RUN: %env_asan_opts=strict_string_checks=1 %run %t + +#include <stdlib.h> +#include <libintl.h> + +int main() { + textdomain(NULL); + return 0; +} diff --git a/test/asan/TestCases/Posix/strchr.c b/test/asan/TestCases/Posix/strchr.c index df854d79ec825..7086e1374523f 100644 --- a/test/asan/TestCases/Posix/strchr.c +++ b/test/asan/TestCases/Posix/strchr.c @@ -27,9 +27,7 @@ int main(int argc, char **argv) { if (mprotect(p + 1, 1, PROT_NONE)) return 1; char *r = strchr(s, 'x'); - // CHECK: AddressSanitizer: SEGV on unknown address - // CHECK: The signal is caused by a READ memory access - // CHECK: strchr.c:[[@LINE-3]] + // CHECK: AddressSanitizer: {{SEGV|BUS}} on unknown address assert(r == p); return 0; diff --git a/test/asan/TestCases/Windows/dll_global_dead_strip.c b/test/asan/TestCases/Windows/dll_global_dead_strip.c index 2664f5baff6c0..15cfd5a7ddbf6 100644 --- a/test/asan/TestCases/Windows/dll_global_dead_strip.c +++ b/test/asan/TestCases/Windows/dll_global_dead_strip.c @@ -1,8 +1,8 @@ // RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t // -// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll +// RUN: %clang_cl_asan /Gw -LD -O0 %s -Fe%t.dll // RUN: %env_asan_opts=report_globals=2 %run %t %t.dll 2>&1 | FileCheck %s --check-prefix=NOSTRIP -// RUN: %clang_cl_asan -LD -O2 %s -Fe%t.dll -link -opt:ref +// RUN: %clang_cl_asan /Gw -LD -O2 %s -Fe%t.dll -link -opt:ref // RUN: %env_asan_opts=report_globals=2 %run %t %t.dll 2>&1 | FileCheck %s --check-prefix=STRIP #include <stdio.h> diff --git a/test/asan/TestCases/Windows/fuse-lld.cc b/test/asan/TestCases/Windows/fuse-lld.cc index 7fa5d4e8a80a2..c20e5ff6c786e 100644 --- a/test/asan/TestCases/Windows/fuse-lld.cc +++ b/test/asan/TestCases/Windows/fuse-lld.cc @@ -1,6 +1,6 @@ // If we have LLD, see that things more or less work. // -// REQUIRES: lld +// REQUIRES: lld-available // // FIXME: Use -fuse-ld=lld after the old COFF linker is removed. // FIXME: Test will fail until we add flags for requesting dwarf or cv. diff --git a/test/asan/TestCases/Windows/global_dead_strip.c b/test/asan/TestCases/Windows/global_dead_strip.c index e68549050be6f..2121392d92686 100644 --- a/test/asan/TestCases/Windows/global_dead_strip.c +++ b/test/asan/TestCases/Windows/global_dead_strip.c @@ -1,6 +1,6 @@ -// RUN: %clang_cl_asan /O0 %s /Fe%t.exe +// RUN: %clang_cl_asan /Gw /O0 %s /Fe%t.exe // RUN: %env_asan_opts=report_globals=2 %t.exe 2>&1 | FileCheck %s --check-prefix=NOSTRIP -// RUN: %clang_cl_asan /O2 %s /Fe%t.exe -link -opt:ref +// RUN: %clang_cl_asan /Gw /O2 %s /Fe%t.exe -link -opt:ref // RUN: %env_asan_opts=report_globals=2 %t.exe 2>&1 | FileCheck %s --check-prefix=STRIP #include <stdio.h> diff --git a/test/asan/android_commands/android_run.py b/test/asan/android_commands/android_run.py index f4ea52bec5880..7e599453d1c47 100755 --- a/test/asan/android_commands/android_run.py +++ b/test/asan/android_commands/android_run.py @@ -18,15 +18,14 @@ def build_env(): return ' '.join(args) is_64bit = (subprocess.check_output(['file', sys.argv[0] + '.real']).find('64-bit') != -1) -asanwrapper = "" if is_64bit else "asanwrapper " device_env = build_env() device_args = ' '.join(sys.argv[1:]) # FIXME: escape? device_stdout = device_binary + '.stdout' device_stderr = device_binary + '.stderr' device_exitcode = device_binary + '.exitcode' -ret = adb(['shell', 'cd %s && %s %s%s %s >%s 2>%s ; echo $? >%s' % - (ANDROID_TMPDIR, device_env, asanwrapper, device_binary, device_args, +ret = adb(['shell', 'cd %s && %s %s %s >%s 2>%s ; echo $? >%s' % + (ANDROID_TMPDIR, device_env, device_binary, device_args, device_stdout, device_stderr, device_exitcode)]) if ret != 0: sys.exit(ret) diff --git a/test/cfi/CMakeLists.txt b/test/cfi/CMakeLists.txt index c3123a8204ebb..fb45f2f400ce1 100644 --- a/test/cfi/CMakeLists.txt +++ b/test/cfi/CMakeLists.txt @@ -1,14 +1,48 @@ -set(CFI_LIT_TEST_MODE Standalone) -configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/Standalone/lit.site.cfg - ) +set(CFI_TESTSUITES) -set(CFI_LIT_TEST_MODE Devirt) -configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/Devirt/lit.site.cfg - ) +macro (add_cfi_test_suites lld thinlto) + set(suffix) + if (${lld}) + set(suffix ${suffix}-lld) + endif() + if (${thinlto}) + set(suffix ${suffix}-thinlto) + endif() + + set(CFI_TEST_USE_LLD ${lld}) + set(CFI_TEST_USE_THINLTO ${thinlto}) + + set(CFI_LIT_TEST_MODE Standalone) + set(CFI_TEST_CONFIG_SUFFIX -standalone${suffix}) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/Standalone${suffix}/lit.site.cfg + ) + list(APPEND CFI_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Standalone${suffix}) + + set(CFI_LIT_TEST_MODE Devirt) + set(CFI_TEST_CONFIG_SUFFIX -devirt${suffix}) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/Devirt${suffix}/lit.site.cfg + ) + list(APPEND CFI_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Devirt${suffix}) +endmacro() + +if (APPLE) + # FIXME: enable ThinLTO tests after fixing http://llvm.org/pr32741 + add_cfi_test_suites(False False) +elseif(WIN32) + # FIXME: enable ThinLTO tests after fixing http://llvm.org/pr32770 + add_cfi_test_suites(True False) +else() + add_cfi_test_suites(False False) + add_cfi_test_suites(False True) + if (COMPILER_RT_HAS_LLD) + add_cfi_test_suites(True False) + add_cfi_test_suites(True True) + endif() +endif() set(CFI_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) list(APPEND CFI_TEST_DEPS @@ -34,7 +68,7 @@ if(NOT COMPILER_RT_STANDALONE_BUILD) LTO ) endif() - if(WIN32 AND COMPILER_RT_HAS_LLD) + if(NOT APPLE AND COMPILER_RT_HAS_LLD) list(APPEND CFI_TEST_DEPS lld ) @@ -42,13 +76,11 @@ if(NOT COMPILER_RT_STANDALONE_BUILD) endif() add_lit_testsuite(check-cfi "Running the cfi regression tests" - ${CMAKE_CURRENT_BINARY_DIR}/Standalone - ${CMAKE_CURRENT_BINARY_DIR}/Devirt + ${CFI_TESTSUITES} DEPENDS ${CFI_TEST_DEPS}) add_lit_target(check-cfi-and-supported "Running the cfi regression tests" - ${CMAKE_CURRENT_BINARY_DIR}/Standalone - ${CMAKE_CURRENT_BINARY_DIR}/Devirt + ${CFI_TESTSUITES} PARAMS check_supported=1 DEPENDS ${CFI_TEST_DEPS}) diff --git a/test/cfi/create-derivers.test b/test/cfi/create-derivers.test index a67562b1a6c8a..8b569d001d89f 100644 --- a/test/cfi/create-derivers.test +++ b/test/cfi/create-derivers.test @@ -1,20 +1,21 @@ REQUIRES: asserts -RUN: %clangxx_cfi -c -o %t1.o %S/simple-fail.cpp +%% Explicit -flto to override possible -flto=thin in %clangxx_cfi +RUN: %clangxx_cfi -flto -c -o %t1.o %S/simple-fail.cpp RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t1.o 2>&1 | FileCheck --check-prefix=B0 %s B0: {{1B|B@@}}: {{.*}} size 1 -RUN: %clangxx_cfi -DB32 -c -o %t2.o %S/simple-fail.cpp +RUN: %clangxx_cfi -DB32 -flto -c -o %t2.o %S/simple-fail.cpp RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t2.o 2>&1 | FileCheck --check-prefix=B32 %s B32: {{1B|B@@}}: {{.*}} size 24 B32-NOT: all-ones -RUN: %clangxx_cfi -DB64 -c -o %t3.o %S/simple-fail.cpp +RUN: %clangxx_cfi -DB64 -flto -c -o %t3.o %S/simple-fail.cpp RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t3.o 2>&1 | FileCheck --check-prefix=B64 %s B64: {{1B|B@@}}: {{.*}} size 54 B64-NOT: all-ones -RUN: %clangxx_cfi -DBM -c -o %t4.o %S/simple-fail.cpp +RUN: %clangxx_cfi -DBM -flto -c -o %t4.o %S/simple-fail.cpp RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t4.o 2>&1 | FileCheck --check-prefix=BM %s BM: {{1B|B@@}}: {{.*}} size 84 BM-NOT: all-ones diff --git a/test/cfi/cross-dso/dlopen.cpp b/test/cfi/cross-dso/icall/dlopen.cpp index ee4dae2b5f7d6..d238a7acec890 100644 --- a/test/cfi/cross-dso/dlopen.cpp +++ b/test/cfi/cross-dso/icall/dlopen.cpp @@ -55,7 +55,7 @@ struct A { #ifdef SHARED_LIB -#include "../utils.h" +#include "../../utils.h" struct B { virtual void f(); }; diff --git a/test/cfi/cross-dso/icall/lit.local.cfg b/test/cfi/cross-dso/icall/lit.local.cfg index db08765a2bb29..322b287a6396c 100644 --- a/test/cfi/cross-dso/icall/lit.local.cfg +++ b/test/cfi/cross-dso/icall/lit.local.cfg @@ -1,3 +1,6 @@ # The cfi-icall checker is only supported on x86 and x86_64 for now. if config.root.host_arch not in ['x86', 'x86_64']: config.unsupported = True + +if config.root.use_thinlto: + config.unsupported = True diff --git a/test/cfi/cross-dso/stats.cpp b/test/cfi/cross-dso/stats.cpp index 6566ea2fc2633..fb98a50a3e78d 100644 --- a/test/cfi/cross-dso/stats.cpp +++ b/test/cfi/cross-dso/stats.cpp @@ -3,6 +3,10 @@ // RUN: env SANITIZER_STATS_PATH=%t.stats %t // RUN: sanstats %t.stats | FileCheck %s +// CFI-icall is not implemented in thinlto mode => ".cfi" suffixes are missing +// in sanstats output. +// XFAIL: thinlto + struct ABase {}; struct A : ABase { diff --git a/test/cfi/icall/lit.local.cfg b/test/cfi/icall/lit.local.cfg index db08765a2bb29..44891c5e2de30 100644 --- a/test/cfi/icall/lit.local.cfg +++ b/test/cfi/icall/lit.local.cfg @@ -1,3 +1,6 @@ # The cfi-icall checker is only supported on x86 and x86_64 for now. if config.root.host_arch not in ['x86', 'x86_64']: config.unsupported = True + +if config.use_thinlto: + config.unsupported = True diff --git a/test/cfi/lit.cfg b/test/cfi/lit.cfg index 3c0250632f5b4..314ba5ce9e069 100644 --- a/test/cfi/lit.cfg +++ b/test/cfi/lit.cfg @@ -1,7 +1,7 @@ import lit.formats import os -config.name = 'cfi' +config.name = 'cfi' + config.name_suffix config.suffixes = ['.c', '.cpp', '.test'] config.test_source_root = os.path.dirname(__file__) @@ -10,7 +10,7 @@ clangxx = ' '.join([config.clang] + config.cxx_mode_flags) config.substitutions.append((r"%clang ", ' '.join([config.clang]) + ' ')) config.substitutions.append((r"%clangxx ", clangxx + ' ')) if config.lto_supported: - clang_cfi = ' '.join(config.lto_launch + [config.clang] + config.lto_flags + ['-flto -fsanitize=cfi ']) + clang_cfi = ' '.join(config.lto_launch + [config.clang] + config.lto_flags + ['-fsanitize=cfi ']) if config.cfi_lit_test_mode == "Devirt": config.available_features.add('devirt') diff --git a/test/cfi/lit.site.cfg.in b/test/cfi/lit.site.cfg.in index 87e5b51e7c022..63611f659f16c 100644 --- a/test/cfi/lit.site.cfg.in +++ b/test/cfi/lit.site.cfg.in @@ -1,6 +1,9 @@ @LIT_SITE_CFG_IN_HEADER@ +config.name_suffix = "@CFI_TEST_CONFIG_SUFFIX@" config.cfi_lit_test_mode = "@CFI_LIT_TEST_MODE@" +config.use_lld = @CFI_TEST_USE_LLD@ +config.use_thinlto = @CFI_TEST_USE_THINLTO@ lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured") lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg") diff --git a/test/lit.common.cfg b/test/lit.common.cfg index d59d7d6681157..4b03a5504221a 100644 --- a/test/lit.common.cfg +++ b/test/lit.common.cfg @@ -129,6 +129,9 @@ if sanitizer_can_use_cxxabi: config.available_features.add('cxxabi') if config.has_lld: + config.available_features.add('lld-available') + +if config.use_lld: config.available_features.add('lld') if config.can_symbolize: @@ -180,6 +183,9 @@ def is_darwin_lto_supported(): return os.path.exists(os.path.join(config.llvm_shlib_dir, 'libLTO.dylib')) def is_linux_lto_supported(): + if config.use_lld: + return True + if not os.path.exists(os.path.join(config.llvm_shlib_dir, 'LLVMgold.so')): return False @@ -202,7 +208,10 @@ if config.host_os == 'Darwin' and is_darwin_lto_supported(): elif config.host_os == 'Linux' and is_linux_lto_supported(): config.lto_supported = True config.lto_launch = [] - config.lto_flags = ["-fuse-ld=gold"] + if config.use_lld: + config.lto_flags = ["-fuse-ld=lld"] + else: + config.lto_flags = ["-fuse-ld=gold"] elif config.host_os == 'Windows' and is_windows_lto_supported(): config.lto_supported = True config.lto_launch = [] @@ -213,6 +222,11 @@ else: if config.lto_supported: config.available_features.add('lto') + if config.use_thinlto: + config.available_features.add('thinlto') + config.lto_flags += ["-flto=thin"] + else: + config.lto_flags += ["-flto"] # Ask llvm-config about assertion mode. try: diff --git a/test/lit.common.configured.in b/test/lit.common.configured.in index 387f4d4a743bc..0ad03a1800427 100644 --- a/test/lit.common.configured.in +++ b/test/lit.common.configured.in @@ -28,6 +28,8 @@ set_default("emulator", "@COMPILER_RT_EMULATOR@") set_default("sanitizer_can_use_cxxabi", @SANITIZER_CAN_USE_CXXABI_PYBOOL@) set_default("has_lld", @COMPILER_RT_HAS_LLD_PYBOOL@) set_default("can_symbolize", @CAN_SYMBOLIZE@) +set_default("use_lld", False) +set_default("use_thinlto", False) config.available_features.add('target-is-%s' % config.target_arch) # LLVM tools dir can be passed in lit parameters, so try to diff --git a/test/lsan/lit.common.cfg b/test/lsan/lit.common.cfg index 7020bd8473e55..da439d4c02822 100644 --- a/test/lsan/lit.common.cfg +++ b/test/lsan/lit.common.cfg @@ -67,8 +67,9 @@ config.substitutions.append( ("%clangxx ", build_invocation(clang_cxxflags)) ) config.substitutions.append( ("%clang_lsan ", build_invocation(clang_lsan_cflags)) ) config.substitutions.append( ("%clangxx_lsan ", build_invocation(clang_lsan_cxxflags)) ) -# LeakSanitizer tests are currently supported on x86-64 Linux, arm Linux and mips64 Linux only. -if config.host_os not in ['Linux'] or config.host_arch not in ['x86_64', 'mips64', 'arm', 'armhf', 'armv7l']: +# LeakSanitizer tests are currently supported on x86-64 Linux, PowerPC64 Linux, arm Linux, and mips64 Linux only. +supported_linux = config.host_os is 'Linux' and config.host_arch in ['x86_64', 'ppc64', 'mips64', 'arm', 'armhf', 'armv7l'] +if not (supported_linux): config.unsupported = True # Don't support Thumb due to broken fast unwinder diff --git a/test/safestack/lit.cfg b/test/safestack/lit.cfg index d4ec73ce703b0..fb5672936f284 100644 --- a/test/safestack/lit.cfg +++ b/test/safestack/lit.cfg @@ -16,7 +16,7 @@ config.substitutions.append( ("%clang_nosafestack ", config.clang + " -O0 -fno-s config.substitutions.append( ("%clang_safestack ", config.clang + " -O0 -fsanitize=safe-stack ") ) if config.lto_supported: - config.substitutions.append((r"%clang_lto_safestack ", ' '.join(config.lto_launch + [config.clang] + config.lto_flags + ['-flto -fsanitize=safe-stack ']))) + config.substitutions.append((r"%clang_lto_safestack ", ' '.join(config.lto_launch + [config.clang] + config.lto_flags + ['-fsanitize=safe-stack ']))) # SafeStack tests are currently supported on Linux, FreeBSD and Darwin only. if config.host_os not in ['Linux', 'FreeBSD', 'Darwin']: diff --git a/test/tsan/Darwin/deadlock.mm b/test/tsan/Darwin/deadlock.mm new file mode 100644 index 0000000000000..36ddfad54f7c9 --- /dev/null +++ b/test/tsan/Darwin/deadlock.mm @@ -0,0 +1,47 @@ +// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %deflake %run %t 2>&1 | FileCheck %s + +#import <Foundation/Foundation.h> + +#import "../test.h" + +pthread_mutex_t m1; +pthread_mutex_t m2; + +int main(int argc, const char *argv[]) { + barrier_init(&barrier, 2); + fprintf(stderr, "Hello world.\n"); + + pthread_mutex_init(&m1, NULL); + pthread_mutex_init(&m2, NULL); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + pthread_mutex_lock(&m1); + pthread_mutex_lock(&m2); + pthread_mutex_unlock(&m2); + pthread_mutex_unlock(&m1); + + barrier_wait(&barrier); + }); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + barrier_wait(&barrier); + + pthread_mutex_lock(&m2); + pthread_mutex_lock(&m1); + pthread_mutex_unlock(&m1); + pthread_mutex_unlock(&m2); + + dispatch_sync(dispatch_get_main_queue(), ^{ + CFRunLoopStop(CFRunLoopGetCurrent()); + }); + }); + + CFRunLoopRun(); + + fprintf(stderr, "Done.\n"); + return 0; +} + +// CHECK: Hello world. +// CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) +// CHECK: Done. diff --git a/test/tsan/Darwin/debug_external.cc b/test/tsan/Darwin/debug_external.cc index 217690fc5dd01..2418a271b23c9 100644 --- a/test/tsan/Darwin/debug_external.cc +++ b/test/tsan/Darwin/debug_external.cc @@ -17,8 +17,6 @@ int __tsan_get_report_loc(void *report, unsigned long idx, const char **type, unsigned long trace_size); int __tsan_get_report_loc_object_type(void *report, unsigned long idx, const char **object_type); -void *__tsan_external_register_tag(const char *object_type); -void __tsan_external_assign_tag(void *addr, void *tag); } void *Thread(void *arg) { diff --git a/test/tsan/Darwin/external-dups.cc b/test/tsan/Darwin/external-dups.cc new file mode 100644 index 0000000000000..79432bac4a025 --- /dev/null +++ b/test/tsan/Darwin/external-dups.cc @@ -0,0 +1,58 @@ +// RUN: %clangxx_tsan %s -o %t +// RUN: %deflake %run %t 2>&1 | FileCheck %s + +#include <thread> + +#import "../test.h" + +void *tag; + +__attribute__((no_sanitize("thread"))) +void ExternalWrite(void *addr) { + __tsan_external_write(addr, __builtin_return_address(0), tag); +} + +int main(int argc, char *argv[]) { + barrier_init(&barrier, 2); + tag = __tsan_external_register_tag("HelloWorld"); + fprintf(stderr, "Start.\n"); + // CHECK: Start. + + for (int i = 0; i < 4; i++) { + void *opaque_object = malloc(16); + std::thread t1([opaque_object] { + ExternalWrite(opaque_object); + barrier_wait(&barrier); + }); + std::thread t2([opaque_object] { + barrier_wait(&barrier); + ExternalWrite(opaque_object); + }); + // CHECK: WARNING: ThreadSanitizer: race on a library object + t1.join(); + t2.join(); + } + + fprintf(stderr, "First phase done.\n"); + // CHECK: First phase done. + + for (int i = 0; i < 4; i++) { + void *opaque_object = malloc(16); + std::thread t1([opaque_object] { + ExternalWrite(opaque_object); + barrier_wait(&barrier); + }); + std::thread t2([opaque_object] { + barrier_wait(&barrier); + ExternalWrite(opaque_object); + }); + // CHECK: WARNING: ThreadSanitizer: race on a library object + t1.join(); + t2.join(); + } + + fprintf(stderr, "Second phase done.\n"); + // CHECK: Second phase done. +} + +// CHECK: ThreadSanitizer: reported 2 warnings diff --git a/test/tsan/Darwin/external-ignore-noninstrumented.cc b/test/tsan/Darwin/external-ignore-noninstrumented.cc new file mode 100644 index 0000000000000..d2acaf54b2631 --- /dev/null +++ b/test/tsan/Darwin/external-ignore-noninstrumented.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_tsan -shared %p/external-lib.cc -fno-sanitize=thread -DUSE_TSAN_CALLBACKS \ +// RUN: -o %t-lib.dylib -install_name @rpath/`basename %t-lib.dylib` + +// RUN: %clangxx_tsan -shared %p/external-noninstrumented-module.cc %t-lib.dylib -fno-sanitize=thread \ +// RUN: -o %t-module.dylib -install_name @rpath/`basename %t-module.dylib` + +// RUN: %clangxx_tsan %s %t-module.dylib -o %t +// RUN: %run %t 2>&1 | FileCheck %s + +#include <stdio.h> + +extern "C" void NonInstrumentedModule(); +int main(int argc, char *argv[]) { + NonInstrumentedModule(); + fprintf(stderr, "Done.\n"); +} + +// CHECK-NOT: WARNING: ThreadSanitizer +// CHECK: Done. diff --git a/test/tsan/Darwin/external-lib.cc b/test/tsan/Darwin/external-lib.cc new file mode 100644 index 0000000000000..f0afdf1dc0603 --- /dev/null +++ b/test/tsan/Darwin/external-lib.cc @@ -0,0 +1,68 @@ +// This file is used from other tests. +// RUN: true + +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +struct MyObject; +typedef MyObject *MyObjectRef; +extern "C" { + void InitializeLibrary(); + MyObject *ObjectCreate(); + long ObjectRead(MyObject *); + void ObjectWrite(MyObject *, long); + void ObjectWriteAnother(MyObject *, long); +} + +struct MyObject { + long _val; + long _another; +}; + +#if defined(USE_TSAN_CALLBACKS) +static void *tag; +void *(*callback_register_tag)(const char *object_type); +void *(*callback_assign_tag)(void *addr, void *tag); +void (*callback_read)(void *addr, void *caller_pc, void *tag); +void (*callback_write)(void *addr, void *caller_pc, void *tag); +#endif + +void InitializeLibrary() { +#if defined(USE_TSAN_CALLBACKS) + callback_register_tag = (decltype(callback_register_tag))dlsym(RTLD_DEFAULT, "__tsan_external_register_tag"); + callback_assign_tag = (decltype(callback_assign_tag))dlsym(RTLD_DEFAULT, "__tsan_external_assign_tag"); + callback_read = (decltype(callback_read))dlsym(RTLD_DEFAULT, "__tsan_external_read"); + callback_write = (decltype(callback_write))dlsym(RTLD_DEFAULT, "__tsan_external_write"); + tag = callback_register_tag("MyLibrary::MyObject"); +#endif +} + +MyObject *ObjectCreate() { + MyObject *ref = (MyObject *)malloc(sizeof(MyObject)); +#if defined(USE_TSAN_CALLBACKS) + callback_assign_tag(ref, tag); +#endif + return ref; +} + +long ObjectRead(MyObject *ref) { +#if defined(USE_TSAN_CALLBACKS) + callback_read(ref, __builtin_return_address(0), tag); +#endif + return ref->_val; +} + +void ObjectWrite(MyObject *ref, long val) { +#if defined(USE_TSAN_CALLBACKS) + callback_write(ref, __builtin_return_address(0), tag); +#endif + ref->_val = val; +} + +void ObjectWriteAnother(MyObject *ref, long val) { +#if defined(USE_TSAN_CALLBACKS) + callback_write(ref, __builtin_return_address(0), tag); +#endif + ref->_another = val; +} diff --git a/test/tsan/Darwin/external-noninstrumented-module.cc b/test/tsan/Darwin/external-noninstrumented-module.cc new file mode 100644 index 0000000000000..ce65970834e51 --- /dev/null +++ b/test/tsan/Darwin/external-noninstrumented-module.cc @@ -0,0 +1,27 @@ +// This file is used from other tests. +// RUN: true + +#include <thread> + +#include <stdio.h> +#include <stdlib.h> + +struct MyObject; +typedef MyObject *MyObjectRef; +extern "C" { + void InitializeLibrary(); + MyObject *ObjectCreate(); + long ObjectRead(MyObject *); + void ObjectWrite(MyObject *, long); + void ObjectWriteAnother(MyObject *, long); +} + +extern "C" void NonInstrumentedModule() { + InitializeLibrary(); + + MyObjectRef ref = ObjectCreate(); + std::thread t1([ref]{ ObjectWrite(ref, 42); }); + std::thread t2([ref]{ ObjectWrite(ref, 43); }); + t1.join(); + t2.join(); +} diff --git a/test/tsan/Darwin/external.cc b/test/tsan/Darwin/external.cc index 2605480d7b82d..211694ab7db19 100644 --- a/test/tsan/Darwin/external.cc +++ b/test/tsan/Darwin/external.cc @@ -1,12 +1,12 @@ -// RUN: %clangxx_tsan %s -shared -DSHARED_LIB \ +// RUN: %clangxx_tsan %p/external-lib.cc -shared \ // RUN: -o %t-lib-instrumented.dylib \ // RUN: -install_name @rpath/`basename %t-lib-instrumented.dylib` -// RUN: %clangxx_tsan %s -shared -DSHARED_LIB -fno-sanitize=thread \ +// RUN: %clangxx_tsan %p/external-lib.cc -shared -fno-sanitize=thread \ // RUN: -o %t-lib-noninstrumented.dylib \ // RUN: -install_name @rpath/`basename %t-lib-noninstrumented.dylib` -// RUN: %clangxx_tsan %s -shared -DSHARED_LIB -fno-sanitize=thread -DUSE_TSAN_CALLBACKS \ +// RUN: %clangxx_tsan %p/external-lib.cc -shared -fno-sanitize=thread -DUSE_TSAN_CALLBACKS \ // RUN: -o %t-lib-noninstrumented-callbacks.dylib \ // RUN: -install_name @rpath/`basename %t-lib-noninstrumented-callbacks.dylib` @@ -23,8 +23,6 @@ #include <thread> -#include <dlfcn.h> -#include <pthread.h> #include <stdio.h> #include <stdlib.h> @@ -38,62 +36,6 @@ extern "C" { void ObjectWriteAnother(MyObject *, long); } -#if defined(SHARED_LIB) - -struct MyObject { - long _val; - long _another; -}; - -#if defined(USE_TSAN_CALLBACKS) -static void *tag; -void *(*callback_register_tag)(const char *object_type); -void *(*callback_assign_tag)(void *addr, void *tag); -void (*callback_read)(void *addr, void *caller_pc, void *tag); -void (*callback_write)(void *addr, void *caller_pc, void *tag); -#endif - -void InitializeLibrary() { -#if defined(USE_TSAN_CALLBACKS) - callback_register_tag = (decltype(callback_register_tag))dlsym(RTLD_DEFAULT, "__tsan_external_register_tag"); - callback_assign_tag = (decltype(callback_assign_tag))dlsym(RTLD_DEFAULT, "__tsan_external_assign_tag"); - callback_read = (decltype(callback_read))dlsym(RTLD_DEFAULT, "__tsan_external_read"); - callback_write = (decltype(callback_write))dlsym(RTLD_DEFAULT, "__tsan_external_write"); - tag = callback_register_tag("MyLibrary::MyObject"); -#endif -} - -MyObject *ObjectCreate() { - MyObject *ref = (MyObject *)malloc(sizeof(MyObject)); -#if defined(USE_TSAN_CALLBACKS) - callback_assign_tag(ref, tag); -#endif - return ref; -} - -long ObjectRead(MyObject *ref) { -#if defined(USE_TSAN_CALLBACKS) - callback_read(ref, __builtin_return_address(0), tag); -#endif - return ref->_val; -} - -void ObjectWrite(MyObject *ref, long val) { -#if defined(USE_TSAN_CALLBACKS) - callback_write(ref, __builtin_return_address(0), tag); -#endif - ref->_val = val; -} - -void ObjectWriteAnother(MyObject *ref, long val) { -#if defined(USE_TSAN_CALLBACKS) - callback_write(ref, __builtin_return_address(0), tag); -#endif - ref->_another = val; -} - -#else // defined(SHARED_LIB) - int main(int argc, char *argv[]) { InitializeLibrary(); @@ -126,11 +68,11 @@ int main(int argc, char *argv[]) { // TEST2-NOT: WARNING: ThreadSanitizer // TEST3: WARNING: ThreadSanitizer: race on a library object - // TEST3: {{Mutating|read-only}} access of object MyLibrary::MyObject at + // TEST3: {{Mutating|read-only}} access of MyLibrary::MyObject at // TEST3: {{ObjectWrite|ObjectRead}} - // TEST3: Previous {{mutating|read-only}} access of object MyLibrary::MyObject at + // TEST3: Previous {{mutating|read-only}} access of MyLibrary::MyObject at // TEST3: {{ObjectWrite|ObjectRead}} - // TEST3: Location is MyLibrary::MyObject object of size 16 at + // TEST3: Location is MyLibrary::MyObject of size 16 at // TEST3: {{ObjectCreate}} fprintf(stderr, "RW test done\n"); @@ -149,15 +91,13 @@ int main(int argc, char *argv[]) { // TEST2-NOT: WARNING: ThreadSanitizer // TEST3: WARNING: ThreadSanitizer: race on a library object - // TEST3: Mutating access of object MyLibrary::MyObject at + // TEST3: Mutating access of MyLibrary::MyObject at // TEST3: {{ObjectWrite|ObjectWriteAnother}} - // TEST3: Previous mutating access of object MyLibrary::MyObject at + // TEST3: Previous mutating access of MyLibrary::MyObject at // TEST3: {{ObjectWrite|ObjectWriteAnother}} - // TEST3: Location is MyLibrary::MyObject object of size 16 at + // TEST3: Location is MyLibrary::MyObject of size 16 at // TEST3: {{ObjectCreate}} fprintf(stderr, "WW test done\n"); // CHECK: WW test done } - -#endif // defined(SHARED_LIB) diff --git a/test/tsan/test.h b/test/tsan/test.h index 6b981c09f53df..bc4f7aad55fea 100644 --- a/test/tsan/test.h +++ b/test/tsan/test.h @@ -8,6 +8,8 @@ #include <stdarg.h> #include "sanitizer_common/print_address.h" +#include <sanitizer/tsan_interface.h> + #ifdef __APPLE__ #include <mach/mach_time.h> #endif diff --git a/test/tsan/unaligned_race.cc b/test/tsan/unaligned_race.cc index 030642a4ddfb0..5850b21542d42 100644 --- a/test/tsan/unaligned_race.cc +++ b/test/tsan/unaligned_race.cc @@ -6,31 +6,22 @@ volatile uint64_t objs[8*2*(2 + 4 + 8)][2]; -extern "C" { -uint16_t __sanitizer_unaligned_load16(volatile void *addr); -uint32_t __sanitizer_unaligned_load32(volatile void *addr); -uint64_t __sanitizer_unaligned_load64(volatile void *addr); -void __sanitizer_unaligned_store16(volatile void *addr, uint16_t v); -void __sanitizer_unaligned_store32(volatile void *addr, uint32_t v); -void __sanitizer_unaligned_store64(volatile void *addr, uint64_t v); -} - // All this mess is to generate unique stack for each race, // otherwise tsan will suppress similar stacks. -static NOINLINE void access(volatile char *p, int sz, int rw) { +static NOINLINE void access(volatile void *p, int sz, int rw) { if (rw) { switch (sz) { - case 0: __sanitizer_unaligned_store16(p, 0); break; - case 1: __sanitizer_unaligned_store32(p, 0); break; - case 2: __sanitizer_unaligned_store64(p, 0); break; + case 0: __sanitizer_unaligned_store16((void *)p, 0); break; + case 1: __sanitizer_unaligned_store32((void *)p, 0); break; + case 2: __sanitizer_unaligned_store64((void *)p, 0); break; default: exit(1); } } else { switch (sz) { - case 0: __sanitizer_unaligned_load16(p); break; - case 1: __sanitizer_unaligned_load32(p); break; - case 2: __sanitizer_unaligned_load64(p); break; + case 0: __sanitizer_unaligned_load16((void *)p); break; + case 1: __sanitizer_unaligned_load32((void *)p); break; + case 2: __sanitizer_unaligned_load64((void *)p); break; default: exit(1); } } |