aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-02-10 07:45:43 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-02-10 07:45:43 +0000
commit476c4db3dc56bee43df384704c75ccc71cfa7a1d (patch)
tree5d0dcec3cc12fc53532fc84029892b98711a2596 /test
parentca9211ecdede9bdedb812b2243a4abdb8dacd1b9 (diff)
downloadsrc-476c4db3dc56bee43df384704c75ccc71cfa7a1d.tar.gz
src-476c4db3dc56bee43df384704c75ccc71cfa7a1d.zip
Import compiler-rt trunk r228651.vendor/compiler-rt/compiler-rt-r228651
Notes
Notes: svn path=/vendor/compiler-rt/dist/; revision=278497 svn path=/vendor/compiler-rt/compiler-rt-r228651/; revision=278498; tag=vendor/compiler-rt/compiler-rt-r228651
Diffstat (limited to 'test')
-rw-r--r--test/asan/CMakeLists.txt188
-rw-r--r--test/asan/TestCases/Android/coverage-android.cc94
-rw-r--r--test/asan/TestCases/Android/lit.local.cfg2
-rw-r--r--test/asan/TestCases/Darwin/address-range-limit.mm38
-rw-r--r--test/asan/TestCases/Darwin/crashlog-stacktraces.c43
-rw-r--r--test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc2
-rw-r--r--test/asan/TestCases/Darwin/dyld_insert_libraries_remove.cc39
-rw-r--r--test/asan/TestCases/Darwin/interception-in-shared-lib-test.cc6
-rw-r--r--test/asan/TestCases/Darwin/interface_symbols_darwin.c9
-rw-r--r--test/asan/TestCases/Darwin/linked-only.cc33
-rw-r--r--test/asan/TestCases/Darwin/mixing-global-constructors.cc42
-rw-r--r--test/asan/TestCases/Darwin/suppressions-darwin.cc8
-rw-r--r--test/asan/TestCases/Linux/asan_preload_test-2.cc4
-rw-r--r--test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc2
-rw-r--r--test/asan/TestCases/Linux/coverage-direct-activation.cc59
-rw-r--r--test/asan/TestCases/Linux/coverage-direct-large.cc24
-rw-r--r--test/asan/TestCases/Linux/coverage-direct.cc45
-rw-r--r--test/asan/TestCases/Linux/coverage-disabled.cc2
-rw-r--r--test/asan/TestCases/Linux/coverage-levels.cc15
-rw-r--r--test/asan/TestCases/Linux/coverage-maybe-open-file.cc2
-rw-r--r--test/asan/TestCases/Linux/coverage-module-unloaded.cc2
-rw-r--r--test/asan/TestCases/Linux/coverage-reset.cc52
-rw-r--r--test/asan/TestCases/Linux/coverage-sandboxing.cc2
-rw-r--r--test/asan/TestCases/Linux/coverage-tracing.cc48
-rw-r--r--test/asan/TestCases/Linux/coverage.cc2
-rw-r--r--test/asan/TestCases/Linux/malloc-in-qsort.cc7
-rw-r--r--test/asan/TestCases/Linux/nohugepage_test.cc91
-rw-r--r--test/asan/TestCases/Linux/overflow-in-qsort.cc4
-rw-r--r--test/asan/TestCases/Linux/quarantine_size_mb.cc24
-rw-r--r--test/asan/TestCases/Linux/sized_delete_test.cc2
-rw-r--r--test/asan/TestCases/Linux/stack-overflow-sigbus.cc64
-rw-r--r--test/asan/TestCases/Linux/stack-trace-dlclose.cc2
-rw-r--r--test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc2
-rw-r--r--test/asan/TestCases/Posix/init-order-dlopen.cc4
-rw-r--r--test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc2
-rw-r--r--test/asan/TestCases/Posix/shared-lib-test.cc8
-rw-r--r--test/asan/TestCases/Posix/start-deactivated.cc36
-rw-r--r--test/asan/TestCases/Posix/tsd_dtor_leak.cc14
-rw-r--r--test/asan/TestCases/Windows/iostream_sbo.cc18
-rw-r--r--test/asan/TestCases/Windows/shadow_mapping_failure.cc18
-rw-r--r--test/asan/TestCases/Windows/thread_suspended.cc27
-rw-r--r--test/asan/TestCases/allocator_returns_null.cc12
-rw-r--r--test/asan/TestCases/asan_options-help.cc9
-rw-r--r--test/asan/TestCases/deep_call_stack.cc3
-rw-r--r--test/asan/TestCases/default_options.cc4
-rw-r--r--test/asan/TestCases/dlclose-test.cc8
-rw-r--r--test/asan/TestCases/interception_failure_test.cc1
-rw-r--r--test/asan/TestCases/log-path_test.cc4
-rw-r--r--test/asan/TestCases/stack-overflow.cc2
-rw-r--r--test/asan/TestCases/suppressions-function.cc4
-rw-r--r--test/asan/TestCases/suppressions-interceptor.cc2
-rw-r--r--test/asan/TestCases/suppressions-library.cc8
-rw-r--r--test/asan/TestCases/zero_page_pc.cc8
-rw-r--r--test/asan/Unit/lit.site.cfg.in10
-rwxr-xr-xtest/asan/android_commands/android_run.py2
-rw-r--r--test/asan/lit.cfg16
-rw-r--r--test/builtins/Unit/clear_cache_test.c19
-rw-r--r--test/builtins/Unit/enable_execute_stack_test.c20
-rw-r--r--test/lit.common.configured.in2
-rw-r--r--test/lsan/TestCases/ignore_object.cc3
-rw-r--r--test/lsan/TestCases/ignore_object_errors.cc4
-rw-r--r--test/lsan/TestCases/leak_check_at_exit.cc2
-rw-r--r--test/lsan/TestCases/leak_check_before_thread_started.cc3
-rw-r--r--test/lsan/TestCases/suppressions_file.cc8
-rw-r--r--test/msan/msan_print_shadow.cc6
-rw-r--r--test/msan/origin-store-long.cc21
-rw-r--r--test/msan/realloc-large-origin.cc30
-rw-r--r--test/msan/realloc-origin.cc21
-rw-r--r--test/msan/select_float_origin.cc2
-rw-r--r--test/msan/use-after-free.cc2
-rw-r--r--test/profile/instrprof-basic.c4
-rw-r--r--test/profile/instrprof-reset-counters.c2
-rw-r--r--test/profile/instrprof-set-filename.c2
-rw-r--r--test/profile/instrprof-without-libc.c2
-rw-r--r--test/profile/instrprof-write-file-atexit-explicitly.c2
-rw-r--r--test/profile/instrprof-write-file-only.c2
-rw-r--r--test/profile/instrprof-write-file.c4
-rw-r--r--test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc37
-rw-r--r--test/sanitizer_common/TestCases/Linux/sanitizer_set_death_callback_test.cc49
-rw-r--r--test/sanitizer_common/TestCases/Linux/sched_getparam.cc13
-rw-r--r--test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc66
-rw-r--r--test/sanitizer_common/TestCases/options-help.cc8
-rw-r--r--test/sanitizer_common/TestCases/options-include.cc21
-rw-r--r--test/sanitizer_common/TestCases/options-invalid.cc15
-rw-r--r--test/tsan/CMakeLists.txt1
-rw-r--r--test/tsan/aligned_vs_unaligned_race.cc17
-rw-r--r--test/tsan/annotate_happens_before.cc57
-rw-r--r--test/tsan/atomic_free.cc7
-rw-r--r--test/tsan/atomic_free2.cc7
-rw-r--r--test/tsan/atomic_norace.cc11
-rw-r--r--test/tsan/atomic_race.cc11
-rw-r--r--test/tsan/atomic_stack.cc7
-rw-r--r--test/tsan/benign_race.cc8
-rw-r--r--test/tsan/blacklist2.cc8
-rw-r--r--test/tsan/cond_cancel.c9
-rw-r--r--test/tsan/cond_race.cc11
-rw-r--r--test/tsan/deadlock_detector_stress_test.cc25
-rw-r--r--test/tsan/deep_stack1.cc16
-rw-r--r--test/tsan/fd_close_norace.cc8
-rw-r--r--test/tsan/fd_location.cc8
-rw-r--r--test/tsan/fd_pipe_race.cc8
-rw-r--r--test/tsan/fd_stdout_race.cc8
-rw-r--r--test/tsan/fork_deadlock.cc8
-rw-r--r--test/tsan/fork_multithreaded.cc14
-rw-r--r--test/tsan/free_race.c12
-rw-r--r--test/tsan/global_race.cc9
-rw-r--r--test/tsan/global_race2.cc9
-rw-r--r--test/tsan/global_race3.cc9
-rw-r--r--test/tsan/halt_on_error.cc8
-rw-r--r--test/tsan/ignore_free.cc9
-rw-r--r--test/tsan/ignore_lib0.cc2
-rw-r--r--test/tsan/ignore_lib1.cc2
-rw-r--r--test/tsan/ignore_lib2.cc2
-rw-r--r--test/tsan/ignore_lib3.cc2
-rw-r--r--test/tsan/ignore_malloc.cc7
-rw-r--r--test/tsan/ignore_race.cc8
-rw-r--r--test/tsan/inlined_memcpy_race.cc9
-rw-r--r--test/tsan/inlined_memcpy_race2.cc9
-rw-r--r--test/tsan/java.h8
-rw-r--r--test/tsan/java_finalizer.cc4
-rw-r--r--test/tsan/java_lock.cc5
-rw-r--r--test/tsan/java_lock_move.cc4
-rw-r--r--test/tsan/java_lock_rec.cc8
-rw-r--r--test/tsan/java_lock_rec_race.cc8
-rw-r--r--test/tsan/java_move_overlap.cc4
-rw-r--r--test/tsan/java_move_overlap_race.cc4
-rw-r--r--test/tsan/java_race_move.cc4
-rw-r--r--test/tsan/java_rwlock.cc5
-rw-r--r--test/tsan/java_volatile.cc42
-rw-r--r--test/tsan/load_shared_lib.cc30
-rw-r--r--test/tsan/malloc_stack.cc7
-rw-r--r--test/tsan/map32bit.cc9
-rw-r--r--test/tsan/memcpy_race.cc9
-rw-r--r--test/tsan/mop_with_offset.cc9
-rw-r--r--test/tsan/mop_with_offset2.cc9
-rw-r--r--test/tsan/mutex_cycle2.c8
-rw-r--r--test/tsan/mutexset1.cc8
-rw-r--r--test/tsan/mutexset2.cc8
-rw-r--r--test/tsan/mutexset3.cc8
-rw-r--r--test/tsan/mutexset4.cc8
-rw-r--r--test/tsan/mutexset5.cc8
-rw-r--r--test/tsan/mutexset6.cc8
-rw-r--r--test/tsan/mutexset7.cc8
-rw-r--r--test/tsan/mutexset8.cc8
-rw-r--r--test/tsan/process_sleep.h7
-rw-r--r--test/tsan/pthread_atfork_deadlock.c8
-rw-r--r--test/tsan/race_on_barrier.c9
-rw-r--r--test/tsan/race_on_mutex.c13
-rw-r--r--test/tsan/race_on_mutex2.c9
-rw-r--r--test/tsan/race_on_puts.cc7
-rw-r--r--test/tsan/race_on_read.cc20
-rw-r--r--test/tsan/race_on_speculative_load.cc11
-rw-r--r--test/tsan/race_on_write.cc9
-rw-r--r--test/tsan/race_with_finished_thread.cc11
-rw-r--r--test/tsan/real_deadlock_detector_stress_test.cc186
-rw-r--r--test/tsan/restore_stack.cc50
-rw-r--r--test/tsan/signal_errno.cc9
-rw-r--r--test/tsan/signal_malloc.cc6
-rw-r--r--test/tsan/signal_recursive.cc30
-rw-r--r--test/tsan/signal_reset.cc74
-rw-r--r--test/tsan/signal_sync.cc7
-rw-r--r--test/tsan/signal_thread.cc52
-rw-r--r--test/tsan/signal_write.cc2
-rw-r--r--test/tsan/simple_race.c8
-rw-r--r--test/tsan/simple_race.cc8
-rw-r--r--test/tsan/simple_stack.c24
-rw-r--r--test/tsan/simple_stack2.cc20
-rw-r--r--test/tsan/sleep_sync.cc8
-rw-r--r--test/tsan/sleep_sync2.cc8
-rw-r--r--test/tsan/stack_race.cc8
-rw-r--r--test/tsan/stack_race2.cc8
-rw-r--r--test/tsan/stack_sync_reuse.cc65
-rw-r--r--test/tsan/suppress_same_address.cc7
-rw-r--r--test/tsan/suppressions_global.cc2
-rw-r--r--test/tsan/suppressions_race.cc10
-rw-r--r--test/tsan/suppressions_race2.cc10
-rw-r--r--test/tsan/test.h31
-rw-r--r--test/tsan/thread_detach.c8
-rw-r--r--test/tsan/thread_leak3.c8
-rw-r--r--test/tsan/thread_leak4.c10
-rw-r--r--test/tsan/thread_leak5.c8
-rw-r--r--test/tsan/thread_name.cc8
-rw-r--r--test/tsan/thread_name2.cc9
-rw-r--r--test/tsan/tiny_race.c7
-rw-r--r--test/tsan/tls_race.cc8
-rw-r--r--test/tsan/tls_race2.cc8
-rw-r--r--test/tsan/unaligned_norace.cc18
-rw-r--r--test/tsan/unaligned_race.cc9
-rw-r--r--test/tsan/vptr_harmful_race.cc8
-rw-r--r--test/tsan/vptr_harmful_race2.cc8
-rw-r--r--test/tsan/vptr_harmful_race3.cc8
-rw-r--r--test/tsan/vptr_harmful_race4.cc8
-rw-r--r--test/tsan/write_in_reader_lock.cc9
-rw-r--r--test/ubsan/TestCases/Float/cast-overflow.cpp1
-rw-r--r--test/ubsan/TestCases/Integer/no-recover.cpp4
-rw-r--r--test/ubsan/TestCases/Misc/coverage-levels.cc38
-rw-r--r--test/ubsan/TestCases/Misc/nonnull-arg.cpp2
-rw-r--r--test/ubsan/TestCases/TypeCheck/misaligned.cpp9
-rw-r--r--test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp2
-rw-r--r--test/ubsan/TestCases/TypeCheck/vptr.cpp19
200 files changed, 2371 insertions, 719 deletions
diff --git a/test/asan/CMakeLists.txt b/test/asan/CMakeLists.txt
index 14f7f506da51..0c46ef7e6e31 100644
--- a/test/asan/CMakeLists.txt
+++ b/test/asan/CMakeLists.txt
@@ -1,140 +1,58 @@
set(ASAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(ASAN_TESTSUITES)
+set(ASAN_DYNAMIC_TESTSUITES)
macro(get_bits_for_arch arch bits)
- if (${arch} STREQUAL "arm" OR
- ${arch} STREQUAL "i386" OR
- ${arch} STREQUAL "i686" OR
- ${arch} STREQUAL "mips")
+ if (${arch} MATCHES "i386|i686|arm|mips|mipsel")
set(bits 32)
- elseif (${arch} STREQUAL "aarch64" OR
- ${arch} STREQUAL "x86_64" OR
- ${arch} STREQUAL "mips64")
+ elseif (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|mips64|mips64el")
set(bits 64)
else()
message(FATAL_ERROR "Unknown target architecture: ${arch}")
endif()
endmacro()
-# TODO: merge with non-ANDROID case
-if(ANDROID)
- foreach(arch ${ASAN_SUPPORTED_ARCH})
- set(ASAN_TEST_TARGET_CC ${CMAKE_CXX_COMPILER})
- set(ASAN_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS})
- set(ASAN_TEST_CONFIG_SUFFIX "-${arch}-android")
- get_bits_for_arch(${arch} ASAN_TEST_BITS)
- set(ASAN_TEST_DYNAMIC True)
- set(ASAN_TEST_TARGET_ARCH "${arch}-android")
- string(TOUPPER ${arch} ARCH_UPPER_CASE)
- set(CONFIG ${ARCH_UPPER_CASE}AndroidConfig)
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG}/lit.site.cfg
- )
- list(APPEND ASAN_TESTSUITES
- ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG})
- endforeach()
-
-else() # Not Android
-
- if(CAN_TARGET_arm)
- # This is only true if we are cross-compiling.
- # Build all tests with host compiler and use host tools.
- set(ASAN_TEST_TARGET_CC ${COMPILER_RT_TEST_COMPILER})
- set(ASAN_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS})
- set(ASAN_TEST_CONFIG_SUFFIX "-arm-linux")
- set(ASAN_TEST_BITS "32")
- set(ASAN_TEST_DYNAMIC False)
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/ARMLinuxConfig/lit.site.cfg
- )
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/ARMLinuxConfig)
+foreach(arch ${ASAN_SUPPORTED_ARCH})
+ if(ANDROID)
+ set(ASAN_TEST_TARGET_ARCH ${arch}-android)
+ else()
+ set(ASAN_TEST_TARGET_ARCH ${arch})
endif()
-
- if(CAN_TARGET_aarch64)
+ string(TOLOWER "-${arch}-${OS_NAME}" ASAN_TEST_CONFIG_SUFFIX)
+ get_bits_for_arch(${arch} ASAN_TEST_BITS)
+ if(ANDROID OR ${arch} MATCHES "arm|aarch64")
# This is only true if we are cross-compiling.
# Build all tests with host compiler and use host tools.
set(ASAN_TEST_TARGET_CC ${COMPILER_RT_TEST_COMPILER})
set(ASAN_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS})
- set(ASAN_TEST_CONFIG_SUFFIX "-aarch64-linux")
- set(ASAN_TEST_BITS "64")
- set(ASAN_TEST_DYNAMIC False)
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/AArch64LinuxConfig/lit.site.cfg
- )
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/AArch64LinuxConfig)
+ else()
+ get_target_flags_for_arch(${arch} ASAN_TEST_TARGET_CFLAGS)
endif()
-
- if(CAN_TARGET_x86_64 OR CAN_TARGET_powerpc64 OR CAN_TARGET_mips64 OR CAN_TARGET_mips64el)
- set(ASAN_TEST_CONFIG_SUFFIX "64")
- set(ASAN_TEST_BITS "64")
- set(ASAN_TEST_TARGET_CFLAGS ${TARGET_64_BIT_CFLAGS})
+ if(ANDROID)
+ set(ASAN_TEST_DYNAMIC True)
+ else()
set(ASAN_TEST_DYNAMIC False)
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig/lit.site.cfg
- )
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig)
- if(COMPILER_RT_BUILD_SHARED_ASAN)
- set(ASAN_TEST_CONFIG_SUFFIX "64-Dynamic")
- set(ASAN_TEST_DYNAMIC True)
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig-dynamic/lit.site.cfg)
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig-dynamic)
- endif()
- endif()
-
- if(CAN_TARGET_i386)
- set(ASAN_TEST_CONFIG_SUFFIX "32")
- set(ASAN_TEST_BITS "32")
- set(ASAN_TEST_TARGET_CFLAGS ${TARGET_32_BIT_CFLAGS})
- set(ASAN_TEST_DYNAMIC False)
- set(ASAN_TEST_TARGET_ARCH "i386")
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig/lit.site.cfg
- )
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig)
- if(COMPILER_RT_BUILD_SHARED_ASAN)
- set(ASAN_TEST_CONFIG_SUFFIX "32-Dynamic")
- set(ASAN_TEST_DYNAMIC True)
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig-dynamic/lit.site.cfg)
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig-dynamic)
- endif()
endif()
+ string(TOUPPER ${arch} ARCH_UPPER_CASE)
+ set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg
+ )
+ list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
- if(CAN_TARGET_mips OR CAN_TARGET_mipsel)
- set(ASAN_TEST_CONFIG_SUFFIX "32")
- set(ASAN_TEST_BITS "32")
- set(ASAN_TEST_TARGET_CFLAGS ${TARGET_32_BIT_CFLAGS})
- set(ASAN_TEST_DYNAMIC False)
+ if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
+ string(TOLOWER "-${arch}-${OS_NAME}-dynamic" ASAN_TEST_CONFIG_SUFFIX)
+ set(ASAN_TEST_DYNAMIC True)
+ set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}DynamicConfig)
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig/lit.site.cfg
- )
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig)
- if(COMPILER_RT_BUILD_SHARED_ASAN)
- set(ASAN_TEST_CONFIG_SUFFIX "32-Dynamic")
- set(ASAN_TEST_DYNAMIC True)
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig-dynamic/lit.site.cfg)
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig-dynamic)
- endif()
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
+ list(APPEND ASAN_DYNAMIC_TESTSUITES
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
endif()
-endif() # Not Android
-
-if(COMPILER_RT_INCLUDE_TESTS)
- configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg)
-endif()
+endforeach()
set(ASAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
if(COMPILER_RT_STANDALONE_BUILD)
@@ -144,13 +62,49 @@ if(COMPILER_RT_STANDALONE_BUILD)
else()
list(APPEND ASAN_TEST_DEPS asan)
endif()
+set(ASAN_DYNAMIC_TEST_DEPS ${ASAN_TEST_DEPS})
-# FIXME: support unit test in the android test runner
-if(COMPILER_RT_INCLUDE_TESTS AND NOT ANDROID)
- list(APPEND ASAN_TEST_DEPS AsanUnitTests)
- list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit)
+# Add unit tests.
+if(COMPILER_RT_INCLUDE_TESTS)
+ set(ASAN_TEST_DYNAMIC False)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg)
+ if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
+ set(ASAN_TEST_DYNAMIC True)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic/lit.site.cfg)
+ endif()
+ # FIXME: support unit test in the android test runner
+ if (NOT ANDROID)
+ list(APPEND ASAN_TEST_DEPS AsanUnitTests)
+ list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit)
+ if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
+ list(APPEND ASAN_DYNAMIC_TEST_DEPS AsanDynamicUnitTests)
+ list(APPEND ASAN_DYNAMIC_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic)
+ endif()
+ endif()
endif()
+
add_lit_testsuite(check-asan "Running the AddressSanitizer tests"
${ASAN_TESTSUITES}
DEPENDS ${ASAN_TEST_DEPS})
set_target_properties(check-asan PROPERTIES FOLDER "ASan tests")
+
+if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
+ # Add check-dynamic-asan target. It is a part of check-all only on Windows,
+ # where we want to always test both dynamic and static runtime.
+ if(NOT OS_NAME MATCHES "Windows")
+ set(EXCLUDE_FROM_ALL TRUE)
+ endif()
+ add_lit_testsuite(check-asan-dynamic
+ "Running the AddressSanitizer tests with dynamic runtime"
+ ${ASAN_DYNAMIC_TESTSUITES}
+ DEPENDS ${ASAN_DYNAMIC_TEST_DEPS})
+ set_target_properties(check-asan-dynamic
+ PROPERTIES FOLDER "ASan dynamic tests")
+ if(NOT OS_NAME MATCHES "Windows")
+ set(EXCLUDE_FROM_ALL FALSE)
+ endif()
+endif()
diff --git a/test/asan/TestCases/Android/coverage-android.cc b/test/asan/TestCases/Android/coverage-android.cc
index 071a2e3e1faa..e243059fbbec 100644
--- a/test/asan/TestCases/Android/coverage-android.cc
+++ b/test/asan/TestCases/Android/coverage-android.cc
@@ -1,8 +1,8 @@
// Test for direct coverage writing with dlopen.
-// Test normal exit.
-// RUN: %clangxx_asan -mllvm -asan-coverage=1 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
-// RUN: %clangxx_asan -mllvm -asan-coverage=1 -DSO_DIR=\"%device\" %s -o %t
+// Test normal exit, coverage level 1.
+// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%device\" %s -o %t
// RUN: adb shell rm -rf %device/coverage-android
// RUN: rm -rf %T/coverage-android
@@ -14,12 +14,12 @@
// RUN: ls; pwd
// RUN: cd %T/coverage-android/direct
// RUN: %sancov rawunpack *.sancov.raw
-// RUN: %sancov print *.sancov |& FileCheck %s
+// RUN: %sancov print *.sancov |& FileCheck --check-prefix=CHECK1 %s
-// Test sudden death.
-// RUN: %clangxx_asan -mllvm -asan-coverage=1 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
-// RUN: %clangxx_asan -mllvm -asan-coverage=1 -DSO_DIR=\"%device\" %s -o %t
+// Test sudden death, coverage level 1.
+// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%device\" %s -o %t
// RUN: adb shell rm -rf %device/coverage-android-kill
// RUN: rm -rf %T/coverage-android-kill
@@ -31,7 +31,75 @@
// RUN: ls; pwd
// RUN: cd %T/coverage-android-kill/direct
// RUN: %sancov rawunpack *.sancov.raw
-// RUN: %sancov print *.sancov |& FileCheck %s
+// RUN: %sancov print *.sancov |& FileCheck --check-prefix=CHECK1 %s
+
+
+// Test normal exit, coverage level 2.
+// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=2 -DSO_DIR=\"%device\" %s -o %t
+
+// RUN: adb shell rm -rf %device/coverage-android
+// RUN: rm -rf %T/coverage-android
+
+// RUN: adb shell mkdir -p %device/coverage-android/direct
+// RUN: mkdir -p %T/coverage-android/direct
+// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t
+// RUN: adb pull %device/coverage-android/direct %T/coverage-android/direct
+// RUN: ls; pwd
+// RUN: cd %T/coverage-android/direct
+// RUN: %sancov rawunpack *.sancov.raw
+// RUN: %sancov print *.sancov |& FileCheck --check-prefix=CHECK2 %s
+
+
+// Test sudden death, coverage level 2.
+// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=2 -DSO_DIR=\"%device\" %s -o %t
+
+// RUN: adb shell rm -rf %device/coverage-android-kill
+// RUN: rm -rf %T/coverage-android-kill
+
+// RUN: adb shell mkdir -p %device/coverage-android-kill/direct
+// RUN: mkdir -p %T/coverage-android-kill/direct
+// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t
+// RUN: adb pull %device/coverage-android-kill/direct %T/coverage-android-kill/direct
+// RUN: ls; pwd
+// RUN: cd %T/coverage-android-kill/direct
+// RUN: %sancov rawunpack *.sancov.raw
+// RUN: %sancov print *.sancov |& FileCheck --check-prefix=CHECK2 %s
+
+
+// Test normal exit, coverage level 3.
+// RUN: %clangxx_asan -fsanitize-coverage=3 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=3 -DSO_DIR=\"%device\" %s -o %t
+
+// RUN: adb shell rm -rf %device/coverage-android
+// RUN: rm -rf %T/coverage-android
+
+// RUN: adb shell mkdir -p %device/coverage-android/direct
+// RUN: mkdir -p %T/coverage-android/direct
+// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t
+// RUN: adb pull %device/coverage-android/direct %T/coverage-android/direct
+// RUN: ls; pwd
+// RUN: cd %T/coverage-android/direct
+// RUN: %sancov rawunpack *.sancov.raw
+// RUN: %sancov print *.sancov |& FileCheck --check-prefix=CHECK3 %s
+
+
+// Test sudden death, coverage level 3.
+// RUN: %clangxx_asan -fsanitize-coverage=3 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=3 -DSO_DIR=\"%device\" %s -o %t
+
+// RUN: adb shell rm -rf %device/coverage-android-kill
+// RUN: rm -rf %T/coverage-android-kill
+
+// RUN: adb shell mkdir -p %device/coverage-android-kill/direct
+// RUN: mkdir -p %T/coverage-android-kill/direct
+// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t
+// RUN: adb pull %device/coverage-android-kill/direct %T/coverage-android-kill/direct
+// RUN: ls; pwd
+// RUN: cd %T/coverage-android-kill/direct
+// RUN: %sancov rawunpack *.sancov.raw
+// RUN: %sancov print *.sancov |& FileCheck --check-prefix=CHECK3 %s
#include <assert.h>
#include <dlfcn.h>
@@ -51,11 +119,17 @@ void bar() {
}
#else
+volatile int sink;
+
int main(int argc, char **argv) {
fprintf(stderr, "PID: %d\n", getpid());
void *handle1 =
dlopen(SO_DIR "/libcoverage_android_test_1.so", RTLD_LAZY);
assert(handle1);
+
+ if (argc == 0)
+ sink = 0;
+
void (*bar1)() = (void (*)())dlsym(handle1, "bar");
assert(bar1);
bar1();
@@ -64,4 +138,6 @@ int main(int argc, char **argv) {
}
#endif
-// CHECK: 2 PCs total
+// CHECK1: 2 PCs total
+// CHECK2: 7 PCs total
+// CHECK3: 8 PCs total
diff --git a/test/asan/TestCases/Android/lit.local.cfg b/test/asan/TestCases/Android/lit.local.cfg
index 42513dd3aa61..63a6e52826a3 100644
--- a/test/asan/TestCases/Android/lit.local.cfg
+++ b/test/asan/TestCases/Android/lit.local.cfg
@@ -5,7 +5,7 @@ def getRoot(config):
root = getRoot(config)
-if root.android != "TRUE":
+if root.android != "1":
config.unsupported = True
config.substitutions.append( ("%device", "/data/local/tmp/Output") )
diff --git a/test/asan/TestCases/Darwin/address-range-limit.mm b/test/asan/TestCases/Darwin/address-range-limit.mm
new file mode 100644
index 000000000000..a6906766d7ee
--- /dev/null
+++ b/test/asan/TestCases/Darwin/address-range-limit.mm
@@ -0,0 +1,38 @@
+// Regression test for https://code.google.com/p/address-sanitizer/issues/detail?id=368.
+
+// RUN: %clang_asan %s -Wno-deprecated-declarations -flat_namespace -bundle -undefined suppress -o %t.bundle
+// RUN: %clang_asan %s -Wno-deprecated-declarations -o %t -framework Foundation && not %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+#import <mach-o/dyld.h>
+
+#include <string>
+
+int main(int argc, char *argv[]) {
+ for (int i = 0; i < 10; i++) {
+ NSObjectFileImage im;
+
+ std::string path = std::string(argv[0]) + ".bundle";
+ NSObjectFileImageReturnCode rc =
+ NSCreateObjectFileImageFromFile(path.c_str(), &im);
+ if (rc != NSObjectFileImageSuccess) {
+ fprintf(stderr, "Could not load bundle.\n");
+ exit(-1);
+ }
+
+ NSModule handle = NSLinkModule(im, "a.bundle", 0);
+ if (handle == 0) {
+ fprintf(stderr, "Could not load bundle.\n");
+ exit(-1);
+ }
+ printf("h: %p\n", handle);
+ }
+
+ char *ptr = (char *)malloc(10);
+ ptr[10] = 'x'; // BOOM
+}
+
+// CHECK: AddressSanitizer: heap-buffer-overflow
+// CHECK: WRITE of size 1
+// CHECK: {{#0 .* in main}}
+// CHECK: is located 0 bytes to the right of 10-byte region
diff --git a/test/asan/TestCases/Darwin/crashlog-stacktraces.c b/test/asan/TestCases/Darwin/crashlog-stacktraces.c
new file mode 100644
index 000000000000..e9af5396e1c3
--- /dev/null
+++ b/test/asan/TestCases/Darwin/crashlog-stacktraces.c
@@ -0,0 +1,43 @@
+// RUN: %clang_asan -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+
+#include <execinfo.h>
+#include <sanitizer/common_interface_defs.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void death_function() {
+ fprintf(stderr, "DEATH CALLBACK\n");
+
+ void* callstack[128];
+ int i, frames = backtrace(callstack, 128);
+ char** strs = backtrace_symbols(callstack, frames);
+ for (i = 0; i < frames; ++i) {
+ fprintf(stderr, "%s\n", strs[i]);
+ }
+ free(strs);
+
+ fprintf(stderr, "END OF BACKTRACE\n");
+}
+
+int fault_function() {
+ char *x = (char*)malloc(10 * sizeof(char));
+ free(x);
+ return x[5]; // BOOM
+}
+
+int main() {
+ __sanitizer_set_death_callback(death_function);
+ fault_function();
+ return 0;
+}
+
+// CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+// CHECK: {{READ of size 1 at 0x.* thread T0}}
+// CHECK: {{ #0 0x.* in fault_function}}
+
+// CHECK: DEATH CALLBACK
+// CHECK: death_function
+// CHECK: fault_function
+// CHECK: main
+// CHECK: END OF BACKTRACE
diff --git a/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc b/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
index b1bb4567f900..0bd4170a353c 100644
--- a/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
+++ b/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
@@ -20,13 +20,11 @@ int main() {
return 0;
}
-// CHECK-NOINSERT: Parsed ASAN_OPTIONS: verbosity=1
// CHECK-NOINSERT: exec()-ing the program with
// CHECK-NOINSERT: DYLD_INSERT_LIBRARIES
// CHECK-NOINSERT: to enable ASan wrappers.
// CHECK-NOINSERT: Passed
-// CHECK: Parsed ASAN_OPTIONS: verbosity=1
// CHECK-NOT: exec()-ing the program with
// CHECK-NOT: DYLD_INSERT_LIBRARIES
// CHECK-NOT: to enable ASan wrappers.
diff --git a/test/asan/TestCases/Darwin/dyld_insert_libraries_remove.cc b/test/asan/TestCases/Darwin/dyld_insert_libraries_remove.cc
new file mode 100644
index 000000000000..a3af8c156ef2
--- /dev/null
+++ b/test/asan/TestCases/Darwin/dyld_insert_libraries_remove.cc
@@ -0,0 +1,39 @@
+// Check that when launching with DYLD_INSERT_LIBRARIES, we properly remove
+// the ASan dylib from the environment variable (both when using an absolute
+// or relative path) and also that the other dylibs are left untouched.
+
+// RUN: mkdir -p %T/dyld_insert_libraries_remove
+// RUN: cp `%clang_asan %s -fsanitize=address -### 2>&1 \
+// RUN: | grep "libclang_rt.asan_osx_dynamic.dylib" \
+// RUN: | sed -e 's/.*"\(.*libclang_rt.asan_osx_dynamic.dylib\)".*/\1/'` \
+// RUN: %T/dyld_insert_libraries_remove/libclang_rt.asan_osx_dynamic.dylib
+
+// RUN: %clangxx_asan %s -o %T/dyld_insert_libraries_remove/a.out
+// RUN: %clangxx -DSHARED_LIB %s \
+// RUN: -dynamiclib -o %T/dyld_insert_libraries_remove/dummy-so.dylib
+
+// RUN: ( cd %T/dyld_insert_libraries_remove && \
+// RUN: DYLD_INSERT_LIBRARIES=@executable_path/libclang_rt.asan_osx_dynamic.dylib:dummy-so.dylib \
+// RUN: %run ./a.out 2>&1 ) | FileCheck %s || exit 1
+
+// RUN: ( cd %T/dyld_insert_libraries_remove && \
+// RUN: DYLD_INSERT_LIBRARIES=libclang_rt.asan_osx_dynamic.dylib:dummy-so.dylib \
+// RUN: %run ./a.out 2>&1 ) | FileCheck %s || exit 1
+
+// RUN: ( cd %T/dyld_insert_libraries_remove && \
+// RUN: DYLD_INSERT_LIBRARIES=%T/dyld_insert_libraries_remove/libclang_rt.asan_osx_dynamic.dylib:dummy-so.dylib \
+// RUN: %run ./a.out 2>&1 ) | FileCheck %s || exit 1
+
+#if !defined(SHARED_LIB)
+#include <stdio.h>
+#include <stdlib.h>
+
+int main() {
+ const char kEnvName[] = "DYLD_INSERT_LIBRARIES";
+ printf("%s=%s\n", kEnvName, getenv(kEnvName));
+ // CHECK: {{DYLD_INSERT_LIBRARIES=dummy-so.dylib}}
+ return 0;
+}
+#else // SHARED_LIB
+void foo() {}
+#endif // SHARED_LIB
diff --git a/test/asan/TestCases/Darwin/interception-in-shared-lib-test.cc b/test/asan/TestCases/Darwin/interception-in-shared-lib-test.cc
index e472a9dc6972..028683d2fc41 100644
--- a/test/asan/TestCases/Darwin/interception-in-shared-lib-test.cc
+++ b/test/asan/TestCases/Darwin/interception-in-shared-lib-test.cc
@@ -3,11 +3,11 @@
// ../Linux/interception-in-shared-lib-test.cc.
// RUN: %clangxx_asan -O0 %s -DSHARED_LIB \
-// RUN: -shared -o %T/libinterception-in-shared-lib-test.so \
-// RUN: -fPIC
+// RUN: -shared -o %t-so.so \
+// RUN: -fPIC -install_name @rpath/interception-in-shared-lib-test.cc.tmp-so.so
// TODO(glider): figure out how to set rpath in a more portable way and unite
// this test with ../Linux/interception-in-shared-lib-test.cc.
-// RUN: %clangxx_asan -O0 %s -o %t -Wl,-rpath,@executable-path -L%T -linterception-in-shared-lib-test && \
+// RUN: %clangxx_asan -O0 %s -o %t -Wl,-rpath,@executable_path %t-so.so && \
// RUN: not %run %t 2>&1 | FileCheck %s
#include <stdio.h>
diff --git a/test/asan/TestCases/Darwin/interface_symbols_darwin.c b/test/asan/TestCases/Darwin/interface_symbols_darwin.c
index 8680d678cf91..a75044d491fb 100644
--- a/test/asan/TestCases/Darwin/interface_symbols_darwin.c
+++ b/test/asan/TestCases/Darwin/interface_symbols_darwin.c
@@ -31,6 +31,15 @@
// RUN: echo __asan_report_store_n >> %t.interface
// RUN: echo __asan_get_current_fake_stack >> %t.interface
// RUN: echo __asan_addr_is_in_fake_stack >> %t.interface
+// RUN: echo __asan_mz_calloc >> %t.interface
+// RUN: echo __asan_mz_destroy >> %t.interface
+// RUN: echo __asan_mz_free >> %t.interface
+// RUN: echo __asan_mz_malloc >> %t.interface
+// RUN: echo __asan_mz_memalign >> %t.interface
+// RUN: echo __asan_mz_realloc >> %t.interface
+// RUN: echo __asan_mz_size >> %t.interface
+// RUN: echo __asan_mz_valloc >> %t.interface
+
// RUN: for i in `jot - 0 10`; do echo __asan_stack_malloc_$i >> %t.interface; done
// RUN: for i in `jot - 0 10`; do echo __asan_stack_free_$i >> %t.interface; done
diff --git a/test/asan/TestCases/Darwin/linked-only.cc b/test/asan/TestCases/Darwin/linked-only.cc
new file mode 100644
index 000000000000..bb19ea8535e2
--- /dev/null
+++ b/test/asan/TestCases/Darwin/linked-only.cc
@@ -0,0 +1,33 @@
+// Main executable is uninstrumented, but linked to ASan runtime.
+// Regression test for https://code.google.com/p/address-sanitizer/issues/detail?id=357.
+
+// RUN: %clangxx -g -O0 %s -c -o %t.o
+// RUN: %clangxx_asan -g -O0 %t.o -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sanitizer/asan_interface.h"
+
+void test_shadow(char *p, size_t size) {
+ fprintf(stderr, "p = %p\n", p);
+ char *q = (char *)__asan_region_is_poisoned(p, size);
+ fprintf(stderr, "=%zd=\n", q ? q - p : -1);
+}
+
+int main(int argc, char *argv[]) {
+ char *p = (char *)malloc(10000);
+ test_shadow(p, 100);
+ free(p);
+ // CHECK: =-1=
+
+ test_shadow((char *)&main, 1);
+ // CHECK: =-1=
+
+ test_shadow((char *)&p, 1);
+ // CHECK: =-1=
+
+ return 0;
+}
diff --git a/test/asan/TestCases/Darwin/mixing-global-constructors.cc b/test/asan/TestCases/Darwin/mixing-global-constructors.cc
new file mode 100644
index 000000000000..0b0f15cc78d5
--- /dev/null
+++ b/test/asan/TestCases/Darwin/mixing-global-constructors.cc
@@ -0,0 +1,42 @@
+// A global constructor from a non-instrumented part calls a function
+// in an instrumented part.
+// Regression test for https://code.google.com/p/address-sanitizer/issues/detail?id=363.
+
+// RUN: %clangxx -DINSTRUMENTED_PART=0 -c %s -o %t-uninst.o
+// RUN: %clangxx_asan -DINSTRUMENTED_PART=1 -c %s -o %t-inst.o
+// RUN: %clangxx_asan %t-uninst.o %t-inst.o -o %t
+
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void func(char *ptr);
+
+#if INSTRUMENTED_PART == 1
+
+void func(char *ptr) {
+ *ptr = 'X';
+}
+
+#else // INSTRUMENTED_PART == 1
+
+struct C1 {
+ C1() {
+ printf("Hello ");
+ char buffer[10] = "world";
+ func(buffer);
+ printf("%s\n", buffer);
+ }
+};
+
+C1 *obj = new C1();
+
+int main(int argc, const char *argv[]) {
+ return 0;
+}
+
+#endif // INSTRUMENTED_PART == 1
+
+// CHECK: Hello Xorld
diff --git a/test/asan/TestCases/Darwin/suppressions-darwin.cc b/test/asan/TestCases/Darwin/suppressions-darwin.cc
index 9a8f56d5dc50..fb37296d404f 100644
--- a/test/asan/TestCases/Darwin/suppressions-darwin.cc
+++ b/test/asan/TestCases/Darwin/suppressions-darwin.cc
@@ -4,17 +4,17 @@
// Check that suppressing the interceptor by name works.
// RUN: echo "interceptor_name:memmove" > %t.supp
-// RUN: ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
// Check that suppressing by interceptor name works even without the symbolizer
-// RUN: ASAN_OPTIONS=suppressions=%t.supp:symbolize=false %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: ASAN_OPTIONS="suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
// Check that suppressing all reports from a library works.
// RUN: echo "interceptor_via_lib:CoreFoundation" > %t.supp
-// RUN: ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
// Check that suppressing library works even without the symbolizer.
-// RUN: ASAN_OPTIONS=suppressions=%t.supp:symbolize=false %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: ASAN_OPTIONS="suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
#include <CoreFoundation/CoreFoundation.h>
diff --git a/test/asan/TestCases/Linux/asan_preload_test-2.cc b/test/asan/TestCases/Linux/asan_preload_test-2.cc
index 00b32e15d17d..0f22264cf1fb 100644
--- a/test/asan/TestCases/Linux/asan_preload_test-2.cc
+++ b/test/asan/TestCases/Linux/asan_preload_test-2.cc
@@ -10,11 +10,11 @@
#include <stdlib.h>
-extern "C" void *memset(void *p, int val, size_t n);
+extern "C" ssize_t write(int fd, const void *buf, size_t count);
void do_access(void *p) {
// CHECK: AddressSanitizer: heap-buffer-overflow
- memset(p, 0, 2);
+ write(1, p, 2);
}
int main(int argc, char **argv) {
diff --git a/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc b/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc
index 0201425106f9..7598f6bc7bc5 100644
--- a/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc
+++ b/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc
@@ -6,7 +6,7 @@
//
// REQUIRES: asan-64-bits
-#include <sanitizer/common_interface_defs.h>
+#include <sanitizer/coverage_interface.h>
#include <stdio.h>
#include <assert.h>
int P = 0;
diff --git a/test/asan/TestCases/Linux/coverage-direct-activation.cc b/test/asan/TestCases/Linux/coverage-direct-activation.cc
new file mode 100644
index 000000000000..9b2a0d8897c8
--- /dev/null
+++ b/test/asan/TestCases/Linux/coverage-direct-activation.cc
@@ -0,0 +1,59 @@
+// Test for direct coverage writing enabled at activation time.
+
+// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_direct_activation_test_1.so -fPIC
+// RUN: %clangxx -c -DSO_DIR=\"%T\" %s -o %t.o
+// RUN: %clangxx_asan -fsanitize-coverage=1 %t.o %libdl -o %t
+
+// RUN: rm -rf %T/coverage-direct-activation
+
+// RUN: mkdir -p %T/coverage-direct-activation/normal
+// RUN: ASAN_OPTIONS=coverage=1,coverage_direct=0,coverage_dir=%T/coverage-direct-activation/normal:verbosity=1 %run %t
+// RUN: %sancov print %T/coverage-direct-activation/normal/*.sancov >%T/coverage-direct-activation/normal/out.txt
+
+// RUN: mkdir -p %T/coverage-direct-activation/direct
+// RUN: ASAN_OPTIONS=start_deactivated=1,coverage_direct=1,verbosity=1 \
+// RUN: ASAN_ACTIVATION_OPTIONS=coverage=1,coverage_dir=%T/coverage-direct-activation/direct %run %t
+// RUN: cd %T/coverage-direct-activation/direct
+// RUN: %sancov rawunpack *.sancov.raw
+// RUN: %sancov print *.sancov >out.txt
+// RUN: cd ../..
+
+// Test start_deactivated=1,coverage=1 in ASAN_OPTIONS.
+
+// RUN: diff -u coverage-direct-activation/normal/out.txt coverage-direct-activation/direct/out.txt
+
+// RUN: mkdir -p %T/coverage-direct-activation/direct2
+// RUN: ASAN_OPTIONS=start_deactivated=1,coverage=1,coverage_direct=1,verbosity=1 \
+// RUN: ASAN_ACTIVATION_OPTIONS=coverage_dir=%T/coverage-direct-activation/direct2 %run %t
+// RUN: cd %T/coverage-direct-activation/direct2
+// RUN: %sancov rawunpack *.sancov.raw
+// RUN: %sancov print *.sancov >out.txt
+// RUN: cd ../..
+
+// RUN: diff -u coverage-direct-activation/normal/out.txt coverage-direct-activation/direct2/out.txt
+
+// XFAIL: android
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef SHARED
+extern "C" {
+void bar() { printf("bar\n"); }
+}
+#else
+
+int main(int argc, char **argv) {
+ fprintf(stderr, "PID: %d\n", getpid());
+ void *handle1 =
+ dlopen(SO_DIR "/libcoverage_direct_activation_test_1.so", RTLD_LAZY);
+ assert(handle1);
+ void (*bar1)() = (void (*)())dlsym(handle1, "bar");
+ assert(bar1);
+ bar1();
+
+ return 0;
+}
+#endif
diff --git a/test/asan/TestCases/Linux/coverage-direct-large.cc b/test/asan/TestCases/Linux/coverage-direct-large.cc
index 78aa68621ad1..25c950e0bb30 100644
--- a/test/asan/TestCases/Linux/coverage-direct-large.cc
+++ b/test/asan/TestCases/Linux/coverage-direct-large.cc
@@ -1,7 +1,9 @@
// Test for direct coverage writing with lots of data.
// Current implementation maps output file in chunks of 64K. This test overflows
// 1 chunk.
-// RUN: %clangxx_asan -fsanitize-coverage=1 -O0 %s -o %t
+
+// RUN: %clangxx_asan -fsanitize-coverage=1 -O0 -DSHARED %s -shared -o %T/libcoverage_direct_large_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=1 -O0 -DSO_DIR=\"%T\" %s %libdl -o %t
// RUN: rm -rf %T/coverage-direct-large
@@ -34,12 +36,30 @@
F3(Q, x##0) F3(Q, x##1) F3(Q, x##2) F3(Q, x##3) F3(Q, x##4) F3(Q, x##5) \
F3(Q, x##6) F3(Q, x##7) F3(Q, x##8) F3(Q, x##9)
-#define DECL(x) __attribute__((noinline)) void x() {}
+#define DECL(x) __attribute__((noinline)) static void x() {}
#define CALL(x) x();
F4(DECL, f)
+#ifdef SHARED
+extern "C" void so_entry() {
+ F4(CALL, f)
+}
+#else
+
+#include <assert.h>
+#include <dlfcn.h>
int main(void) {
F4(CALL, f)
+
+ void *handle1 =
+ dlopen(SO_DIR "/libcoverage_direct_large_test_1.so", RTLD_LAZY);
+ assert(handle1);
+ void (*so_entry)() = (void (*)())dlsym(handle1, "so_entry");
+ assert(so_entry);
+ so_entry();
+
return 0;
}
+
+#endif // SHARED
diff --git a/test/asan/TestCases/Linux/coverage-direct.cc b/test/asan/TestCases/Linux/coverage-direct.cc
index 2cc1aed0a0fa..45222fa1a03e 100644
--- a/test/asan/TestCases/Linux/coverage-direct.cc
+++ b/test/asan/TestCases/Linux/coverage-direct.cc
@@ -1,6 +1,26 @@
-// Test for direct coverage writing with dlopen.
+// Test for direct coverage writing with dlopen at coverage level 1 to 3.
+
// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_direct_test_1.so -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%T\" %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%T\" %s %libdl -o %t
+
+// RUN: rm -rf %T/coverage-direct
+
+// RUN: mkdir -p %T/coverage-direct/normal
+// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t
+// RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt
+
+// RUN: mkdir -p %T/coverage-direct/direct
+// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t
+// RUN: cd %T/coverage-direct/direct
+// RUN: %sancov rawunpack *.sancov.raw
+// RUN: %sancov print *.sancov >out.txt
+// RUN: cd ../..
+
+// RUN: diff -u coverage-direct/normal/out.txt coverage-direct/direct/out.txt
+
+
+// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED %s -shared -o %T/libcoverage_direct_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=2 -DSO_DIR=\"%T\" %s %libdl -o %t
// RUN: rm -rf %T/coverage-direct
@@ -16,7 +36,26 @@
// RUN: cd ../..
// RUN: diff -u coverage-direct/normal/out.txt coverage-direct/direct/out.txt
-//
+
+
+// RUN: %clangxx_asan -fsanitize-coverage=3 -DSHARED %s -shared -o %T/libcoverage_direct_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=3 -DSO_DIR=\"%T\" %s %libdl -o %t
+
+// RUN: rm -rf %T/coverage-direct
+
+// RUN: mkdir -p %T/coverage-direct/normal
+// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t
+// RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt
+
+// RUN: mkdir -p %T/coverage-direct/direct
+// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t
+// RUN: cd %T/coverage-direct/direct
+// RUN: %sancov rawunpack *.sancov.raw
+// RUN: %sancov print *.sancov >out.txt
+// RUN: cd ../..
+
+// RUN: diff -u coverage-direct/normal/out.txt coverage-direct/direct/out.txt
+
// XFAIL: android
#include <assert.h>
diff --git a/test/asan/TestCases/Linux/coverage-disabled.cc b/test/asan/TestCases/Linux/coverage-disabled.cc
index a75b26dc02e9..cb33542a5701 100644
--- a/test/asan/TestCases/Linux/coverage-disabled.cc
+++ b/test/asan/TestCases/Linux/coverage-disabled.cc
@@ -12,6 +12,8 @@
// RUN: ASAN_OPTIONS=coverage_direct=1:coverage_dir=%T/coverage-disabled/direct:verbosity=1 %run %t
// RUN: cd %T/coverage-disabled/direct
// RUN: not %sancov rawunpack *.sancov
+//
+// XFAIL: android
int main(int argc, char **argv) {
return 0;
diff --git a/test/asan/TestCases/Linux/coverage-levels.cc b/test/asan/TestCases/Linux/coverage-levels.cc
index 748ef1f08db5..cc196c5a9e18 100644
--- a/test/asan/TestCases/Linux/coverage-levels.cc
+++ b/test/asan/TestCases/Linux/coverage-levels.cc
@@ -1,11 +1,15 @@
// Test various levels of coverage
//
// RUN: %clangxx_asan -O1 -fsanitize-coverage=1 %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
// RUN: %clangxx_asan -O1 -fsanitize-coverage=2 %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2
// RUN: %clangxx_asan -O1 -fsanitize-coverage=3 %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3
+// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3
+
+// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET
+// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET
+// RUN: ASAN_OPTIONS=coverage=1:coverage_pcs=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOPCS
//
// REQUIRES: asan-64-bits
@@ -15,6 +19,11 @@ int main(int argc, char **argv) {
sink = 0;
}
+// CHECK1: CovDump: bitset of 1 bits written, 1 bits are set
// CHECK1: 1 PCs written
+// CHECK2: CovDump: bitset of 3 bits written, 2 bits are set
// CHECK2: 2 PCs written
+// CHECK3: CovDump: bitset of 4 bits written, 3 bits are set
// CHECK3: 3 PCs written
+// CHECK3_NOBITSET-NOT: bitset of
+// CHECK3_NOPCS-NOT: PCs written
diff --git a/test/asan/TestCases/Linux/coverage-maybe-open-file.cc b/test/asan/TestCases/Linux/coverage-maybe-open-file.cc
index 4664cef7f5af..4580de411799 100644
--- a/test/asan/TestCases/Linux/coverage-maybe-open-file.cc
+++ b/test/asan/TestCases/Linux/coverage-maybe-open-file.cc
@@ -13,7 +13,7 @@
#include <string.h>
#include <unistd.h>
-#include <sanitizer/common_interface_defs.h>
+#include <sanitizer/coverage_interface.h>
int main(int argc, char **argv) {
int fd = __sanitizer_maybe_open_cov_file("test");
diff --git a/test/asan/TestCases/Linux/coverage-module-unloaded.cc b/test/asan/TestCases/Linux/coverage-module-unloaded.cc
index 449841e78189..f8d9c57f81be 100644
--- a/test/asan/TestCases/Linux/coverage-module-unloaded.cc
+++ b/test/asan/TestCases/Linux/coverage-module-unloaded.cc
@@ -2,7 +2,7 @@
// modules.
// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_module_unloaded_test_1.so -fPIC
// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_module_unloaded_test_2.so -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%T\" %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%T\" %s %libdl -o %t
// RUN: export ASAN_OPTIONS=coverage=1:verbosity=1
// RUN: mkdir -p %T/coverage-module-unloaded && cd %T/coverage-module-unloaded
// RUN: %run %t 2>&1 | FileCheck %s
diff --git a/test/asan/TestCases/Linux/coverage-reset.cc b/test/asan/TestCases/Linux/coverage-reset.cc
new file mode 100644
index 000000000000..d3d35e21b5a7
--- /dev/null
+++ b/test/asan/TestCases/Linux/coverage-reset.cc
@@ -0,0 +1,52 @@
+// Test __sanitizer_reset_coverage().
+
+// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t
+// RUN: ASAN_OPTIONS=coverage=1 %run %t
+
+#include <sanitizer/coverage_interface.h>
+#include <stdio.h>
+#include <assert.h>
+static volatile int sink;
+__attribute__((noinline)) void bar() { sink = 2; }
+__attribute__((noinline)) void foo() { sink = 1; }
+
+#define GET_AND_PRINT_COVERAGE() \
+ bitset = 0; \
+ for (size_t i = 0; i < n_guards; i++) \
+ if (guards[i]) bitset |= 1U << i; \
+ printf("line %d: bitset %zd total: %zd\n", __LINE__, bitset, \
+ __sanitizer_get_total_unique_coverage());
+
+#define IS_POWER_OF_TWO(a) ((a & ((a) - 1)) == 0)
+
+int main() {
+ size_t *guards = 0;
+ size_t bitset;
+ size_t n_guards = __sanitizer_get_coverage_guards(&guards);
+
+ GET_AND_PRINT_COVERAGE();
+ size_t main_bit = bitset;
+ assert(IS_POWER_OF_TWO(main_bit));
+
+ foo();
+ GET_AND_PRINT_COVERAGE();
+ size_t foo_bit = bitset & ~main_bit;
+ assert(IS_POWER_OF_TWO(foo_bit));
+
+ bar();
+ GET_AND_PRINT_COVERAGE();
+ size_t bar_bit = bitset & ~(main_bit | foo_bit);
+ assert(IS_POWER_OF_TWO(bar_bit));
+
+ __sanitizer_reset_coverage();
+ GET_AND_PRINT_COVERAGE();
+ assert(bitset == 0);
+
+ foo();
+ GET_AND_PRINT_COVERAGE();
+ assert(bitset == foo_bit);
+
+ bar();
+ GET_AND_PRINT_COVERAGE();
+ assert(bitset == (foo_bit | bar_bit));
+}
diff --git a/test/asan/TestCases/Linux/coverage-sandboxing.cc b/test/asan/TestCases/Linux/coverage-sandboxing.cc
index 56f9c40f4cc0..1a72c6bb9a6e 100644
--- a/test/asan/TestCases/Linux/coverage-sandboxing.cc
+++ b/test/asan/TestCases/Linux/coverage-sandboxing.cc
@@ -27,7 +27,7 @@
#include <string.h>
#include <unistd.h>
-#include <sanitizer/common_interface_defs.h>
+#include <sanitizer/coverage_interface.h>
#define bb0(n) \
case n: \
diff --git a/test/asan/TestCases/Linux/coverage-tracing.cc b/test/asan/TestCases/Linux/coverage-tracing.cc
index 89ab0d283add..49dbb5e9528b 100644
--- a/test/asan/TestCases/Linux/coverage-tracing.cc
+++ b/test/asan/TestCases/Linux/coverage-tracing.cc
@@ -2,21 +2,49 @@
//
// RUN: %clangxx_asan -O1 -fsanitize-coverage=1 -mllvm -sanitizer-coverage-experimental-tracing %s -o %t
// RUN: rm -rf %T/coverage-tracing
-// RUN: mkdir -p %T/coverage-tracing
-// RUN: ASAN_OPTIONS=coverage=1:coverage_dir=%T/coverage-tracing:verbosity=1 %run %t 1 2 3 4 2>&1 | FileCheck %s
+// RUN: mkdir %T/coverage-tracing
+// RUN: cd %T/coverage-tracing
+// RUN: A=x; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK1; mv trace-points.*.sancov $A.points
+// RUN: A=f; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points
+// RUN: A=b; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points
+// RUN: A=bf; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points
+// RUN: A=fb; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points
+// RUN: A=ffb; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points
+// RUN: A=fff; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points
+// RUN: A=bbf; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 100 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK301; mv trace-points.*.sancov $A.points
+// RUN: diff f.points fff.points
+// RUN: diff bf.points fb.points
+// RUN: diff bf.points ffb.points
+// RUN: diff bf.points bbf.points
+// RUN: not diff x.points f.points
+// RUN: not diff x.points b.points
+// RUN: not diff x.points bf.points
+// RUN: not diff f.points b.points
+// RUN: not diff f.points bf.points
+// RUN: not diff b.points bf.points
// RUN: rm -rf %T/coverage-tracing
//
// REQUIRES: asan-64-bits
+#include <stdlib.h>
volatile int sink;
+__attribute__((noinline)) void foo() { sink++; }
+__attribute__((noinline)) void bar() { sink++; }
+
int main(int argc, char **argv) {
- volatile int i = 0;
- do {
- sink = 0;
- i++;
- } while (i < argc);
- return 0;
+ if (argc != 3) return 0;
+ int n = strtol(argv[2], 0, 10);
+ while (n-- > 0) {
+ for (int i = 0; argv[1][i]; i++) {
+ if (argv[1][i] == 'f') foo();
+ else if (argv[1][i] == 'b') bar();
+ }
+ }
}
-// CHECK: CovDump: Trace: {{[3-9]}} PCs written
-// CHECK: CovDump: Trace: {{[6-9]}} Events written
+// CHECK: CovDump: Trace: 3 PCs written
+// CHECK1: CovDump: Trace: 1 Events written
+// CHECK2: CovDump: Trace: 2 Events written
+// CHECK3: CovDump: Trace: 3 Events written
+// CHECK4: CovDump: Trace: 4 Events written
+// CHECK301: CovDump: Trace: 301 Events written
diff --git a/test/asan/TestCases/Linux/coverage.cc b/test/asan/TestCases/Linux/coverage.cc
index f6eb0ae9285b..06fe1a295eaf 100644
--- a/test/asan/TestCases/Linux/coverage.cc
+++ b/test/asan/TestCases/Linux/coverage.cc
@@ -13,7 +13,7 @@
// https://code.google.com/p/address-sanitizer/issues/detail?id=263
// XFAIL: android
-#include "sanitizer/common_interface_defs.h"
+#include <sanitizer/coverage_interface.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
diff --git a/test/asan/TestCases/Linux/malloc-in-qsort.cc b/test/asan/TestCases/Linux/malloc-in-qsort.cc
index 545bc7e42a17..80af409d66a9 100644
--- a/test/asan/TestCases/Linux/malloc-in-qsort.cc
+++ b/test/asan/TestCases/Linux/malloc-in-qsort.cc
@@ -39,15 +39,12 @@ int main() {
return GlobalPtr[10];
}
-// Fast unwind: can not unwind through qsort.
-// FIXME: this test does not properly work with slow unwind yet.
-
+// Fast unwind may not unwind through qsort.
// CHECK-FAST: ERROR: AddressSanitizer: heap-buffer-overflow
// CHECK-FAST: is located 0 bytes to the right
// CHECK-FAST: #0{{.*}}operator new
// CHECK-FAST-NEXT: #1{{.*}}QsortCallback
-// CHECK-FAST-NOT: MyQsort
-//
+
// CHECK-SLOW: ERROR: AddressSanitizer: heap-buffer-overflow
// CHECK-SLOW: is located 0 bytes to the right
// CHECK-SLOW: #0{{.*}}operator new
diff --git a/test/asan/TestCases/Linux/nohugepage_test.cc b/test/asan/TestCases/Linux/nohugepage_test.cc
new file mode 100644
index 000000000000..b549f3bc2119
--- /dev/null
+++ b/test/asan/TestCases/Linux/nohugepage_test.cc
@@ -0,0 +1,91 @@
+// Regression test for
+// https://code.google.com/p/chromium/issues/detail?id=446692
+// where asan consumed too much RAM due to transparent hugetables.
+//
+// RUN: %clangxx_asan -g %s -o %t
+// RUN: ASAN_OPTIONS=no_huge_pages_for_shadow=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
+//
+// Would be great to run the test with no_huge_pages_for_shadow=0, but
+// the result will depend on the OS version and settings...
+//
+// REQUIRES: x86_64-supported-target, asan-64-bits
+//
+// WARNING: this test is very subtle and may nto work on some systems.
+// If this is the case we'll need to futher improve it or disable it.
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sanitizer/asan_interface.h>
+
+char FileContents[1 << 14];
+
+void FileToString(const char *path) {
+ FileContents[0] = 0;
+ int fd = open(path, 0);
+ if (fd < 0) return;
+ ssize_t res = read(fd, FileContents, sizeof(FileContents) - 1);
+ if (res >= 0)
+ FileContents[res] = 0;
+}
+
+long ReadShadowRss() {
+ const char *path = "/proc/self/smaps";
+ FileToString(path);
+ char *s = strstr(FileContents, "2008fff7000-10007fff8000");
+ if (!s) return 0;
+
+ s = strstr(s, "Rss:");
+ if (!s) return 0;
+ s = s + 4;
+ return atol(s);
+}
+
+const int kAllocSize = 1 << 28; // 256Mb
+const int kTwoMb = 1 << 21;
+const int kAsanShadowGranularity = 8;
+
+char *x;
+
+__attribute__((no_sanitize_address)) void TouchNoAsan(size_t i) { x[i] = 0; }
+
+int main() {
+ long rss[5];
+ rss[0] = ReadShadowRss();
+ // use mmap directly to avoid asan touching the shadow.
+ x = (char *)mmap(0, kAllocSize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, 0, 0);
+ fprintf(stderr, "X: %p-%p\n", x, x + kAllocSize);
+ rss[1] = ReadShadowRss();
+
+ // Touch the allocated region, but not the shadow.
+ for (size_t i = 0; i < kAllocSize; i += kTwoMb * kAsanShadowGranularity)
+ TouchNoAsan(i);
+ rss[2] = ReadShadowRss();
+
+ // Touch the shadow just a bit, in 2Mb*Granularity steps.
+ for (size_t i = 0; i < kAllocSize; i += kTwoMb * kAsanShadowGranularity)
+ __asan_poison_memory_region(x + i, kAsanShadowGranularity);
+ rss[3] = ReadShadowRss();
+
+ // Touch all the shadow.
+ __asan_poison_memory_region(x, kAllocSize);
+ rss[4] = ReadShadowRss();
+
+ // Print the differences.
+ for (int i = 0; i < 4; i++) {
+ assert(rss[i] > 0);
+ assert(rss[i+1] >= rss[i]);
+ long diff = rss[i+1] / rss[i];
+ fprintf(stderr, "RSS CHANGE IS %d => %d: %s (%ld vs %ld)\n", i, i + 1,
+ diff < 10 ? "SMALL" : "LARGE", rss[i], rss[i + 1]);
+ }
+}
+// CHECK: RSS CHANGE IS 2 => 3: SMALL
+// CHECK: RSS CHANGE IS 3 => 4: LARGE
diff --git a/test/asan/TestCases/Linux/overflow-in-qsort.cc b/test/asan/TestCases/Linux/overflow-in-qsort.cc
index 79b654e117cd..21bdff60cd30 100644
--- a/test/asan/TestCases/Linux/overflow-in-qsort.cc
+++ b/test/asan/TestCases/Linux/overflow-in-qsort.cc
@@ -37,11 +37,9 @@ int main() {
MyQsort(a, 2);
}
-// Fast unwind: can not unwind through qsort.
-
+// Fast unwind may not unwind through qsort.
// CHECK-FAST: ERROR: AddressSanitizer: global-buffer-overflow
// CHECK-FAST: #0{{.*}} in QsortCallback
-// CHECK-FAST-NOT: MyQsort
// CHECK-FAST: is located 0 bytes to the right of global variable 'global_array
// CHECK-SLOW: ERROR: AddressSanitizer: global-buffer-overflow
diff --git a/test/asan/TestCases/Linux/quarantine_size_mb.cc b/test/asan/TestCases/Linux/quarantine_size_mb.cc
new file mode 100644
index 000000000000..4499992444f9
--- /dev/null
+++ b/test/asan/TestCases/Linux/quarantine_size_mb.cc
@@ -0,0 +1,24 @@
+// Test quarantine_size_mb (and the deprecated quarantine_size)
+// RUN: %clangxx_asan %s -o %t
+// RUN: ASAN_OPTIONS=quarantine_size=10485760:verbosity=1:hard_rss_limit_mb=50 %run %t 2>&1 | FileCheck %s --check-prefix=Q10
+// RUN: ASAN_OPTIONS=quarantine_size_mb=10:verbosity=1:hard_rss_limit_mb=50 %run %t 2>&1 | FileCheck %s --check-prefix=Q10
+// RUN: ASAN_OPTIONS=quarantine_size_mb=10:quarantine_size=20:verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=BOTH
+// RUN: ASAN_OPTIONS=quarantine_size_mb=1000:hard_rss_limit_mb=50 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT
+// RUN: ASAN_OPTIONS=hard_rss_limit_mb=50 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT
+#include <string.h>
+char *g;
+
+static const int kNumAllocs = 1 << 11;
+static const int kAllocSize = 1 << 20;
+
+int main() {
+ for (int i = 0; i < kNumAllocs; i++) {
+ g = new char[kAllocSize];
+ memset(g, -1, kAllocSize);
+ delete [] (g);
+ }
+}
+
+// Q10: quarantine_size_mb=10M
+// BOTH: please use either 'quarantine_size' (deprecated) or quarantine_size_mb, but not both
+// RSS_LIMIT: AddressSanitizer: hard rss limit exhausted
diff --git a/test/asan/TestCases/Linux/sized_delete_test.cc b/test/asan/TestCases/Linux/sized_delete_test.cc
index 823e3c0bf88e..343cb0a86fed 100644
--- a/test/asan/TestCases/Linux/sized_delete_test.cc
+++ b/test/asan/TestCases/Linux/sized_delete_test.cc
@@ -8,7 +8,7 @@
// Sized-delete is implemented with a weak delete() definition.
// Weak symbols are kind of broken on Android.
-// XFAIL: android
+// XFAIL: android, asan-dynamic-runtime
#include <new>
#include <stdio.h>
diff --git a/test/asan/TestCases/Linux/stack-overflow-sigbus.cc b/test/asan/TestCases/Linux/stack-overflow-sigbus.cc
new file mode 100644
index 000000000000..5f597e9c51f0
--- /dev/null
+++ b/test/asan/TestCases/Linux/stack-overflow-sigbus.cc
@@ -0,0 +1,64 @@
+// Test ASan detection of stack-overflow condition when Linux sends SIGBUS.
+
+// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+
+const int BS = 1024;
+volatile char x;
+volatile int y = 1;
+
+void recursive_func(char *p) {
+ char buf[BS];
+ buf[rand() % BS] = 1;
+ buf[rand() % BS] = 2;
+ x = buf[rand() % BS];
+ if (y)
+ recursive_func(buf);
+ x = 1; // prevent tail call optimization
+ // CHECK: {{stack-overflow on address 0x.* \(pc 0x.* bp 0x.* sp 0x.* T.*\)}}
+}
+
+void LimitStackAndReexec(int argc, char **argv) {
+ struct rlimit rlim;
+ int res = getrlimit(RLIMIT_STACK, &rlim);
+ assert(res == 0);
+ if (rlim.rlim_cur == RLIM_INFINITY) {
+ rlim.rlim_cur = 256 * 1024;
+ res = setrlimit(RLIMIT_STACK, &rlim);
+ assert(res == 0);
+
+ execv(argv[0], argv);
+ assert(0 && "unreachable");
+ }
+}
+
+int main(int argc, char **argv) {
+ LimitStackAndReexec(argc, argv);
+
+ // Map some memory just before the start of the current stack vma.
+ // When the stack grows down and crashes into it, Linux can send
+ // SIGBUS instead of SIGSEGV. See:
+ // http://lkml.iu.edu/hypermail/linux/kernel/1008.1/02299.html
+ const long pagesize = sysconf(_SC_PAGESIZE);
+ FILE *f = fopen("/proc/self/maps", "r");
+ char a[1000];
+ void *p = 0;
+ while (fgets(a, sizeof a, f)) {
+ if (strstr(a, "[stack]")) {
+ unsigned long addr;
+ if (sscanf(a, "%lx", &addr) == 1)
+ p = mmap((void *)(addr - 4 * pagesize), pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ }
+ }
+ assert(p);
+
+ recursive_func(0);
+ return 0;
+}
diff --git a/test/asan/TestCases/Linux/stack-trace-dlclose.cc b/test/asan/TestCases/Linux/stack-trace-dlclose.cc
index e494e5661d1d..b3bd9f7780f5 100644
--- a/test/asan/TestCases/Linux/stack-trace-dlclose.cc
+++ b/test/asan/TestCases/Linux/stack-trace-dlclose.cc
@@ -2,7 +2,7 @@
// XFAIL: android
//
// RUN: %clangxx_asan -DSHARED %s -shared -o %T/stack_trace_dlclose.so -fPIC
-// RUN: %clangxx_asan -DSO_DIR=\"%T\" %s -o %t
+// RUN: %clangxx_asan -DSO_DIR=\"%T\" %s %libdl -o %t
// RUN: ASAN_OPTIONS=exitcode=0 %run %t 2>&1 | FileCheck %s
// XFAIL: arm-linux-gnueabi
// XFAIL: armv7l-unknown-linux-gnueabihf
diff --git a/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc b/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc
index 6ed02f4d5374..3ce6446eca22 100644
--- a/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc
+++ b/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc
@@ -5,7 +5,7 @@
// shared object files.
// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: %clangxx_asan -O0 %s %libdl -o %t
// RUN: env ASAN_OPTIONS=symbolize=0 not %run %t 2>&1 | %asan_symbolize | FileCheck %s
// XFAIL: arm-linux-gnueabi
// XFAIL: armv7l-unknown-linux-gnueabihf
diff --git a/test/asan/TestCases/Posix/init-order-dlopen.cc b/test/asan/TestCases/Posix/init-order-dlopen.cc
index 6f204775eb4e..3c6f093b03d1 100644
--- a/test/asan/TestCases/Posix/init-order-dlopen.cc
+++ b/test/asan/TestCases/Posix/init-order-dlopen.cc
@@ -10,8 +10,8 @@
// If the linker doesn't support --export-dynamic (which is ELF-specific),
// try to link without that option.
// FIXME: find a better solution.
-// RUN: %clangxx_asan -O0 %s -pthread -o %t -Wl,--export-dynamic || \
-// RUN: %clangxx_asan -O0 %s -pthread -o %t
+// RUN: %clangxx_asan -O0 %s -pthread %libdl -o %t -Wl,--export-dynamic || \
+// RUN: %clangxx_asan -O0 %s -pthread %libdl -o %t
// RUN: ASAN_OPTIONS=strict_init_order=true %run %t 2>&1 | FileCheck %s
#if !defined(SHARED_LIB)
#include <dlfcn.h>
diff --git a/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc b/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc
index 0a4998049cb0..f852a62ea9a3 100644
--- a/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc
+++ b/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc
@@ -2,7 +2,7 @@
// RUN: %clangxx_asan %s -o %t
// The memory is released only when the deallocated chunk leaves the quarantine,
// otherwise the mmap(p, ...) call overwrites the malloc header.
-// RUN: ASAN_OPTIONS=quarantine_size=1 %run %t
+// RUN: ASAN_OPTIONS=quarantine_size_mb=0 %run %t
#include <assert.h>
#include <string.h>
diff --git a/test/asan/TestCases/Posix/shared-lib-test.cc b/test/asan/TestCases/Posix/shared-lib-test.cc
index a0827b5fefbf..305942a0792d 100644
--- a/test/asan/TestCases/Posix/shared-lib-test.cc
+++ b/test/asan/TestCases/Posix/shared-lib-test.cc
@@ -1,11 +1,11 @@
// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s %libdl -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O1 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O1 %s %libdl -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O2 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O2 %s %libdl -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s %libdl -o %t && not %run %t 2>&1 | FileCheck %s
// XFAIL: arm-linux-gnueabi
#if !defined(SHARED_LIB)
diff --git a/test/asan/TestCases/Posix/start-deactivated.cc b/test/asan/TestCases/Posix/start-deactivated.cc
index d60677a8a5bb..d7e0dfc98e6d 100644
--- a/test/asan/TestCases/Posix/start-deactivated.cc
+++ b/test/asan/TestCases/Posix/start-deactivated.cc
@@ -4,12 +4,25 @@
// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
// RUN: %clangxx -O0 %s -c -o %t.o
-// RUN: %clangxx_asan -O0 %t.o -o %t
-// RUN: ASAN_OPTIONS=start_deactivated=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %t.o %libdl -o %t
+// RUN: ASAN_OPTIONS=start_deactivated=1,allocator_may_return_null=0 \
+// RUN: ASAN_ACTIVATION_OPTIONS=allocator_may_return_null=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
+// RUN: ASAN_OPTIONS=start_deactivated=1 \
+// RUN: ASAN_ACTIVATION_OPTIONS=help=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HELP
+// RUN: ASAN_OPTIONS=start_deactivated=1,verbosity=1 \
+// RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED
+// RUN: ASAN_OPTIONS=start_deactivated=1 \
+// RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED-V0
+
+// Check that verbosity=1 in activation flags affects reporting of unrecognized activation flags.
+// RUN: ASAN_OPTIONS=start_deactivated=1 \
+// RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0,verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED
+
// XFAIL: arm-linux-gnueabi
// XFAIL: armv7l-unknown-linux-gnueabihf
#if !defined(SHARED_LIB)
+#include <assert.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
@@ -43,12 +56,18 @@ int main(int argc, char *argv[]) {
test_malloc_shadow();
// CHECK: =5=
+ // After this line ASan is activated and starts detecting errors.
void *fn = dlsym(dso, "do_another_bad_thing");
if (!fn) {
fprintf(stderr, "dlsym failed: %s\n", dlerror());
return 1;
}
+ // Test that ASAN_ACTIVATION_OPTIONS=allocator_may_return_null=1 has effect.
+ void *p = malloc((unsigned long)-2);
+ assert(!p);
+ // CHECK: WARNING: AddressSanitizer failed to allocate 0xfff{{.*}} bytes
+
((Fn)fn)();
// CHECK: AddressSanitizer: heap-buffer-overflow
// CHECK: READ of size 1
@@ -67,3 +86,16 @@ extern "C" void do_another_bad_thing() {
printf("%hhx\n", p[105]);
}
#endif // SHARED_LIB
+
+// help=1 in activation flags lists only flags are are supported at activation
+// CHECK-HELP: Available flags for {{.*}}Sanitizer:
+// CHECK-HELP-NOT: handle_segv
+// CHECK-HELP: max_redzone
+// CHECK-HELP-NOT: handle_segv
+
+// unsupported activation flags produce a warning ...
+// CHECK-UNSUPPORTED: WARNING: found 1 unrecognized
+// CHECK-UNSUPPORTED: handle_segv
+
+// ... but not at verbosity=0
+// CHECK-UNSUPPORTED-V0-NOT: WARNING: found {{.*}} unrecognized
diff --git a/test/asan/TestCases/Posix/tsd_dtor_leak.cc b/test/asan/TestCases/Posix/tsd_dtor_leak.cc
index 32253afc8b25..6952245227b4 100644
--- a/test/asan/TestCases/Posix/tsd_dtor_leak.cc
+++ b/test/asan/TestCases/Posix/tsd_dtor_leak.cc
@@ -1,7 +1,7 @@
// Regression test for a leak in tsd:
// https://code.google.com/p/address-sanitizer/issues/detail?id=233
// RUN: %clangxx_asan -O1 %s -pthread -o %t
-// RUN: ASAN_OPTIONS=quarantine_size=1 %run %t
+// RUN: ASAN_OPTIONS=quarantine_size_mb=0 %run %t
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
@@ -25,15 +25,17 @@ void Dtor(void *tsd) {
int main() {
assert(0 == pthread_key_create(&tsd_key, Dtor));
- size_t old_heap_size = 0;
+ pthread_t t;
+ for (int i = 0; i < 3; i++) {
+ pthread_create(&t, 0, Thread, 0);
+ pthread_join(t, 0);
+ }
+ size_t old_heap_size = __sanitizer_get_heap_size();
for (int i = 0; i < 10; i++) {
- pthread_t t;
pthread_create(&t, 0, Thread, 0);
pthread_join(t, 0);
size_t new_heap_size = __sanitizer_get_heap_size();
fprintf(stderr, "heap size: new: %zd old: %zd\n", new_heap_size, old_heap_size);
- if (old_heap_size)
- assert(old_heap_size == new_heap_size);
- old_heap_size = new_heap_size;
+ assert(old_heap_size == new_heap_size);
}
}
diff --git a/test/asan/TestCases/Windows/iostream_sbo.cc b/test/asan/TestCases/Windows/iostream_sbo.cc
new file mode 100644
index 000000000000..ffcd53013ec6
--- /dev/null
+++ b/test/asan/TestCases/Windows/iostream_sbo.cc
@@ -0,0 +1,18 @@
+// First, check this works with the default blacklist:
+// RUN: %clang_cl_asan -O0 %s -Fe%t
+// RUN: echo "42" | %run %t 2>&1 | FileCheck %s
+//
+// Then, make sure it still works when a user uses his own blacklist file:
+// RUN: %clang_cl_asan -O0 %s -fsanitize-blacklist=%p/../Helpers/initialization-blacklist.txt -Fe%t2
+// RUN: echo "42" | %run %t2 2>&1 | FileCheck %s
+
+#include <iostream>
+
+int main() {
+ int i;
+ std::cout << "Type i: ";
+ std::cin >> i;
+ return 0;
+// CHECK: Type i:
+// CHECK-NOT: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
+}
diff --git a/test/asan/TestCases/Windows/shadow_mapping_failure.cc b/test/asan/TestCases/Windows/shadow_mapping_failure.cc
new file mode 100644
index 000000000000..97cd3d60cdfa
--- /dev/null
+++ b/test/asan/TestCases/Windows/shadow_mapping_failure.cc
@@ -0,0 +1,18 @@
+// RUN: %clang_cl_asan -O0 %s -Fe%t
+// RUN: not %run %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+
+char bigchunk[1 << 30];
+
+int main() {
+ printf("Hello, world!\n");
+ scanf("%s", bigchunk);
+// CHECK-NOT: Hello, world!
+// CHECK: Shadow memory range interleaves with an existing memory mapping.
+// CHECK: ASan shadow was supposed to be located in the [0x2fff0000-0x{{.*}}ffff] range.
+// CHECK: Dumping process modules:
+// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}shadow_mapping_failure
+// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}kernel32.dll
+// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}ntdll.dll
+}
diff --git a/test/asan/TestCases/Windows/thread_suspended.cc b/test/asan/TestCases/Windows/thread_suspended.cc
new file mode 100644
index 000000000000..47e4f9d5d19b
--- /dev/null
+++ b/test/asan/TestCases/Windows/thread_suspended.cc
@@ -0,0 +1,27 @@
+// RUN: %clang_cl_asan -O0 %s -Fe%t
+// RUN: %run %t
+
+#include <windows.h>
+
+DWORD WINAPI thread_proc(void *) {
+ volatile char stack_buffer[42];
+ for (int i = 0; i < sizeof(stack_buffer); ++i)
+ stack_buffer[i] = 42;
+ return 0x42;
+}
+
+int main() {
+ DWORD exitcode;
+ HANDLE thr = CreateThread(NULL, 0, thread_proc, NULL, CREATE_SUSPENDED, NULL);
+ ResumeThread(thr);
+ if (thr == 0)
+ return 1;
+ if (WAIT_OBJECT_0 != WaitForSingleObject(thr, INFINITE))
+ return 2;
+
+ GetExitCodeThread(thr, &exitcode);
+ if (exitcode != 0x42)
+ return 3;
+ CloseHandle(thr);
+}
+
diff --git a/test/asan/TestCases/allocator_returns_null.cc b/test/asan/TestCases/allocator_returns_null.cc
index 59a053c3dcad..da6fbd43099e 100644
--- a/test/asan/TestCases/allocator_returns_null.cc
+++ b/test/asan/TestCases/allocator_returns_null.cc
@@ -24,14 +24,14 @@
int main(int argc, char **argv) {
volatile size_t size = std::numeric_limits<size_t>::max() - 10000;
assert(argc == 2);
- char *x = 0;
+ void *x = 0;
if (!strcmp(argv[1], "malloc")) {
fprintf(stderr, "malloc:\n");
- x = (char*)malloc(size);
+ x = malloc(size);
}
if (!strcmp(argv[1], "calloc")) {
fprintf(stderr, "calloc:\n");
- x = (char*)calloc(size / 4, 4);
+ x = calloc(size / 4, 4);
}
if (!strcmp(argv[1], "calloc-overflow")) {
@@ -39,18 +39,18 @@ int main(int argc, char **argv) {
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);
+ x = calloc(kArraySize, kArraySize2);
}
if (!strcmp(argv[1], "realloc")) {
fprintf(stderr, "realloc:\n");
- x = (char*)realloc(0, size);
+ x = 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);
+ x = realloc(t, size);
assert(*t == 42);
free(t);
}
diff --git a/test/asan/TestCases/asan_options-help.cc b/test/asan/TestCases/asan_options-help.cc
new file mode 100644
index 000000000000..f10830f16085
--- /dev/null
+++ b/test/asan/TestCases/asan_options-help.cc
@@ -0,0 +1,9 @@
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: ASAN_OPTIONS=help=1 %run %t 2>&1 | FileCheck %s
+
+int main() {
+}
+
+// CHECK: Available flags for AddressSanitizer:
+// CHECK-DAG: handle_segv
+// CHECK-DAG: check_initialization_order
diff --git a/test/asan/TestCases/deep_call_stack.cc b/test/asan/TestCases/deep_call_stack.cc
index 789f23454d19..a5b846e3eb75 100644
--- a/test/asan/TestCases/deep_call_stack.cc
+++ b/test/asan/TestCases/deep_call_stack.cc
@@ -1,7 +1,8 @@
// Check that UAR mode can handle very deep recusrion.
-// export ASAN_OPTIONS=detect_stack_use_after_return=1
+// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1
// RUN: %clangxx_asan -O2 %s -o %t && \
// RUN: (ulimit -s 4096; %run %t) 2>&1 | FileCheck %s
+
// Also check that use_sigaltstack+verbosity doesn't crash.
// RUN: env ASAN_OPTIONS=verbosity=1:use_sigaltstack=1 %run %t | FileCheck %s
#include <stdio.h>
diff --git a/test/asan/TestCases/default_options.cc b/test/asan/TestCases/default_options.cc
index 6453f66a9523..1614fbe71b4b 100644
--- a/test/asan/TestCases/default_options.cc
+++ b/test/asan/TestCases/default_options.cc
@@ -4,12 +4,12 @@
// __asan_default_options() are not supported on Windows.
// XFAIL: win32
-const char *kAsanDefaultOptions="verbosity=1 foo=bar";
+const char *kAsanDefaultOptions="verbosity=1 help=1";
extern "C"
__attribute__((no_sanitize_address))
const char *__asan_default_options() {
- // CHECK: Using the defaults from __asan_default_options: {{.*}} foo=bar
+ // CHECK: Available flags for AddressSanitizer:
return kAsanDefaultOptions;
}
diff --git a/test/asan/TestCases/dlclose-test.cc b/test/asan/TestCases/dlclose-test.cc
index 094453f3de2a..2d31aee5a32f 100644
--- a/test/asan/TestCases/dlclose-test.cc
+++ b/test/asan/TestCases/dlclose-test.cc
@@ -15,13 +15,13 @@
// REQUIRES: x86_64-supported-target,i386-supported-target
// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s %libdl -o %t && %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O1 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O1 %s %libdl -o %t && %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O2 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O2 %s %libdl -o %t && %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s %libdl -o %t && %run %t 2>&1 | FileCheck %s
#if !defined(SHARED_LIB)
#include <assert.h>
diff --git a/test/asan/TestCases/interception_failure_test.cc b/test/asan/TestCases/interception_failure_test.cc
index a23fe6938ca9..53c50090bfa6 100644
--- a/test/asan/TestCases/interception_failure_test.cc
+++ b/test/asan/TestCases/interception_failure_test.cc
@@ -5,6 +5,7 @@
// RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
+// XFAIL: freebsd
#include <stdlib.h>
#include <stdio.h>
diff --git a/test/asan/TestCases/log-path_test.cc b/test/asan/TestCases/log-path_test.cc
index 5a1d0729119a..7dd1fadda86d 100644
--- a/test/asan/TestCases/log-path_test.cc
+++ b/test/asan/TestCases/log-path_test.cc
@@ -13,7 +13,7 @@
// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.log.*
// Invalid log_path.
-// RUN: env ASAN_OPTIONS=log_path=/INVALID not %run %t 2> %t.out
+// RUN: env ASAN_OPTIONS=log_path=/dev/null/INVALID not %run %t 2> %t.out
// RUN: FileCheck %s --check-prefix=CHECK-INVALID < %t.out
// Too long log_path.
@@ -40,5 +40,5 @@ int main(int argc, char **argv) {
return res;
}
// CHECK-ERROR: ERROR: AddressSanitizer
-// CHECK-INVALID: ERROR: Can't open file: /INVALID
+// CHECK-INVALID: ERROR: Can't open file: /dev/null/INVALID
// CHECK-LONG: ERROR: Path is too long: 01234
diff --git a/test/asan/TestCases/stack-overflow.cc b/test/asan/TestCases/stack-overflow.cc
index 7542d56b6db8..d4bb74730f12 100644
--- a/test/asan/TestCases/stack-overflow.cc
+++ b/test/asan/TestCases/stack-overflow.cc
@@ -92,7 +92,7 @@ void LimitStackAndReexec(int argc, char **argv) {
int res = getrlimit(RLIMIT_STACK, &rlim);
assert(res == 0);
if (rlim.rlim_cur == RLIM_INFINITY) {
- rlim.rlim_cur = 128 * 1024;
+ rlim.rlim_cur = 256 * 1024;
res = setrlimit(RLIMIT_STACK, &rlim);
assert(res == 0);
diff --git a/test/asan/TestCases/suppressions-function.cc b/test/asan/TestCases/suppressions-function.cc
index c52b3c303518..0a6c9995827e 100644
--- a/test/asan/TestCases/suppressions-function.cc
+++ b/test/asan/TestCases/suppressions-function.cc
@@ -3,8 +3,8 @@
// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
// RUN: echo "interceptor_via_fun:crash_function" > %t.supp
-// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
-// RUN: %clangxx_asan -O3 %s -o %t && ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: %clangxx_asan -O3 %s -o %t && ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
// XFAIL: android
diff --git a/test/asan/TestCases/suppressions-interceptor.cc b/test/asan/TestCases/suppressions-interceptor.cc
index 10d24fdc30a3..45a14d1a422a 100644
--- a/test/asan/TestCases/suppressions-interceptor.cc
+++ b/test/asan/TestCases/suppressions-interceptor.cc
@@ -3,7 +3,7 @@
// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
// RUN: echo "interceptor_name:strlen" > %t.supp
-// RUN: ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
// XFAIL: android
diff --git a/test/asan/TestCases/suppressions-library.cc b/test/asan/TestCases/suppressions-library.cc
index dfb0d4a5e030..28f19f54efc1 100644
--- a/test/asan/TestCases/suppressions-library.cc
+++ b/test/asan/TestCases/suppressions-library.cc
@@ -1,11 +1,11 @@
-// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
-// RUN: %clangxx_asan -O0 %s %t-so.so -o %t
+// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so -install_name @rpath/suppressions-library.cc.tmp-so.so
+// RUN: %clangxx_asan -O0 %s %t-so.so -o %t -rpath @executable_path
// Check that without suppressions, we catch the issue.
// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
-// RUN: echo "interceptor_via_lib:%t-so.so" > %t.supp
-// RUN: ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: echo "interceptor_via_lib:suppressions-library.cc.tmp-so.so" > %t.supp
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
// XFAIL: android
diff --git a/test/asan/TestCases/zero_page_pc.cc b/test/asan/TestCases/zero_page_pc.cc
index 5810a9fb9dde..925cbc63a305 100644
--- a/test/asan/TestCases/zero_page_pc.cc
+++ b/test/asan/TestCases/zero_page_pc.cc
@@ -6,7 +6,11 @@ int main() {
void_f *func = (void_f *)0x4;
func();
// x86 reports the SEGV with both address=4 and pc=4.
- // PowerPC64 reports it with address=4 but pc still in main().
- // CHECK: {{AddressSanitizer: SEGV.*(address|pc) 0x0*4}}
+ // On PowerPC64 ELFv1, the pointer is taken to be a function-descriptor
+ // pointer out of which three 64-bit quantities are read. This will SEGV, but
+ // the compiler is free to choose the order. As a result, the address is
+ // either 0x4, 0xc or 0x14. The pc is still in main() because it has not
+ // actually made the call when the faulting access occurs.
+ // CHECK: {{AddressSanitizer: SEGV.*(address|pc) 0x0*[4c]}}
return 0;
}
diff --git a/test/asan/Unit/lit.site.cfg.in b/test/asan/Unit/lit.site.cfg.in
index 1791b6b05b1c..b5991023ee8a 100644
--- a/test/asan/Unit/lit.site.cfg.in
+++ b/test/asan/Unit/lit.site.cfg.in
@@ -8,7 +8,7 @@ lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/unittests/lit.common.un
def push_ld_library_path(config, new_path):
new_ld_library_path = os.path.pathsep.join(
- (new_path, config.environment['LD_LIBRARY_PATH']))
+ (new_path, config.environment.get('LD_LIBRARY_PATH', '')))
config.environment['LD_LIBRARY_PATH'] = new_ld_library_path
# Setup config name.
@@ -17,7 +17,13 @@ config.name = 'AddressSanitizer-Unit'
# Setup test source and exec root. For unit tests, we define
# it as build directory with ASan unit tests.
# FIXME: De-hardcode this path.
-config.test_exec_root = "@COMPILER_RT_BINARY_DIR@/lib/asan/tests"
+if @ASAN_TEST_DYNAMIC@:
+ test_dir = "dynamic"
+else:
+ test_dir = "default"
+config.test_exec_root = os.path.join("@COMPILER_RT_BINARY_DIR@",
+ "lib", "asan", "tests", test_dir)
+
config.test_source_root = config.test_exec_root
# Set LD_LIBRARY_PATH to pick dynamic runtime up properly.
diff --git a/test/asan/android_commands/android_run.py b/test/asan/android_commands/android_run.py
index 7f8c612a0cf0..621844fd30a2 100755
--- a/test/asan/android_commands/android_run.py
+++ b/test/asan/android_commands/android_run.py
@@ -14,7 +14,7 @@ def build_env():
args.append('LD_LIBRARY_PATH=%s:%s' %
(ANDROID_TMPDIR, os.environ.get('LD_LIBRARY_PATH', '')))
for (key, value) in os.environ.items():
- if key in ['ASAN_OPTIONS']:
+ if key in ['ASAN_OPTIONS', 'ASAN_ACTIVATION_OPTIONS']:
args.append('%s="%s"' % (key, value))
return ' '.join(args)
diff --git a/test/asan/lit.cfg b/test/asan/lit.cfg
index 82a36de9cdda..8be7062614b3 100644
--- a/test/asan/lit.cfg
+++ b/test/asan/lit.cfg
@@ -19,7 +19,7 @@ def push_dynamic_library_lookup_path(config, new_path):
dynamic_library_lookup_var = 'LD_LIBRARY_PATH'
new_ld_library_path = os.path.pathsep.join(
- (new_path, config.environment[dynamic_library_lookup_var]))
+ (new_path, config.environment.get(dynamic_library_lookup_var, '')))
config.environment[dynamic_library_lookup_var] = new_ld_library_path
# Setup config name.
@@ -28,17 +28,19 @@ config.name = 'AddressSanitizer' + config.name_suffix
# Setup source root.
config.test_source_root = os.path.dirname(__file__)
+# There is no libdl on FreeBSD.
+if config.host_os != 'FreeBSD':
+ libdl_flag = "-ldl"
+else:
+ libdl_flag = ""
+
# GCC-ASan doesn't link in all the necessary libraries automatically, so
# we have to do it ourselves.
if config.compiler_id == 'GNU':
- extra_linkflags = ["-pthread", "-lstdc++"]
+ extra_linkflags = ["-pthread", "-lstdc++", libdl_flag]
else:
extra_linkflags = []
-# There is no libdl on FreeBSD.
-if config.compiler_id == 'GNU' and config.host_os != 'FreeBSD':
- extra_linkflags += ["-ldl"]
-
# Setup default compiler flags used with -fsanitize=address option.
# FIXME: Review the set of required flags and check if it can be reduced.
target_cflags = [get_required_attr(config, "target_cflags")] + extra_linkflags
@@ -121,6 +123,8 @@ else:
config.substitutions.append( ('CHECK-%kernel_bits', ("CHECK-kernel-" + kernel_bits + "-bits")))
+config.substitutions.append( ("%libdl", libdl_flag) )
+
config.available_features.add("asan-" + config.bits + "-bits")
# Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL
diff --git a/test/builtins/Unit/clear_cache_test.c b/test/builtins/Unit/clear_cache_test.c
index 3507fd80b288..3c893018545f 100644
--- a/test/builtins/Unit/clear_cache_test.c
+++ b/test/builtins/Unit/clear_cache_test.c
@@ -38,7 +38,18 @@ int func2()
return 2;
}
-
+void *__attribute__((noinline))
+memcpy_f(void *dst, const void *src, size_t n) {
+// ARM and MIPS nartually align functions, but use the LSB for ISA selection
+// (THUMB, MIPS16/uMIPS respectively). Ensure that the ISA bit is ignored in
+// the memcpy
+#if defined(__arm__) || defined(__mips__)
+ return (void *)((uintptr_t)memcpy(dst, (void *)((uintptr_t)src & ~1), n) |
+ ((uintptr_t)src & 1));
+#else
+ return memcpy(dst, (void *)((uintptr_t)src), n);
+#endif
+}
unsigned char execution_buffer[128];
@@ -59,16 +70,14 @@ int main()
return 1;
// verify you can copy and execute a function
- memcpy(execution_buffer, (void *)(uintptr_t)&func1, 128);
+ pfunc f1 = (pfunc)memcpy_f(execution_buffer, func1, 128);
__clear_cache(execution_buffer, &execution_buffer[128]);
- pfunc f1 = (pfunc)(uintptr_t)execution_buffer;
if ((*f1)() != 1)
return 1;
// verify you can overwrite a function with another
- memcpy(execution_buffer, (void *)(uintptr_t)&func2, 128);
+ pfunc f2 = (pfunc)memcpy_f(execution_buffer, func2, 128);
__clear_cache(execution_buffer, &execution_buffer[128]);
- pfunc f2 = (pfunc)(uintptr_t)execution_buffer;
if ((*f2)() != 2)
return 1;
diff --git a/test/builtins/Unit/enable_execute_stack_test.c b/test/builtins/Unit/enable_execute_stack_test.c
index c0f67b337939..38a142afb24d 100644
--- a/test/builtins/Unit/enable_execute_stack_test.c
+++ b/test/builtins/Unit/enable_execute_stack_test.c
@@ -45,8 +45,18 @@ int func2()
return 2;
}
-
-
+void *__attribute__((noinline))
+memcpy_f(void *dst, const void *src, size_t n) {
+// ARM and MIPS nartually align functions, but use the LSB for ISA selection
+// (THUMB, MIPS16/uMIPS respectively). Ensure that the ISA bit is ignored in
+// the memcpy
+#if defined(__arm__) || defined(__mips__)
+ return (void *)((uintptr_t)memcpy(dst, (void *)((uintptr_t)src & ~1), n) |
+ ((uintptr_t)src & 1));
+#else
+ return memcpy(dst, (void *)((uintptr_t)src), n);
+#endif
+}
int main()
{
@@ -55,16 +65,14 @@ int main()
__enable_execute_stack(execution_buffer);
// verify you can copy and execute a function
- memcpy(execution_buffer, (void *)(uintptr_t)&func1, 128);
+ pfunc f1 = (pfunc)memcpy_f(execution_buffer, func1, 128);
__clear_cache(execution_buffer, &execution_buffer[128]);
- pfunc f1 = (pfunc)(uintptr_t)execution_buffer;
if ((*f1)() != 1)
return 1;
// verify you can overwrite a function with another
- memcpy(execution_buffer, (void *)(uintptr_t)&func2, 128);
+ pfunc f2 = (pfunc)memcpy_f(execution_buffer, func2, 128);
__clear_cache(execution_buffer, &execution_buffer[128]);
- pfunc f2 = (pfunc)(uintptr_t)execution_buffer;
if ((*f2)() != 2)
return 1;
diff --git a/test/lit.common.configured.in b/test/lit.common.configured.in
index beecaa25886a..ceab67d4ad07 100644
--- a/test/lit.common.configured.in
+++ b/test/lit.common.configured.in
@@ -30,7 +30,7 @@ set_default("emulator", "@COMPILER_RT_EMULATOR@")
# apply substitution.
try:
config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
-except KeyError,e:
+except KeyError as e:
key, = e.args
lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key))
diff --git a/test/lsan/TestCases/ignore_object.cc b/test/lsan/TestCases/ignore_object.cc
index 38d76e6798b2..ac69e12a4ba6 100644
--- a/test/lsan/TestCases/ignore_object.cc
+++ b/test/lsan/TestCases/ignore_object.cc
@@ -1,5 +1,5 @@
// Test for __lsan_ignore_object().
-// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=0:verbosity=2"
+// RUN: LSAN_BASE="report_objects=1:use_registers=0:use_stacks=0:use_globals=0:use_tls=0"
// RUN: %clangxx_lsan %s -o %t
// RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t 2>&1 | FileCheck %s
@@ -20,5 +20,4 @@ int main() {
return 0;
}
// CHECK: Test alloc: [[ADDR:.*]].
-// CHECK: ignoring heap object at [[ADDR]]
// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 1337 byte(s) leaked in 1 allocation(s)
diff --git a/test/lsan/TestCases/ignore_object_errors.cc b/test/lsan/TestCases/ignore_object_errors.cc
index 39b9b0288bb3..41603274a306 100644
--- a/test/lsan/TestCases/ignore_object_errors.cc
+++ b/test/lsan/TestCases/ignore_object_errors.cc
@@ -1,5 +1,4 @@
// Test for incorrect use of __lsan_ignore_object().
-// RUN: LSAN_BASE="verbosity=2"
// RUN: %clangxx_lsan %s -o %t
// RUN: LSAN_OPTIONS=$LSAN_BASE %run %t 2>&1 | FileCheck %s
@@ -18,5 +17,4 @@ int main() {
return 0;
}
// CHECK: Test alloc: [[ADDR:.*]].
-// CHECK: heap object at [[ADDR]] is already being ignored
-// CHECK: no heap object found at [[ADDR]]
+// CHECK-NOT: SUMMARY: {{.*}} leaked
diff --git a/test/lsan/TestCases/leak_check_at_exit.cc b/test/lsan/TestCases/leak_check_at_exit.cc
index fe3f70e40005..6f1cd22cf68d 100644
--- a/test/lsan/TestCases/leak_check_at_exit.cc
+++ b/test/lsan/TestCases/leak_check_at_exit.cc
@@ -4,7 +4,7 @@
// RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-do
// RUN: LSAN_OPTIONS=$LSAN_BASE not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-do
// RUN: LSAN_OPTIONS=$LSAN_BASE:"leak_check_at_exit=0" not %run %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-do
-// RUN: LSAN_OPTIONS=%LSAN_BASE:"leak_check_at_exit=0" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-dont
+// RUN: LSAN_OPTIONS=$LSAN_BASE:"leak_check_at_exit=0" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-dont
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/lsan/TestCases/leak_check_before_thread_started.cc b/test/lsan/TestCases/leak_check_before_thread_started.cc
index 891cd699a255..0bd4837f14c0 100644
--- a/test/lsan/TestCases/leak_check_before_thread_started.cc
+++ b/test/lsan/TestCases/leak_check_before_thread_started.cc
@@ -1,8 +1,7 @@
// Regression test for http://llvm.org/bugs/show_bug.cgi?id=21621
// This test relies on timing between threads, so any failures will be flaky.
-// RUN: LSAN_BASE="use_stacks=0:use_registers=0"
// RUN: %clangxx_lsan %s -o %t
-// RUN: %run %t
+// RUN: LSAN_OPTIONS="log_pointers=1:log_threads=1" %run %t
#include <assert.h>
#include <pthread.h>
#include <stdlib.h>
diff --git a/test/lsan/TestCases/suppressions_file.cc b/test/lsan/TestCases/suppressions_file.cc
index 16ad9323461e..d030896d519f 100644
--- a/test/lsan/TestCases/suppressions_file.cc
+++ b/test/lsan/TestCases/suppressions_file.cc
@@ -1,11 +1,11 @@
// RUN: LSAN_BASE="use_registers=0:use_stacks=0"
// RUN: %clangxx_lsan %s -o %t
-// RUN: echo "leak:*LSanTestLeakingFunc*" > %t.supp1
-// RUN: LSAN_OPTIONS=$LSAN_BASE:suppressions=%t.supp1 not %run %t 2>&1 | FileCheck %s
+// RUN: echo "leak:*LSanTestLeakingFunc*" > %t.supp
+// RUN: LSAN_OPTIONS="$LSAN_BASE:suppressions='%t.supp'" not %run %t 2>&1 | FileCheck %s
-// RUN: echo "leak:%t" > %t.supp2
-// RUN: LSAN_OPTIONS=$LSAN_BASE:suppressions="%t.supp2":symbolize=false %run %t
+// RUN: echo "leak:%t" > %t.supp
+// RUN: LSAN_OPTIONS="$LSAN_BASE:suppressions='%t.supp':symbolize=false" %run %t
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/msan/msan_print_shadow.cc b/test/msan/msan_print_shadow.cc
index 0cc1d660be1b..f4894596a0e2 100644
--- a/test/msan/msan_print_shadow.cc
+++ b/test/msan/msan_print_shadow.cc
@@ -99,7 +99,7 @@ int main(void) {
// CHECK-ORIGINS: #1 {{.*}} in main{{.*}}msan_print_shadow.cc:14
// CHECK-ORIGINS: Origin B (origin_id {{.*}}):
-// CHECK-ORIGINS: Uninitialized value was created by a heap allocation
+// CHECK-ORIGINS: Memory was marked as uninitialized
// CHECK-ORIGINS: #0 {{.*}} in __msan_allocated_memory
// CHECK-ORIGINS: #1 {{.*}} in main{{.*}}msan_print_shadow.cc:18
@@ -110,13 +110,13 @@ int main(void) {
// CHECK-ORIGINS: #0 {{.*}} in main{{.*}}msan_print_shadow.cc:12
// CHECK-ORIGINS: Origin D (origin_id {{.*}}):
-// CHECK-ORIGINS: Uninitialized value was created by a heap allocation
+// CHECK-ORIGINS: Memory was marked as uninitialized
// CHECK-ORIGINS: #0 {{.*}} in __msan_allocated_memory
// CHECK-ORIGINS: #1 {{.*}} in main{{.*}}msan_print_shadow.cc:20
// ...
// CHECK-ORIGINS: Origin Z (origin_id {{.*}}):
-// CHECK-ORIGINS: Uninitialized value was created by a heap allocation
+// CHECK-ORIGINS: Memory was marked as uninitialized
// CHECK-ORIGINS: #0 {{.*}} in __msan_allocated_memory
// CHECK-ORIGINS: #1 {{.*}} in main{{.*}}msan_print_shadow.cc:42
diff --git a/test/msan/origin-store-long.cc b/test/msan/origin-store-long.cc
new file mode 100644
index 000000000000..a7c2b7a7d578
--- /dev/null
+++ b/test/msan/origin-store-long.cc
@@ -0,0 +1,21 @@
+// Check that 8-byte store updates origin for the full store range.
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s < %t.out
+
+#include <sanitizer/msan_interface.h>
+
+int main() {
+ uint64_t *volatile p = new uint64_t;
+ uint64_t *volatile q = new uint64_t;
+ *p = *q;
+ char *z = (char *)p;
+ return z[6];
+// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+// CHECK: in main {{.*}}origin-store-long.cc:[[@LINE-2]]
+
+// CHECK: Uninitialized value was created by a heap allocation
+// CHECK: in main {{.*}}origin-store-long.cc:[[@LINE-8]]
+}
+
diff --git a/test/msan/realloc-large-origin.cc b/test/msan/realloc-large-origin.cc
new file mode 100644
index 000000000000..de39394cbb79
--- /dev/null
+++ b/test/msan/realloc-large-origin.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+// This is a regression test: there used to be broken "stored to memory at"
+// stacks with
+// in __msan_memcpy
+// in __msan::MsanReallocate
+// and nothing below that.
+
+#include <stdlib.h>
+int main(int argc, char **argv) {
+ char *p = (char *)malloc(100);
+ p = (char *)realloc(p, 10000);
+ char x = p[50];
+ free(p);
+ return x;
+
+// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+// CHECK: {{#0 0x.* in main .*realloc-large-origin.cc:}}[[@LINE-3]]
+
+// CHECK: Uninitialized value was stored to memory at
+// CHECK: {{#0 0x.* in .*realloc}}
+// CHECK: {{#1 0x.* in main .*realloc-large-origin.cc:}}[[@LINE-10]]
+
+// CHECK: Uninitialized value was created by a heap allocation
+// CHECK: {{#0 0x.* in .*malloc}}
+// CHECK: {{#1 0x.* in main .*realloc-large-origin.cc:}}[[@LINE-15]]
+}
diff --git a/test/msan/realloc-origin.cc b/test/msan/realloc-origin.cc
new file mode 100644
index 000000000000..6707cc9049a4
--- /dev/null
+++ b/test/msan/realloc-origin.cc
@@ -0,0 +1,21 @@
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+// This test relies on realloc from 100 to 101 being done in-place.
+
+#include <stdlib.h>
+int main(int argc, char **argv) {
+ char *p = (char *)malloc(100);
+ p = (char *)realloc(p, 101);
+ char x = p[100];
+ free(p);
+ return x;
+ // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+ // CHECK: {{#0 0x.* in main .*realloc-origin.cc:}}[[@LINE-2]]
+
+ // CHECK: Uninitialized value was created by a heap allocation
+ // CHECK: {{#0 0x.* in .*realloc}}
+ // CHECK: {{#1 0x.* in main .*realloc-origin.cc:}}[[@LINE-9]]
+}
diff --git a/test/msan/select_float_origin.cc b/test/msan/select_float_origin.cc
index ca8f3a83b0ed..75731dc457fb 100644
--- a/test/msan/select_float_origin.cc
+++ b/test/msan/select_float_origin.cc
@@ -17,7 +17,7 @@ int main() {
__msan_allocated_memory(&y, sizeof(y));
float z = b ? x : y;
if (z > 0) printf(".\n");
- // CHECK: Uninitialized value was created by a heap allocation
+ // CHECK: Memory was marked as uninitialized
// CHECK: {{#0 0x.* in .*__msan_allocated_memory}}
// CHECK: {{#1 0x.* in main .*select_float_origin.cc:}}[[@LINE-6]]
return 0;
diff --git a/test/msan/use-after-free.cc b/test/msan/use-after-free.cc
index 5b408c536495..869bad98e455 100644
--- a/test/msan/use-after-free.cc
+++ b/test/msan/use-after-free.cc
@@ -27,7 +27,7 @@ int main(int argc, char **argv) {
// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
// CHECK: {{#0 0x.* in main .*use-after-free.cc:}}[[@LINE-3]]
- // CHECK-ORIGINS: Uninitialized value was created by a heap allocation
+ // CHECK-ORIGINS: Uninitialized value was created by a heap deallocation
// CHECK-ORIGINS: {{#0 0x.* in .*free}}
// CHECK-ORIGINS: {{#1 0x.* in main .*use-after-free.cc:}}[[@LINE-9]]
return 0;
diff --git a/test/profile/instrprof-basic.c b/test/profile/instrprof-basic.c
index fd3516cfad03..995525bf9553 100644
--- a/test/profile/instrprof-basic.c
+++ b/test/profile/instrprof-basic.c
@@ -27,5 +27,5 @@ int main(int argc, const char *argv[]) {
return 1;
}
-// CHECK: ![[PD1]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
-// CHECK: ![[PD2]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
+// CHECK: ![[PD2]] = !{!"branch_weights", i32 2, i32 1}
diff --git a/test/profile/instrprof-reset-counters.c b/test/profile/instrprof-reset-counters.c
index c92732baf45d..e8892366bcfe 100644
--- a/test/profile/instrprof-reset-counters.c
+++ b/test/profile/instrprof-reset-counters.c
@@ -16,4 +16,4 @@ void foo(int N) {
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[FOO:[0-9]+]]
if (N) {}
}
-// CHECK: ![[FOO]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// CHECK: ![[FOO]] = !{!"branch_weights", i32 2, i32 1}
diff --git a/test/profile/instrprof-set-filename.c b/test/profile/instrprof-set-filename.c
index 045821899e44..51aa4234fea1 100644
--- a/test/profile/instrprof-set-filename.c
+++ b/test/profile/instrprof-set-filename.c
@@ -11,4 +11,4 @@ int main(int argc, const char *argv[]) {
__llvm_profile_set_filename(argv[1]);
return 0;
}
-// CHECK: ![[PD1]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-without-libc.c b/test/profile/instrprof-without-libc.c
index 60ca9496c611..fc6c9b25b3ba 100644
--- a/test/profile/instrprof-without-libc.c
+++ b/test/profile/instrprof-without-libc.c
@@ -46,7 +46,7 @@ int main(int argc, const char *argv[]) {
return fclose(File);
#endif
}
-// CHECK: ![[PD1]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
// CHECK-SYMBOLS-NOT: ___cxx_global_var_init
// CHECK-SYMBOLS-NOT: ___llvm_profile_register_write_file_atexit
diff --git a/test/profile/instrprof-write-file-atexit-explicitly.c b/test/profile/instrprof-write-file-atexit-explicitly.c
index ba229b9144fa..18c365af5003 100644
--- a/test/profile/instrprof-write-file-atexit-explicitly.c
+++ b/test/profile/instrprof-write-file-atexit-explicitly.c
@@ -14,4 +14,4 @@ int main(int argc, const char *argv[]) {
__llvm_profile_set_filename(argv[1]);
return 0;
}
-// CHECK: ![[PD1]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-write-file-only.c b/test/profile/instrprof-write-file-only.c
index 0dd61de39f1a..4abbdea7c674 100644
--- a/test/profile/instrprof-write-file-only.c
+++ b/test/profile/instrprof-write-file-only.c
@@ -32,4 +32,4 @@ int foo(int X) {
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{[^,]+$}}
return X <= 0 ? -X : X;
}
-// CHECK: ![[PD1]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-write-file.c b/test/profile/instrprof-write-file.c
index 12967cb94a55..af008ed9439e 100644
--- a/test/profile/instrprof-write-file.c
+++ b/test/profile/instrprof-write-file.c
@@ -30,5 +30,5 @@ int foo(int X) {
// CHECK2: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD2:[0-9]+]]
return X <= 0 ? -X : X;
}
-// CHECK: ![[PD1]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
-// CHECK2: ![[PD2]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
+// CHECK2: ![[PD2]] = !{!"branch_weights", i32 2, i32 1}
diff --git a/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc b/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
new file mode 100644
index 000000000000..225c44e25cd0
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
@@ -0,0 +1,37 @@
+// Check hard_rss_limit_mb. Not all sanitizers implement it yet.
+// RUN: %clangxx -O2 %s -o %t
+//
+// Run with limit should fail:
+// RUN: %tool_options=hard_rss_limit_mb=100 not %run %t 2>&1 | FileCheck %s
+// This run uses getrusage:
+// RUN: %tool_options=hard_rss_limit_mb=100:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s
+//
+// Run w/o limit or with a large enough limit should pass:
+// RUN: %tool_options=hard_rss_limit_mb=1000 %run %t
+// RUN: %run %t
+//
+// FIXME: make it work for other sanitizers.
+// XFAIL: lsan
+// XFAIL: tsan
+// XFAIL: msan
+
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+const int kNumAllocs = 200 * 1000;
+const int kAllocSize = 1000;
+volatile char *sink[kNumAllocs];
+
+int main(int argc, char **argv) {
+ for (int i = 0; i < kNumAllocs; i++) {
+ if ((i % 1000) == 0) {
+ fprintf(stderr, "[%d]\n", i);
+ }
+ char *x = new char[kAllocSize];
+ memset(x, 0, kAllocSize);
+ sink[i] = x;
+ }
+ sleep(1); // Make sure the background thread has time to kill the process.
+// CHECK: hard rss limit exhausted
+}
diff --git a/test/sanitizer_common/TestCases/Linux/sanitizer_set_death_callback_test.cc b/test/sanitizer_common/TestCases/Linux/sanitizer_set_death_callback_test.cc
new file mode 100644
index 000000000000..ee3d59c72172
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/sanitizer_set_death_callback_test.cc
@@ -0,0 +1,49 @@
+// RUN: %clangxx -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// Check __sanitizer_set_death_callback. Not all sanitizers implement it yet.
+// XFAIL: lsan
+// XFAIL: tsan
+
+#include <sanitizer/common_interface_defs.h>
+#include <stdio.h>
+#include <pthread.h>
+
+volatile char *zero = 0;
+
+void Death() {
+ fprintf(stderr, "DEATH CALLBACK EXECUTED\n");
+}
+// CHECK: DEATH CALLBACK EXECUTED
+
+int global[10];
+volatile char *sink;
+
+void *Thread(void *x) {
+ global[0]++;
+ return x;
+}
+
+__attribute__((noinline))
+void MaybeInit(int *uninitialized) {
+ if (zero)
+ *uninitialized = 1;
+}
+
+__attribute__((noinline))
+void Leak() {
+ sink = new char[100]; // trigger lsan report.
+}
+
+int main(int argc, char **argv) {
+ int uninitialized;
+ __sanitizer_set_death_callback(Death);
+ MaybeInit(&uninitialized);
+ if (uninitialized) // trigger msan report.
+ global[0] = 77;
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ global[0]++; // trigger tsan report.
+ pthread_join(t, 0);
+ global[argc + 10]++; // trigger asan report.
+ Leak();
+ sink = 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/sched_getparam.cc b/test/sanitizer_common/TestCases/Linux/sched_getparam.cc
new file mode 100644
index 000000000000..390c656fe209
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/sched_getparam.cc
@@ -0,0 +1,13 @@
+// RUN: %clangxx -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <sched.h>
+#include <stdio.h>
+
+int main(void) {
+ struct sched_param param;
+ int res = sched_getparam(0, &param);
+ assert(res == 0);
+ if (param.sched_priority == 42) printf(".\n");
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc b/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc
new file mode 100644
index 000000000000..145cc5d05769
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc
@@ -0,0 +1,66 @@
+// Check soft_rss_limit_mb. Not all sanitizers implement it yet.
+// RUN: %clangxx -O2 %s -o %t
+//
+// Run with limit should fail:
+// RUN: %tool_options=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_1
+// RUN: %tool_options=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
+
+// This run uses getrusage. We can only test getrusage when allocator_may_return_null=0
+// because getrusage gives us max-rss, not current-rss.
+// RUN: %tool_options=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
+
+// FIXME: make it work for other sanitizers.
+// XFAIL: lsan
+// XFAIL: tsan
+// XFAIL: msan
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+static const int kMaxNumAllocs = 1 << 9;
+static const int kAllocSize = 1 << 20; // Large enough to go via mmap.
+
+static char *allocs[kMaxNumAllocs];
+
+int main() {
+ int num_allocs = kMaxNumAllocs / 4;
+ for (int i = 0; i < 3; i++, num_allocs *= 2) {
+ fprintf(stderr, "[%d] allocating %d times\n", i, num_allocs);
+ int zero_results = 0;
+ for (int j = 0; j < num_allocs; j++) {
+ if ((j % (num_allocs / 8)) == 0) {
+ usleep(100000);
+ fprintf(stderr, " [%d]\n", j);
+ }
+ allocs[j] = (char*)malloc(kAllocSize);
+ if (allocs[j])
+ memset(allocs[j], -1, kAllocSize);
+ else
+ zero_results++;
+ }
+ if (zero_results)
+ fprintf(stderr, "Some of the malloc calls returned null: %d\n",
+ zero_results);
+ if (zero_results != num_allocs)
+ fprintf(stderr, "Some of the malloc calls returned non-null: %d\n",
+ num_allocs - zero_results);
+ for (int j = 0; j < num_allocs; j++) {
+ free(allocs[j]);
+ }
+ }
+}
+
+// CHECK_MAY_RETURN_1: allocating 128 times
+// CHECK_MAY_RETURN_1: Some of the malloc calls returned non-null: 128
+// CHECK_MAY_RETURN_1: allocating 256 times
+// CHECK_MAY_RETURN_1: Some of the malloc calls returned null:
+// CHECK_MAY_RETURN_1: Some of the malloc calls returned non-null:
+// CHECK_MAY_RETURN_1: allocating 512 times
+// CHECK_MAY_RETURN_1: Some of the malloc calls returned null:
+// CHECK_MAY_RETURN_1: Some of the malloc calls returned non-null:
+
+// CHECK_MAY_RETURN_0: allocating 128 times
+// CHECK_MAY_RETURN_0: Some of the malloc calls returned non-null: 128
+// CHECK_MAY_RETURN_0: allocating 256 times
+// CHECK_MAY_RETURN_0: allocator is terminating the process instead of returning
diff --git a/test/sanitizer_common/TestCases/options-help.cc b/test/sanitizer_common/TestCases/options-help.cc
new file mode 100644
index 000000000000..eaa04a494be4
--- /dev/null
+++ b/test/sanitizer_common/TestCases/options-help.cc
@@ -0,0 +1,8 @@
+// RUN: %clangxx -O0 %s -o %t
+// RUN: %tool_options=help=1 %run %t 2>&1 | FileCheck %s
+
+int main() {
+}
+
+// CHECK: Available flags for {{.*}}Sanitizer:
+// CHECK: handle_segv
diff --git a/test/sanitizer_common/TestCases/options-include.cc b/test/sanitizer_common/TestCases/options-include.cc
new file mode 100644
index 000000000000..ae8995164853
--- /dev/null
+++ b/test/sanitizer_common/TestCases/options-include.cc
@@ -0,0 +1,21 @@
+// RUN: %clangxx -O0 %s -o %t
+// RUN: echo -e "symbolize=1\ninclude='%t.options2.txt'" >%t.options1.txt
+// RUN: echo -e "help=1\n" >%t.options2.txt
+// RUN: cat %t.options1.txt
+// RUN: cat %t.options2.txt
+// RUN: %tool_options="help=0:include='%t.options1.txt'" %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-VERBOSITY1 <%t.out
+// RUN: %tool_options="include='%t.options1.txt',help=0" %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-VERBOSITY0 <%t.out
+// RUN: %tool_options="include='%t.options-not-found.txt',help=1" not %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-NOT-FOUND < %t.out
+
+#include <stdio.h>
+
+int main() {
+ fprintf(stderr, "done\n");
+}
+
+// CHECK-VERBOSITY1: Available flags for
+// CHECK-VERBOSITY0-NOT: Available flags for
+// CHECK-NOT-FOUND: Failed to read options from
diff --git a/test/sanitizer_common/TestCases/options-invalid.cc b/test/sanitizer_common/TestCases/options-invalid.cc
new file mode 100644
index 000000000000..3c261405c992
--- /dev/null
+++ b/test/sanitizer_common/TestCases/options-invalid.cc
@@ -0,0 +1,15 @@
+// RUN: %clangxx -O0 %s -o %t
+// RUN: %tool_options=invalid_option_name=10,verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-V1
+// RUN: %tool_options=invalid_option_name=10 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-V0
+
+#include <stdio.h>
+
+int main() {
+ fprintf(stderr, "done\n");
+}
+
+// CHECK-V1: WARNING: found 1 unrecognized
+// CHECK-V1: invalid_option_name
+// CHECK-V0-NOT: WARNING: found 1 unrecognized
+// CHECK-V0-NOT: invalid_option_name
+// CHECK: done
diff --git a/test/tsan/CMakeLists.txt b/test/tsan/CMakeLists.txt
index 29c0821b3c5a..5a9542fd76fc 100644
--- a/test/tsan/CMakeLists.txt
+++ b/test/tsan/CMakeLists.txt
@@ -1,4 +1,5 @@
set(TSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+list(APPEND TSAN_TEST_DEPS GotsanRuntimeCheck)
if(NOT COMPILER_RT_STANDALONE_BUILD)
list(APPEND TSAN_TEST_DEPS tsan)
endif()
diff --git a/test/tsan/aligned_vs_unaligned_race.cc b/test/tsan/aligned_vs_unaligned_race.cc
index f82542ed2b85..5c1189f34a4b 100644
--- a/test/tsan/aligned_vs_unaligned_race.cc
+++ b/test/tsan/aligned_vs_unaligned_race.cc
@@ -1,34 +1,35 @@
-// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
// Race between an aligned access and an unaligned access, which
// touches the same memory region.
-// This is a real race which is not detected by tsan.
-// https://code.google.com/p/thread-sanitizer/issues/detail?id=17
-#include <pthread.h>
-#include <stdio.h>
+#include "test.h"
#include <stdint.h>
uint64_t Global[2];
void *Thread1(void *x) {
Global[1]++;
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
+ barrier_wait(&barrier);
char *p1 = reinterpret_cast<char *>(&Global[0]);
- uint64_t *p4 = reinterpret_cast<uint64_t *>(p1 + 1);
- (*p4)++;
+ struct __attribute__((packed, aligned(1))) u_uint64_t { uint64_t val; };
+ u_uint64_t *p4 = reinterpret_cast<u_uint64_t *>(p1 + 1);
+ (*p4).val++;
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
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("Pass\n");
- // CHECK-NOT: ThreadSanitizer: data race
+ // CHECK: ThreadSanitizer: data race
// CHECK: Pass
return 0;
}
diff --git a/test/tsan/annotate_happens_before.cc b/test/tsan/annotate_happens_before.cc
new file mode 100644
index 000000000000..011661699a7a
--- /dev/null
+++ b/test/tsan/annotate_happens_before.cc
@@ -0,0 +1,57 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include "test.h"
+
+/*
+Annotations usage example.
+
+Tsan does not see synchronization in barrier_wait.
+ANNOTATE_HAPPENS_BEFORE/AFTER communicate the synchronization to tsan
+and prevent the race report.
+
+If the compiler does not support __has_feature macro, then you can build with
+CFLAGS="-fsanitize=thread -DTHREAD_SANITIZER" and then use
+#ifdef THREAD_SANITIZER to enabled annotations.
+*/
+
+#if defined(__has_feature) && __has_feature(thread_sanitizer)
+# define ANNOTATE_HAPPENS_BEFORE(addr) \
+ AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr))
+# define ANNOTATE_HAPPENS_AFTER(addr) \
+ AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr))
+extern "C" void AnnotateHappensBefore(const char *f, int l, void *addr);
+extern "C" void AnnotateHappensAfter(const char *f, int l, void *addr);
+#else
+# define ANNOTATE_HAPPENS_BEFORE(addr)
+# define ANNOTATE_HAPPENS_AFTER(addr)
+#endif
+
+int Global;
+
+void *Thread1(void *x) {
+ barrier_wait(&barrier);
+ ANNOTATE_HAPPENS_AFTER(&barrier);
+ Global++;
+ return NULL;
+}
+
+void *Thread2(void *x) {
+ Global--;
+ ANNOTATE_HAPPENS_BEFORE(&barrier);
+ barrier_wait(&barrier);
+ return NULL;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ 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/test/tsan/atomic_free.cc b/test/tsan/atomic_free.cc
index 1dcf887c41d5..a0d8e426b49f 100644
--- a/test/tsan/atomic_free.cc
+++ b/test/tsan/atomic_free.cc
@@ -1,17 +1,18 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
void *Thread(void *a) {
__atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST);
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
int *a = new int(0);
pthread_t t;
pthread_create(&t, 0, Thread, a);
- sleep(1);
+ barrier_wait(&barrier);
delete a;
pthread_join(t, 0);
}
diff --git a/test/tsan/atomic_free2.cc b/test/tsan/atomic_free2.cc
index c50be6bba940..4a9f268a4008 100644
--- a/test/tsan/atomic_free2.cc
+++ b/test/tsan/atomic_free2.cc
@@ -1,18 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
void *Thread(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
__atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
int *a = new int(0);
pthread_t t;
pthread_create(&t, 0, Thread, a);
delete a;
+ barrier_wait(&barrier);
pthread_join(t, 0);
}
diff --git a/test/tsan/atomic_norace.cc b/test/tsan/atomic_norace.cc
index d9ccda58883c..625109b1fe63 100644
--- a/test/tsan/atomic_norace.cc
+++ b/test/tsan/atomic_norace.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
const int kTestCount = 4;
typedef long long T;
@@ -36,7 +34,8 @@ void *Thread(void *p) {
for (int i = 0; i < kTestCount; i++) {
Test(i, &atomics[i], false);
}
- sleep(2);
+ barrier_wait(&barrier);
+ barrier_wait(&barrier);
for (int i = 0; i < kTestCount; i++) {
fprintf(stderr, "Test %d reverse\n", i);
Test(i, &atomics[kTestCount + i], false);
@@ -45,9 +44,10 @@ void *Thread(void *p) {
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
- sleep(1);
+ barrier_wait(&barrier);
for (int i = 0; i < kTestCount; i++) {
fprintf(stderr, "Test %d\n", i);
Test(i, &atomics[i], true);
@@ -55,6 +55,7 @@ int main() {
for (int i = 0; i < kTestCount; i++) {
Test(i, &atomics[kTestCount + i], true);
}
+ barrier_wait(&barrier);
pthread_join(t, 0);
}
diff --git a/test/tsan/atomic_race.cc b/test/tsan/atomic_race.cc
index 9cee8ed8272f..5a0317c4acfa 100644
--- a/test/tsan/atomic_race.cc
+++ b/test/tsan/atomic_race.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
+#include "test.h"
const int kTestCount = 4;
typedef long long T;
@@ -36,7 +34,8 @@ void *Thread(void *p) {
for (int i = 0; i < kTestCount; i++) {
Test(i, &atomics[i], false);
}
- sleep(4);
+ barrier_wait(&barrier);
+ barrier_wait(&barrier);
for (int i = 0; i < kTestCount; i++) {
fprintf(stderr, "Test %d reverse\n", i);
Test(i, &atomics[kTestCount + i], false);
@@ -45,9 +44,10 @@ void *Thread(void *p) {
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
- sleep(1);
+ barrier_wait(&barrier);
for (int i = 0; i < kTestCount; i++) {
fprintf(stderr, "Test %d\n", i);
Test(i, &atomics[i], true);
@@ -55,6 +55,7 @@ int main() {
for (int i = 0; i < kTestCount; i++) {
Test(i, &atomics[kTestCount + i], true);
}
+ barrier_wait(&barrier);
pthread_join(t, 0);
}
diff --git a/test/tsan/atomic_stack.cc b/test/tsan/atomic_stack.cc
index 7e3176f8e784..979eaea8b699 100644
--- a/test/tsan/atomic_stack.cc
+++ b/test/tsan/atomic_stack.cc
@@ -1,21 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
int Global;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
__atomic_fetch_add(&Global, 1, __ATOMIC_RELAXED);
return NULL;
}
void *Thread2(void *x) {
Global++;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/benign_race.cc b/test/tsan/benign_race.cc
index b6cba19aa96e..2f72fe1860d0 100644
--- a/test/tsan/benign_race.cc
+++ b/test/tsan/benign_race.cc
@@ -1,7 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
int WTFGlobal;
@@ -18,10 +16,12 @@ void WTFAnnotateBenignRaceSized(const char *f, int l,
void *Thread(void *x) {
Global = 42;
WTFGlobal = 142;
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
AnnotateBenignRaceSized(__FILE__, __LINE__,
&Global, sizeof(Global), "Race on Global");
WTFAnnotateBenignRaceSized(__FILE__, __LINE__,
@@ -29,7 +29,7 @@ int main() {
"Race on WTFGlobal");
pthread_t t;
pthread_create(&t, 0, Thread, 0);
- sleep(1);
+ barrier_wait(&barrier);
Global = 43;
WTFGlobal = 143;
pthread_join(t, 0);
diff --git a/test/tsan/blacklist2.cc b/test/tsan/blacklist2.cc
index 1092561e55bb..629b58821bfe 100644
--- a/test/tsan/blacklist2.cc
+++ b/test/tsan/blacklist2.cc
@@ -5,14 +5,12 @@
// RUN: %clangxx_tsan -O1 %s -fsanitize-blacklist=%t.blacklist -o %t
// RUN: %deflake %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
// CHECK: ThreadSanitizer: data race
// CHECK: Write of size 4
// CHECK: #0 Thread1{{.*}}blacklist2.cc:[[@LINE+1]]
@@ -35,10 +33,12 @@ void *Blacklisted_Thread2(void *x) {
Global--;
// CHECK: #2 Blacklisted_Thread2{{.*}}blacklist2.cc:[[@LINE+1]]
CallTouchGlobal();
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Blacklisted_Thread2, NULL);
diff --git a/test/tsan/cond_cancel.c b/test/tsan/cond_cancel.c
index 397cad4b1838..e744570b12fc 100644
--- a/test/tsan/cond_cancel.c
+++ b/test/tsan/cond_cancel.c
@@ -2,10 +2,7 @@
// CHECK-NOT: WARNING
// CHECK: OK
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
pthread_mutex_t m;
pthread_cond_t c;
@@ -14,6 +11,7 @@ int x;
void *thr1(void *p) {
pthread_mutex_lock(&m);
pthread_cleanup_push((void(*)(void *arg))pthread_mutex_unlock, &m);
+ barrier_wait(&barrier);
while (x == 0)
pthread_cond_wait(&c, &m);
pthread_cleanup_pop(1);
@@ -21,12 +19,15 @@ void *thr1(void *p) {
}
int main() {
+ barrier_init(&barrier, 2);
+
pthread_t th;
pthread_mutex_init(&m, 0);
pthread_cond_init(&c, 0);
pthread_create(&th, 0, thr1, 0);
+ barrier_wait(&barrier);
sleep(1); // let it block on cond var
pthread_cancel(th);
diff --git a/test/tsan/cond_race.cc b/test/tsan/cond_race.cc
index fa42fafca4d2..52654f16e85c 100644
--- a/test/tsan/cond_race.cc
+++ b/test/tsan/cond_race.cc
@@ -3,10 +3,7 @@
// CHECK: ThreadSanitizer: data race
// CHECK: pthread_cond_signal
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
struct Ctx {
pthread_mutex_t m;
@@ -20,10 +17,12 @@ void *thr(void *p) {
c->done = true;
pthread_mutex_unlock(&c->m);
pthread_cond_signal(&c->c);
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
Ctx *c = new Ctx();
pthread_mutex_init(&c->m, 0);
pthread_cond_init(&c->c, 0);
@@ -33,8 +32,8 @@ int main() {
while (!c->done)
pthread_cond_wait(&c->c, &c->m);
pthread_mutex_unlock(&c->m);
- // w/o this sleep, it can be reported as use-after-free
- sleep(1);
+ // otherwise it can be reported as use-after-free
+ barrier_wait(&barrier);
delete c;
pthread_join(th, 0);
}
diff --git a/test/tsan/deadlock_detector_stress_test.cc b/test/tsan/deadlock_detector_stress_test.cc
index 53624782e07b..e02a9123f5af 100644
--- a/test/tsan/deadlock_detector_stress_test.cc
+++ b/test/tsan/deadlock_detector_stress_test.cc
@@ -7,12 +7,9 @@
// RUN: TSAN_OPTIONS=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RD
// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRecursiveMutex
// RUN: TSAN_OPTIONS=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-REC
-#include <pthread.h>
+#include "test.h"
#undef NDEBUG
#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
#include <new>
#ifndef LockType
@@ -224,7 +221,7 @@ class LockTest {
fprintf(stderr, "Starting Test5\n");
// CHECK: Starting Test5
Init(5);
- RunThreads(&LockTest::Lock_0_1, &LockTest::Lock_1_0);
+ RunThreads(&LockTest::Lock_0_1<true>, &LockTest::Lock_1_0<true>);
// CHECK: WARNING: ThreadSanitizer: lock-order-inversion
// CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ({{.*}}) => [[M2:M[0-9]+]] ({{.*}}) => [[M1]]
// CHECK: Mutex [[M2]] acquired here while holding mutex [[M1]] in thread [[T1:T[0-9]+]]
@@ -503,8 +500,21 @@ class LockTest {
private:
void Lock2(size_t l1, size_t l2) { L(l1); L(l2); U(l2); U(l1); }
- void Lock_0_1() { Lock2(0, 1); }
- void Lock_1_0() { sleep(1); Lock2(1, 0); }
+
+ template<bool wait = false>
+ void Lock_0_1() {
+ Lock2(0, 1);
+ if (wait)
+ barrier_wait(&barrier);
+ }
+
+ template<bool wait = false>
+ void Lock_1_0() {
+ if (wait)
+ barrier_wait(&barrier);
+ Lock2(1, 0);
+ }
+
void Lock1_Loop(size_t i, size_t n_iter) {
for (size_t it = 0; it < n_iter; it++) {
// if ((it & (it - 1)) == 0) fprintf(stderr, "%zd", i);
@@ -569,6 +579,7 @@ class LockTest {
};
int main(int argc, char **argv) {
+ barrier_init(&barrier, 2);
if (argc > 1)
test_number = atoi(argv[1]);
if (argc > 2)
diff --git a/test/tsan/deep_stack1.cc b/test/tsan/deep_stack1.cc
index 1d00a0e856d5..39185efee7a9 100644
--- a/test/tsan/deep_stack1.cc
+++ b/test/tsan/deep_stack1.cc
@@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t -DORDER1 && %deflake %run %t | FileCheck %s
// RUN: %clangxx_tsan -O1 %s -o %t -DORDER2 && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
volatile int X;
volatile int N;
@@ -17,13 +15,17 @@ static void foo() {
void *Thread(void *p) {
#ifdef ORDER1
- sleep(1);
+ barrier_wait(&barrier);
#endif
F();
+#ifdef ORDER2
+ barrier_wait(&barrier);
+#endif
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
N = 50000;
F = foo;
pthread_t t;
@@ -32,9 +34,13 @@ int main() {
pthread_attr_setstacksize(&a, N * 256 + (1 << 20));
pthread_create(&t, &a, Thread, 0);
#ifdef ORDER2
- sleep(1);
+ barrier_wait(&barrier);
#endif
X = 43;
+#ifdef ORDER1
+ barrier_wait(&barrier);
+#endif
+
pthread_join(t, 0);
}
diff --git a/test/tsan/fd_close_norace.cc b/test/tsan/fd_close_norace.cc
index 7238d64b432b..1b52c20f990c 100644
--- a/test/tsan/fd_close_norace.cc
+++ b/test/tsan/fd_close_norace.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -9,17 +7,19 @@
void *Thread1(void *x) {
int f = open("/dev/random", O_RDONLY);
close(f);
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
int f = open("/dev/random", O_RDONLY);
close(f);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/fd_location.cc b/test/tsan/fd_location.cc
index 535329e06409..1861c89cba9b 100644
--- a/test/tsan/fd_location.cc
+++ b/test/tsan/fd_location.cc
@@ -1,23 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int fds[2];
void *Thread1(void *x) {
write(fds[1], "a", 1);
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
close(fds[0]);
close(fds[1]);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pipe(fds);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
diff --git a/test/tsan/fd_pipe_race.cc b/test/tsan/fd_pipe_race.cc
index 88c4ed4aa398..b94893b93691 100644
--- a/test/tsan/fd_pipe_race.cc
+++ b/test/tsan/fd_pipe_race.cc
@@ -1,23 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int fds[2];
void *Thread1(void *x) {
write(fds[1], "a", 1);
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
close(fds[0]);
close(fds[1]);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pipe(fds);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
diff --git a/test/tsan/fd_stdout_race.cc b/test/tsan/fd_stdout_race.cc
index d6a2c7c796f1..fcf8c21300c6 100644
--- a/test/tsan/fd_stdout_race.cc
+++ b/test/tsan/fd_stdout_race.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -9,7 +7,7 @@
int X;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
int f = open("/dev/random", O_RDONLY);
char buf;
read(f, &buf, 1);
@@ -21,10 +19,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
X = 43;
write(STDOUT_FILENO, "a", 1);
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/fork_deadlock.cc b/test/tsan/fork_deadlock.cc
index cc5b12214cf9..9418800bd336 100644
--- a/test/tsan/fork_deadlock.cc
+++ b/test/tsan/fork_deadlock.cc
@@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && TSAN_OPTIONS="atexit_sleep_ms=50" %run %t 2>&1 | FileCheck %s
-#include <stdlib.h>
-#include <stdio.h>
+#include "test.h"
#include <errno.h>
-#include <pthread.h>
-#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -16,13 +13,14 @@ static void *incrementer(void *p) {
}
static void *watchdog(void *p) {
- sleep(100);
+ sleep(100); // is not intended to exit
fprintf(stderr, "timed out after 100 seconds\n");
exit(1);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t th1, th2;
pthread_create(&th1, 0, incrementer, 0);
pthread_create(&th2, 0, watchdog, 0);
diff --git a/test/tsan/fork_multithreaded.cc b/test/tsan/fork_multithreaded.cc
index 5176a14d6a65..3ddb417c7cb5 100644
--- a/test/tsan/fork_multithreaded.cc
+++ b/test/tsan/fork_multithreaded.cc
@@ -1,19 +1,21 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-DIE
// RUN: %clangxx_tsan -O1 %s -o %t && TSAN_OPTIONS="die_after_fork=0" %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-NODIE
-#include <stdlib.h>
-#include <stdio.h>
+#include "test.h"
#include <errno.h>
-#include <pthread.h>
-#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
static void *sleeper(void *p) {
- sleep(10);
+ sleep(10); // not intended to exit during test
+ return 0;
+}
+
+static void *nop(void *p) {
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t th;
pthread_create(&th, 0, sleeper, 0);
switch (fork()) {
@@ -23,7 +25,7 @@ int main() {
case 0: // child
{
pthread_t th2;
- pthread_create(&th2, 0, sleeper, 0);
+ pthread_create(&th2, 0, nop, 0);
exit(0);
break;
}
diff --git a/test/tsan/free_race.c b/test/tsan/free_race.c
index 663d7bcf2eb9..63cee8c4adc5 100644
--- a/test/tsan/free_race.c
+++ b/test/tsan/free_race.c
@@ -1,12 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t
// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOZUPP
-// RUN: TSAN_OPTIONS="suppressions=%s.supp print_suppressions=1" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUPP
+// RUN: TSAN_OPTIONS="suppressions='%s.supp' print_suppressions=1" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUPP
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
int *mem;
pthread_mutex_t mtx;
@@ -15,11 +11,12 @@ void *Thread1(void *x) {
pthread_mutex_lock(&mtx);
free(mem);
pthread_mutex_unlock(&mtx);
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
pthread_mutex_lock(&mtx);
mem[0] = 42;
pthread_mutex_unlock(&mtx);
@@ -27,6 +24,7 @@ void *Thread2(void *x) {
}
int main() {
+ barrier_init(&barrier, 2);
mem = (int*)malloc(100);
pthread_mutex_init(&mtx, 0);
pthread_t t;
diff --git a/test/tsan/global_race.cc b/test/tsan/global_race.cc
index e12bb1d220f8..d70bee4a556b 100644
--- a/test/tsan/global_race.cc
+++ b/test/tsan/global_race.cc
@@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %T/global_race.cc.exe && %deflake %run %T/global_race.cc.exe | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
int GlobalData[10];
void *Thread(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
GlobalData[2] = 42;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
// On FreeBSD, the %p conversion specifier works as 0x%x and thus does not
// match to the format used in the diagnotic message.
fprintf(stderr, "addr=0x%012lx\n", (unsigned long) GlobalData);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
GlobalData[2] = 43;
+ barrier_wait(&barrier);
pthread_join(t, 0);
}
diff --git a/test/tsan/global_race2.cc b/test/tsan/global_race2.cc
index ac994cc0f4c4..6631008d85a5 100644
--- a/test/tsan/global_race2.cc
+++ b/test/tsan/global_race2.cc
@@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
int x;
void *Thread(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
x = 1;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
// On FreeBSD, the %p conversion specifier works as 0x%x and thus does not
// match to the format used in the diagnotic message.
fprintf(stderr, "addr2=0x%012lx\n", (unsigned long) &x);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
x = 0;
+ barrier_wait(&barrier);
pthread_join(t, 0);
}
diff --git a/test/tsan/global_race3.cc b/test/tsan/global_race3.cc
index a3222bb3d8cb..e7e9a7fef028 100644
--- a/test/tsan/global_race3.cc
+++ b/test/tsan/global_race3.cc
@@ -1,8 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
namespace XXX {
struct YYY {
@@ -12,18 +9,20 @@ namespace XXX {
}
void *Thread(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
XXX::YYY::ZZZ[0] = 1;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
// On FreeBSD, the %p conversion specifier works as 0x%x and thus does not
// match to the format used in the diagnotic message.
fprintf(stderr, "addr3=0x%012lx\n", (unsigned long) XXX::YYY::ZZZ);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
XXX::YYY::ZZZ[0] = 0;
+ barrier_wait(&barrier);
pthread_join(t, 0);
}
diff --git a/test/tsan/halt_on_error.cc b/test/tsan/halt_on_error.cc
index 3c55c60a457e..e55454b57c1d 100644
--- a/test/tsan/halt_on_error.cc
+++ b/test/tsan/halt_on_error.cc
@@ -1,21 +1,21 @@
// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS halt_on_error=1" %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int X;
void *Thread(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
X = 42;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
fprintf(stderr, "BEFORE\n");
pthread_t t;
pthread_create(&t, 0, Thread, 0);
X = 43;
+ barrier_wait(&barrier);
pthread_join(t, 0);
fprintf(stderr, "AFTER\n");
return 0;
diff --git a/test/tsan/ignore_free.cc b/test/tsan/ignore_free.cc
index 1df6dce2f5e0..bb6c6ee14364 100644
--- a/test/tsan/ignore_free.cc
+++ b/test/tsan/ignore_free.cc
@@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
extern "C" {
void AnnotateIgnoreReadsBegin(const char *f, int l);
@@ -13,14 +10,16 @@ void AnnotateIgnoreWritesEnd(const char *f, int l);
void *Thread(void *p) {
*(int*)p = 42;
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
int *p = new int(0);
pthread_t t;
pthread_create(&t, 0, Thread, p);
- sleep(1);
+ barrier_wait(&barrier);
AnnotateIgnoreReadsBegin(__FILE__, __LINE__);
AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
free(p);
diff --git a/test/tsan/ignore_lib0.cc b/test/tsan/ignore_lib0.cc
index fe1a35558015..63c9340e99ac 100644
--- a/test/tsan/ignore_lib0.cc
+++ b/test/tsan/ignore_lib0.cc
@@ -3,7 +3,7 @@
// RUN: echo running w/o suppressions:
// RUN: LD_LIBRARY_PATH=%T${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOSUPP
// RUN: echo running with suppressions:
-// RUN: LD_LIBRARY_PATH=%T${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
+// RUN: LD_LIBRARY_PATH=%T${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
// Tests that interceptors coming from a library specified in called_from_lib
// suppression are ignored.
diff --git a/test/tsan/ignore_lib1.cc b/test/tsan/ignore_lib1.cc
index 30a9994b94f5..ef1f973795ed 100644
--- a/test/tsan/ignore_lib1.cc
+++ b/test/tsan/ignore_lib1.cc
@@ -3,7 +3,7 @@
// RUN: echo running w/o suppressions:
// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOSUPP
// RUN: echo running with suppressions:
-// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
+// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %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.
diff --git a/test/tsan/ignore_lib2.cc b/test/tsan/ignore_lib2.cc
index 23a0872feabe..ad3107cf53a2 100644
--- a/test/tsan/ignore_lib2.cc
+++ b/test/tsan/ignore_lib2.cc
@@ -1,7 +1,7 @@
// 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" %deflake %run %t | FileCheck %s
+// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %deflake %run %t | FileCheck %s
// Tests that called_from_lib suppression matched against 2 libraries
// causes program crash (this is not supported).
diff --git a/test/tsan/ignore_lib3.cc b/test/tsan/ignore_lib3.cc
index 137109ea6cb4..96bf313f43a1 100644
--- a/test/tsan/ignore_lib3.cc
+++ b/test/tsan/ignore_lib3.cc
@@ -1,6 +1,6 @@
// 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" %deflake %run %t | FileCheck %s
+// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %deflake %run %t | FileCheck %s
// Tests that unloading of a library matched against called_from_lib suppression
// causes program crash (this is not supported).
diff --git a/test/tsan/ignore_malloc.cc b/test/tsan/ignore_malloc.cc
index 0f1fb5e3dfdc..1f633f062d0e 100644
--- a/test/tsan/ignore_malloc.cc
+++ b/test/tsan/ignore_malloc.cc
@@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
extern "C" {
void AnnotateIgnoreReadsBegin(const char *f, int l);
@@ -16,7 +13,7 @@ int *g;
void *Thread(void *a) {
int *p = 0;
while ((p = __atomic_load_n(&g, __ATOMIC_RELAXED)) == 0)
- usleep(100);
+ usleep(100); // spin-wait
*p = 42;
return 0;
}
diff --git a/test/tsan/ignore_race.cc b/test/tsan/ignore_race.cc
index c6e067fabec0..cc33b66b27d4 100644
--- a/test/tsan/ignore_race.cc
+++ b/test/tsan/ignore_race.cc
@@ -1,7 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
@@ -16,13 +14,15 @@ void *Thread(void *x) {
Global = 42;
AnnotateIgnoreReadsEnd(__FILE__, __LINE__);
AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
- sleep(1);
+ barrier_wait(&barrier);
Global = 43;
pthread_join(t, 0);
printf("OK\n");
diff --git a/test/tsan/inlined_memcpy_race.cc b/test/tsan/inlined_memcpy_race.cc
index a95576a83c9a..e3ed07abcf89 100644
--- a/test/tsan/inlined_memcpy_race.cc
+++ b/test/tsan/inlined_memcpy_race.cc
@@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
+#include "test.h"
#include <string.h>
-#include <unistd.h>
int x[4], z[4];
void *MemCpyThread(void *a) {
memcpy((int*)a, z, 16);
+ barrier_wait(&barrier);
return NULL;
}
void *MemSetThread(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
memset((int*)a, 0, 16);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
// Race on x between memcpy and memset
pthread_create(&t[0], NULL, MemCpyThread, x);
diff --git a/test/tsan/inlined_memcpy_race2.cc b/test/tsan/inlined_memcpy_race2.cc
index 63b560f02269..37414ba5d3db 100644
--- a/test/tsan/inlined_memcpy_race2.cc
+++ b/test/tsan/inlined_memcpy_race2.cc
@@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
+#include "test.h"
#include <string.h>
-#include <unistd.h>
int y[4], z[4];
void *MemMoveThread(void *a) {
memmove((int*)a, z, 16);
+ barrier_wait(&barrier);
return NULL;
}
void *MemSetThread(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
memset((int*)a, 0, 16);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
// Race on y between memmove and memset
pthread_create(&t[0], NULL, MemMoveThread, y);
diff --git a/test/tsan/java.h b/test/tsan/java.h
index d986d08be060..35fdbc1e7bb1 100644
--- a/test/tsan/java.h
+++ b/test/tsan/java.h
@@ -1,7 +1,4 @@
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
extern "C" {
typedef unsigned long jptr; // NOLINT
@@ -18,4 +15,7 @@ void __tsan_java_mutex_read_lock(jptr addr);
void __tsan_java_mutex_read_unlock(jptr addr);
void __tsan_java_mutex_lock_rec(jptr addr, int rec);
int __tsan_java_mutex_unlock_rec(jptr addr);
+int __tsan_java_acquire(jptr addr);
+int __tsan_java_release(jptr addr);
+int __tsan_java_release_store(jptr addr);
}
diff --git a/test/tsan/java_finalizer.cc b/test/tsan/java_finalizer.cc
index d5c6a22d1e16..acbbf08ad711 100644
--- a/test/tsan/java_finalizer.cc
+++ b/test/tsan/java_finalizer.cc
@@ -2,13 +2,14 @@
#include "java.h"
void *Thread(void *p) {
- sleep(1);
+ barrier_wait(&barrier);
__tsan_java_finalize();
*(int*)p = 42;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@@ -17,6 +18,7 @@ int main() {
pthread_t th;
pthread_create(&th, 0, Thread, (void*)jheap);
*(int*)jheap = 43;
+ barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
fprintf(stderr, "DONE\n");
diff --git a/test/tsan/java_lock.cc b/test/tsan/java_lock.cc
index 36a0f8b7bff3..f1720529523c 100644
--- a/test/tsan/java_lock.cc
+++ b/test/tsan/java_lock.cc
@@ -1,12 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "java.h"
-#include <unistd.h>
jptr varaddr;
jptr lockaddr;
void *Thread(void *p) {
- sleep(1);
+ barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr);
*(int*)varaddr = 42;
__tsan_java_mutex_unlock(lockaddr);
@@ -14,6 +13,7 @@ void *Thread(void *p) {
}
int main() {
+ barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@@ -26,6 +26,7 @@ int main() {
__tsan_java_mutex_lock(lockaddr);
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
+ barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
fprintf(stderr, "DONE\n");
diff --git a/test/tsan/java_lock_move.cc b/test/tsan/java_lock_move.cc
index 19c3e35d6633..fe5491dc2aa0 100644
--- a/test/tsan/java_lock_move.cc
+++ b/test/tsan/java_lock_move.cc
@@ -7,7 +7,7 @@ jptr varaddr2;
jptr lockaddr2;
void *Thread(void *p) {
- sleep(1);
+ barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr2);
*(int*)varaddr2 = 42;
__tsan_java_mutex_unlock(lockaddr2);
@@ -15,6 +15,7 @@ void *Thread(void *p) {
}
int main() {
+ barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@@ -31,6 +32,7 @@ int main() {
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
__tsan_java_move(varaddr, varaddr2, kBlockSize);
+ barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(varaddr2, kBlockSize);
printf("DONE\n");
diff --git a/test/tsan/java_lock_rec.cc b/test/tsan/java_lock_rec.cc
index 2b0ab0eb92d0..f0bf40196e9f 100644
--- a/test/tsan/java_lock_rec.cc
+++ b/test/tsan/java_lock_rec.cc
@@ -1,6 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "java.h"
-#include <unistd.h>
jptr varaddr;
jptr lockaddr;
@@ -14,7 +13,8 @@ void *Thread(void *p) {
printf("FAILED 0 rec=%d\n", rec);
exit(1);
}
- sleep(2);
+ barrier_wait(&barrier);
+ barrier_wait(&barrier);
__tsan_java_mutex_lock_rec(lockaddr, rec);
if (*(int*)varaddr != 43) {
printf("FAILED 3 var=%d\n", *(int*)varaddr);
@@ -26,6 +26,7 @@ void *Thread(void *p) {
}
int main() {
+ barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@@ -36,7 +37,7 @@ int main() {
lockaddr = jheap + 8;
pthread_t th;
pthread_create(&th, 0, Thread, 0);
- sleep(1);
+ barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr);
if (*(int*)varaddr != 42) {
printf("FAILED 1 var=%d\n", *(int*)varaddr);
@@ -44,6 +45,7 @@ int main() {
}
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
+ barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
printf("DONE\n");
diff --git a/test/tsan/java_lock_rec_race.cc b/test/tsan/java_lock_rec_race.cc
index 841aa396360d..3da8ad076990 100644
--- a/test/tsan/java_lock_rec_race.cc
+++ b/test/tsan/java_lock_rec_race.cc
@@ -1,6 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include "java.h"
-#include <unistd.h>
jptr varaddr;
jptr lockaddr;
@@ -15,7 +14,8 @@ void *Thread(void *p) {
exit(1);
}
*(int*)varaddr = 42;
- sleep(2);
+ barrier_wait(&barrier);
+ barrier_wait(&barrier);
__tsan_java_mutex_lock_rec(lockaddr, rec);
__tsan_java_mutex_unlock(lockaddr);
__tsan_java_mutex_unlock(lockaddr);
@@ -24,6 +24,7 @@ void *Thread(void *p) {
}
int main() {
+ barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@@ -34,10 +35,11 @@ int main() {
lockaddr = jheap + 8;
pthread_t th;
pthread_create(&th, 0, Thread, 0);
- sleep(1);
+ barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr);
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
+ barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
printf("DONE\n");
diff --git a/test/tsan/java_move_overlap.cc b/test/tsan/java_move_overlap.cc
index 12955b4ba0de..7ed98ef1a210 100644
--- a/test/tsan/java_move_overlap.cc
+++ b/test/tsan/java_move_overlap.cc
@@ -13,7 +13,7 @@ jptr lockaddr1_new;
jptr lockaddr2_new;
void *Thread(void *p) {
- sleep(1);
+ barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr1_new);
*(char*)varaddr1_new = 43;
__tsan_java_mutex_unlock(lockaddr1_new);
@@ -24,6 +24,7 @@ void *Thread(void *p) {
}
int main(int argc, char **argv) {
+ barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
void *jheap = malloc(kHeapSize);
jheap = (char*)jheap + 8;
@@ -62,6 +63,7 @@ int main(int argc, char **argv) {
__tsan_java_mutex_unlock(lockaddr2_old);
__tsan_java_move(varaddr1_old, varaddr1_new, kBlockSize);
+ barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(varaddr1_new, kBlockSize);
printf("DONE\n");
diff --git a/test/tsan/java_move_overlap_race.cc b/test/tsan/java_move_overlap_race.cc
index 2b3769be6117..874b90b26341 100644
--- a/test/tsan/java_move_overlap_race.cc
+++ b/test/tsan/java_move_overlap_race.cc
@@ -9,13 +9,14 @@ jptr varaddr1_new;
jptr varaddr2_new;
void *Thread(void *p) {
- sleep(1);
+ barrier_wait(&barrier);
*(int*)varaddr1_new = 43;
*(int*)varaddr2_new = 43;
return 0;
}
int main(int argc, char **argv) {
+ barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
void *jheap = malloc(kHeapSize);
jheap = (char*)jheap + 8;
@@ -42,6 +43,7 @@ int main(int argc, char **argv) {
*(int*)varaddr2_old = 43;
__tsan_java_move(varaddr1_old, varaddr1_new, kBlockSize);
+ barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(varaddr1_new, kBlockSize);
printf("DONE\n");
diff --git a/test/tsan/java_race_move.cc b/test/tsan/java_race_move.cc
index 8a51be92aa10..6d1b092160e0 100644
--- a/test/tsan/java_race_move.cc
+++ b/test/tsan/java_race_move.cc
@@ -5,12 +5,13 @@ jptr varaddr;
jptr varaddr2;
void *Thread(void *p) {
- sleep(1);
+ barrier_wait(&barrier);
*(int*)varaddr2 = 42;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@@ -23,6 +24,7 @@ int main() {
pthread_create(&th, 0, Thread, 0);
*(int*)varaddr = 43;
__tsan_java_move(varaddr, varaddr2, kBlockSize);
+ barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(varaddr2, kBlockSize);
fprintf(stderr, "DONE\n");
diff --git a/test/tsan/java_rwlock.cc b/test/tsan/java_rwlock.cc
index b03afa6e092d..a4cc92a13635 100644
--- a/test/tsan/java_rwlock.cc
+++ b/test/tsan/java_rwlock.cc
@@ -1,12 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "java.h"
-#include <unistd.h>
jptr varaddr;
jptr lockaddr;
void *Thread(void *p) {
- sleep(1);
+ barrier_wait(&barrier);
__tsan_java_mutex_read_lock(lockaddr);
*(int*)varaddr = 42;
__tsan_java_mutex_read_unlock(lockaddr);
@@ -14,6 +13,7 @@ void *Thread(void *p) {
}
int main() {
+ barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@@ -26,6 +26,7 @@ int main() {
__tsan_java_mutex_lock(lockaddr);
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
+ barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
printf("DONE\n");
diff --git a/test/tsan/java_volatile.cc b/test/tsan/java_volatile.cc
new file mode 100644
index 000000000000..885b4f241712
--- /dev/null
+++ b/test/tsan/java_volatile.cc
@@ -0,0 +1,42 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include "java.h"
+
+jptr varaddr;
+jptr lockaddr;
+
+void *Thread(void *p) {
+ while (__atomic_load_n((int*)lockaddr, __ATOMIC_RELAXED) == 0)
+ usleep(1000); // spin-wait
+ __tsan_java_acquire(lockaddr);
+ *(int*)varaddr = 42;
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ int const kHeapSize = 1024 * 1024;
+ jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
+ __tsan_java_init(jheap, kHeapSize);
+ const int kBlockSize = 16;
+ __tsan_java_alloc(jheap, kBlockSize);
+ varaddr = jheap;
+ lockaddr = jheap + 8;
+ pthread_t th;
+ pthread_create(&th, 0, Thread, 0);
+ *(int*)varaddr = 43;
+ __tsan_java_release(lockaddr);
+ __atomic_store_n((int*)lockaddr, 1, __ATOMIC_RELAXED);
+ pthread_join(th, 0);
+ *(int*)lockaddr = 0;
+ pthread_create(&th, 0, Thread, 0);
+ *(int*)varaddr = 43;
+ __tsan_java_release_store(lockaddr);
+ __atomic_store_n((int*)lockaddr, 1, __ATOMIC_RELAXED);
+ pthread_join(th, 0);
+ __tsan_java_free(jheap, kBlockSize);
+ fprintf(stderr, "DONE\n");
+ return __tsan_java_fini();
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: data race
+// CHECK: DONE
diff --git a/test/tsan/load_shared_lib.cc b/test/tsan/load_shared_lib.cc
index a27dc1cc6ffb..b7934b82df73 100644
--- a/test/tsan/load_shared_lib.cc
+++ b/test/tsan/load_shared_lib.cc
@@ -7,35 +7,39 @@
#ifdef BUILD_SO
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
int GLOB_SHARED = 0;
extern "C"
+void init_so() {
+ barrier_init(&barrier, 2);
+}
+
+extern "C"
void *write_from_so(void *unused) {
- if (unused)
- sleep(1);
+ if (unused == 0)
+ barrier_wait(&barrier);
GLOB_SHARED++;
+ if (unused != 0)
+ barrier_wait(&barrier);
return NULL;
}
#else // BUILD_SO
+#include "test.h"
#include <dlfcn.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
-
#include <string>
int GLOB = 0;
void *write_glob(void *unused) {
- if (unused)
- sleep(1);
+ if (unused == 0)
+ barrier_wait(&barrier);
GLOB++;
+ if (unused != 0)
+ barrier_wait(&barrier);
return NULL;
}
@@ -48,6 +52,7 @@ void race_two_threads(void *(*access_callback)(void *unused)) {
}
int main(int argc, char *argv[]) {
+ barrier_init(&barrier, 2);
std::string path = std::string(argv[0]) + std::string("-so.so");
race_two_threads(write_glob);
// CHECK: write_glob
@@ -56,6 +61,9 @@ int main(int argc, char *argv[]) {
printf("error in dlopen(): %s\n", dlerror());
return 1;
}
+ void (*init_so)();
+ *(void **)&init_so = dlsym(lib, "init_so");
+ init_so();
void *(*write_from_so)(void *unused);
*(void **)&write_from_so = dlsym(lib, "write_from_so");
race_two_threads(write_from_so);
diff --git a/test/tsan/malloc_stack.cc b/test/tsan/malloc_stack.cc
index 6027360754aa..ba1d62bcd9e7 100644
--- a/test/tsan/malloc_stack.cc
+++ b/test/tsan/malloc_stack.cc
@@ -1,20 +1,21 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
_Atomic(int*) p;
void *thr(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
int *pp = __c11_atomic_load(&p, __ATOMIC_RELAXED);
*pp = 42;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t th;
pthread_create(&th, 0, thr, p);
__c11_atomic_store(&p, new int, __ATOMIC_RELAXED);
+ barrier_wait(&barrier);
pthread_join(th, 0);
}
diff --git a/test/tsan/map32bit.cc b/test/tsan/map32bit.cc
index 3a76fa2f6d62..9dae6880e7fe 100644
--- a/test/tsan/map32bit.cc
+++ b/test/tsan/map32bit.cc
@@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
+#include "test.h"
#include <stdint.h>
-#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
@@ -12,10 +9,12 @@
void *Thread(void *ptr) {
*(int*)ptr = 42;
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
void *ptr = mmap(0, 128 << 10, PROT_READ|PROT_WRITE,
MAP_32BIT|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
fprintf(stderr, "ptr=%p\n", ptr);
@@ -29,7 +28,7 @@ int main() {
}
pthread_t t;
pthread_create(&t, 0, Thread, ptr);
- sleep(1);
+ barrier_wait(&barrier);
*(int*)ptr = 42;
pthread_join(t, 0);
munmap(ptr, 128 << 10);
diff --git a/test/tsan/memcpy_race.cc b/test/tsan/memcpy_race.cc
index 8ec8e0a3e6a5..d49577306d6c 100644
--- a/test/tsan/memcpy_race.cc
+++ b/test/tsan/memcpy_race.cc
@@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
+#include "test.h"
#include <string.h>
-#include <unistd.h>
char *data = new char[10];
char *data1 = new char[10];
@@ -12,17 +9,19 @@ char *data2 = new char[10];
void *Thread1(void *x) {
static volatile int size = 1;
memcpy(data+5, data1, size);
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
static volatile int size = 4;
- sleep(1);
+ barrier_wait(&barrier);
memcpy(data+3, data2, size);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
fprintf(stderr, "addr=%p\n", &data[5]);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
diff --git a/test/tsan/mop_with_offset.cc b/test/tsan/mop_with_offset.cc
index e44c78b7d1b4..c67e81e09cda 100644
--- a/test/tsan/mop_with_offset.cc
+++ b/test/tsan/mop_with_offset.cc
@@ -1,23 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
void *Thread1(void *x) {
int *p = (int*)x;
p[0] = 1;
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
char *p = (char*)x;
p[2] = 1;
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
int *data = new int(42);
fprintf(stderr, "ptr1=%p\n", data);
fprintf(stderr, "ptr2=%p\n", (char*)data + 2);
diff --git a/test/tsan/mop_with_offset2.cc b/test/tsan/mop_with_offset2.cc
index a465d5f09471..460267359cec 100644
--- a/test/tsan/mop_with_offset2.cc
+++ b/test/tsan/mop_with_offset2.cc
@@ -1,11 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
int *p = (int*)x;
p[0] = 1;
return NULL;
@@ -14,10 +11,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
char *p = (char*)x;
p[2] = 1;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
int *data = new int(42);
fprintf(stderr, "ptr1=%p\n", data);
fprintf(stderr, "ptr2=%p\n", (char*)data + 2);
diff --git a/test/tsan/mutex_cycle2.c b/test/tsan/mutex_cycle2.c
index 031830d5ec63..85d19a0d0c35 100644
--- a/test/tsan/mutex_cycle2.c
+++ b/test/tsan/mutex_cycle2.c
@@ -2,10 +2,10 @@
// RUN: not %run %t 2>&1 | FileCheck %s
// RUN: TSAN_OPTIONS=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s
// RUN: TSAN_OPTIONS=detect_deadlocks=0 %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
-// RUN: echo "deadlock:main" > %t.sup
-// RUN: TSAN_OPTIONS="suppressions=%t.sup" %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
-// RUN: echo "deadlock:zzzz" > %t.sup
-// RUN: TSAN_OPTIONS="suppressions=%t.sup" not %run %t 2>&1 | FileCheck %s
+// RUN: echo "deadlock:main" > %t.supp
+// RUN: TSAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: echo "deadlock:zzzz" > %t.supp
+// RUN: TSAN_OPTIONS="suppressions='%t.supp'" not %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
diff --git a/test/tsan/mutexset1.cc b/test/tsan/mutexset1.cc
index 72964edfb1e7..407cfe5bd9f1 100644
--- a/test/tsan/mutexset1.cc
+++ b/test/tsan/mutexset1.cc
@@ -1,13 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
pthread_mutex_t mtx;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
pthread_mutex_lock(&mtx);
Global++;
pthread_mutex_unlock(&mtx);
@@ -16,10 +14,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
Global--;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]]):
diff --git a/test/tsan/mutexset2.cc b/test/tsan/mutexset2.cc
index 01a5f5df6e94..2a3e5bb95e87 100644
--- a/test/tsan/mutexset2.cc
+++ b/test/tsan/mutexset2.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
pthread_mutex_t mtx;
@@ -10,16 +8,18 @@ void *Thread1(void *x) {
pthread_mutex_lock(&mtx);
Global++;
pthread_mutex_unlock(&mtx);
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
Global--;
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T2:
// CHECK: Previous write of size 4 at {{.*}} by thread T1
diff --git a/test/tsan/mutexset3.cc b/test/tsan/mutexset3.cc
index e14bb1111e32..ce64cf86e37c 100644
--- a/test/tsan/mutexset3.cc
+++ b/test/tsan/mutexset3.cc
@@ -1,14 +1,12 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
pthread_mutex_t mtx1;
pthread_mutex_t mtx2;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
pthread_mutex_lock(&mtx1);
pthread_mutex_lock(&mtx2);
Global++;
@@ -19,10 +17,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
Global--;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]], write [[M2:M[0-9]+]]):
diff --git a/test/tsan/mutexset4.cc b/test/tsan/mutexset4.cc
index db860e005d67..b961efd2136c 100644
--- a/test/tsan/mutexset4.cc
+++ b/test/tsan/mutexset4.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
pthread_mutex_t mtx1;
@@ -13,16 +11,18 @@ void *Thread1(void *x) {
Global++;
pthread_mutex_unlock(&mtx2);
pthread_mutex_unlock(&mtx1);
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
Global--;
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T2:
// CHECK: Previous write of size 4 at {{.*}} by thread T1
diff --git a/test/tsan/mutexset5.cc b/test/tsan/mutexset5.cc
index e1cc2fcacf62..8ef9af0ced52 100644
--- a/test/tsan/mutexset5.cc
+++ b/test/tsan/mutexset5.cc
@@ -1,14 +1,12 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
pthread_mutex_t mtx1;
pthread_mutex_t mtx2;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
pthread_mutex_lock(&mtx1);
Global++;
pthread_mutex_unlock(&mtx1);
@@ -19,10 +17,12 @@ void *Thread2(void *x) {
pthread_mutex_lock(&mtx2);
Global--;
pthread_mutex_unlock(&mtx2);
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]]):
diff --git a/test/tsan/mutexset6.cc b/test/tsan/mutexset6.cc
index 07dcc0a7394d..f4251db6970e 100644
--- a/test/tsan/mutexset6.cc
+++ b/test/tsan/mutexset6.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
pthread_mutex_t mtx1;
@@ -9,7 +7,7 @@ pthread_spinlock_t mtx2;
pthread_rwlock_t mtx3;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
pthread_mutex_lock(&mtx1);
Global++;
pthread_mutex_unlock(&mtx1);
@@ -24,10 +22,12 @@ void *Thread2(void *x) {
Global--;
pthread_spin_unlock(&mtx2);
pthread_rwlock_unlock(&mtx3);
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]]):
diff --git a/test/tsan/mutexset7.cc b/test/tsan/mutexset7.cc
index 12174844c799..d3a221d1b421 100644
--- a/test/tsan/mutexset7.cc
+++ b/test/tsan/mutexset7.cc
@@ -1,13 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
__thread int huge[1024*1024];
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
Global++;
return NULL;
}
@@ -20,10 +18,12 @@ void *Thread2(void *x) {
pthread_mutex_unlock(mtx);
pthread_mutex_destroy(mtx);
delete mtx;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/mutexset8.cc b/test/tsan/mutexset8.cc
index 3e1ab8c5a744..40d5d043dedd 100644
--- a/test/tsan/mutexset8.cc
+++ b/test/tsan/mutexset8.cc
@@ -1,13 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
pthread_mutex_t *mtx;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
pthread_mutex_lock(mtx);
Global++;
pthread_mutex_unlock(mtx);
@@ -16,10 +14,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
Global--;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]]):
diff --git a/test/tsan/process_sleep.h b/test/tsan/process_sleep.h
deleted file mode 100644
index 5938a42bf8b2..000000000000
--- a/test/tsan/process_sleep.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <time.h>
-
-static void process_sleep(int sec) {
- clock_t beg = clock();
- while((clock() - beg) / CLOCKS_PER_SEC < sec)
- usleep(100);
-}
diff --git a/test/tsan/pthread_atfork_deadlock.c b/test/tsan/pthread_atfork_deadlock.c
index 0f33b9022e5f..4aeec82b6850 100644
--- a/test/tsan/pthread_atfork_deadlock.c
+++ b/test/tsan/pthread_atfork_deadlock.c
@@ -4,14 +4,12 @@
// When the data race was reported, pthread_atfork() handler used to be
// executed which caused another race report in the same thread, which resulted
// in a deadlock.
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int glob = 0;
void *worker(void *unused) {
- sleep(1);
+ barrier_wait(&barrier);
glob++;
return NULL;
}
@@ -22,10 +20,12 @@ void atfork() {
}
int main() {
+ barrier_init(&barrier, 2);
pthread_atfork(atfork, NULL, NULL);
pthread_t t;
pthread_create(&t, NULL, worker, NULL);
glob++;
+ barrier_wait(&barrier);
pthread_join(t, NULL);
// CHECK: ThreadSanitizer: data race
// CHECK-NOT: ATFORK
diff --git a/test/tsan/race_on_barrier.c b/test/tsan/race_on_barrier.c
index 99b18fe4d8e6..cf8a4cb99274 100644
--- a/test/tsan/race_on_barrier.c
+++ b/test/tsan/race_on_barrier.c
@@ -1,25 +1,24 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
pthread_barrier_t B;
int Global;
void *Thread1(void *x) {
pthread_barrier_init(&B, 0, 2);
+ barrier_wait(&barrier);
pthread_barrier_wait(&B);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
pthread_barrier_wait(&B);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, NULL, Thread1, NULL);
Thread2(0);
diff --git a/test/tsan/race_on_mutex.c b/test/tsan/race_on_mutex.c
index b4adeeb4df72..7bd461bf3731 100644
--- a/test/tsan/race_on_mutex.c
+++ b/test/tsan/race_on_mutex.c
@@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
pthread_mutex_t Mtx;
int Global;
@@ -12,11 +9,12 @@ void *Thread1(void *x) {
pthread_mutex_lock(&Mtx);
Global = 42;
pthread_mutex_unlock(&Mtx);
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
pthread_mutex_lock(&Mtx);
Global = 43;
pthread_mutex_unlock(&Mtx);
@@ -24,6 +22,7 @@ void *Thread2(void *x) {
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
@@ -36,7 +35,7 @@ int main() {
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK-NEXT: Atomic read of size 1 at {{.*}} by thread T2:
// CHECK-NEXT: #0 pthread_mutex_lock
-// CHECK-NEXT: #1 Thread2{{.*}} {{.*}}race_on_mutex.c:20{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #1 Thread2{{.*}} {{.*}}race_on_mutex.c:18{{(:3)?}} ({{.*}})
// CHECK: Previous write of size 1 at {{.*}} by thread T1:
// CHECK-NEXT: #0 pthread_mutex_init {{.*}} ({{.*}})
-// CHECK-NEXT: #1 Thread1{{.*}} {{.*}}race_on_mutex.c:11{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #1 Thread1{{.*}} {{.*}}race_on_mutex.c:8{{(:3)?}} ({{.*}})
diff --git a/test/tsan/race_on_mutex2.c b/test/tsan/race_on_mutex2.c
index 1796d0c6480b..6ee5438f566e 100644
--- a/test/tsan/race_on_mutex2.c
+++ b/test/tsan/race_on_mutex2.c
@@ -1,21 +1,20 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
void *Thread(void *x) {
pthread_mutex_lock((pthread_mutex_t*)x);
pthread_mutex_unlock((pthread_mutex_t*)x);
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_mutex_t Mtx;
pthread_mutex_init(&Mtx, 0);
pthread_t t;
pthread_create(&t, 0, Thread, &Mtx);
- sleep(1);
+ barrier_wait(&barrier);
pthread_mutex_destroy(&Mtx);
pthread_join(t, 0);
return 0;
diff --git a/test/tsan/race_on_puts.cc b/test/tsan/race_on_puts.cc
index 1f2b4db836ed..f2541823bf0c 100644
--- a/test/tsan/race_on_puts.cc
+++ b/test/tsan/race_on_puts.cc
@@ -1,21 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
char s[] = "abracadabra";
void *Thread0(void *p) {
puts(s);
+ barrier_wait(&barrier);
return 0;
}
void *Thread1(void *p) {
+ barrier_wait(&barrier);
s[3] = 'z';
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t th[2];
pthread_create(&th[0], 0, Thread0, 0);
pthread_create(&th[1], 0, Thread1, 0);
diff --git a/test/tsan/race_on_read.cc b/test/tsan/race_on_read.cc
index 1ec0522b9035..d388bbacde5b 100644
--- a/test/tsan/race_on_read.cc
+++ b/test/tsan/race_on_read.cc
@@ -1,31 +1,35 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <unistd.h>
#include <errno.h>
int fd;
char buf;
-void *Thread(void *x) {
- sleep(1);
+void *Thread1(void *x) {
+ barrier_wait(&barrier);
read(fd, &buf, 1);
return NULL;
}
+void *Thread2(void *x) {
+ read(fd, &buf, 1);
+ barrier_wait(&barrier);
+ return NULL;
+}
+
int main() {
+ barrier_init(&barrier, 2);
fd = open("/dev/random", O_RDONLY);
if (fd < 0) {
fprintf(stderr, "failed to open /dev/random (%d)\n", errno);
return 1;
}
pthread_t t[2];
- pthread_create(&t[0], NULL, Thread, NULL);
- pthread_create(&t[1], NULL, Thread, NULL);
+ pthread_create(&t[0], NULL, Thread1, NULL);
+ pthread_create(&t[1], NULL, Thread2, NULL);
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
close(fd);
diff --git a/test/tsan/race_on_speculative_load.cc b/test/tsan/race_on_speculative_load.cc
index f816db9e8853..b50b69677d4b 100644
--- a/test/tsan/race_on_speculative_load.cc
+++ b/test/tsan/race_on_speculative_load.cc
@@ -1,9 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t | FileCheck %s
// Regtest for https://code.google.com/p/thread-sanitizer/issues/detail?id=40
// This is a correct program and tsan should not report a race.
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
+#include "test.h"
+
int g;
__attribute__((noinline))
int foo(int cond) {
@@ -11,17 +10,21 @@ int foo(int cond) {
return g;
return 0;
}
+
void *Thread1(void *p) {
+ barrier_wait(&barrier);
long res = foo((long)p);
- sleep(1);
return (void*) res;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread1, 0);
g = 1;
+ barrier_wait(&barrier);
pthread_join(t, 0);
printf("PASS\n");
+ // CHECK-NOT: ThreadSanitizer: data race
// CHECK: PASS
}
diff --git a/test/tsan/race_on_write.cc b/test/tsan/race_on_write.cc
index 484bbb7ae022..147591a39b9b 100644
--- a/test/tsan/race_on_write.cc
+++ b/test/tsan/race_on_write.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -11,7 +9,7 @@ char buf;
void *Thread1(void *x) {
buf = 1;
- sleep(1);
+ barrier_wait(&barrier);
return NULL;
}
@@ -21,11 +19,12 @@ void *Thread2(void *x) {
}
int main() {
+ barrier_init(&barrier, 2);
fd = open("/dev/null", O_WRONLY);
if (fd < 0) return 1;
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
- sleep(1);
+ barrier_wait(&barrier);
pthread_create(&t[1], NULL, Thread2, NULL);
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
diff --git a/test/tsan/race_with_finished_thread.cc b/test/tsan/race_with_finished_thread.cc
index d28760093c42..755a7bd982bb 100644
--- a/test/tsan/race_with_finished_thread.cc
+++ b/test/tsan/race_with_finished_thread.cc
@@ -1,9 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
+#include "test.h"
// Ensure that we can restore a stack of a finished thread.
@@ -15,16 +11,19 @@ void __attribute__((noinline)) foobar(int *p) {
void *Thread1(void *x) {
foobar(&g_data);
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
+ sleep(1); // let the thread finish and exit
g_data = 43;
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/real_deadlock_detector_stress_test.cc b/test/tsan/real_deadlock_detector_stress_test.cc
new file mode 100644
index 000000000000..67c878f45084
--- /dev/null
+++ b/test/tsan/real_deadlock_detector_stress_test.cc
@@ -0,0 +1,186 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <vector>
+#include <algorithm>
+
+const int kThreads = 4;
+const int kMutexes = 16 << 10;
+const int kIters = 400 << 10;
+const int kMaxPerThread = 10;
+
+const int kStateInited = 0;
+const int kStateNotInited = -1;
+const int kStateLocked = -2;
+
+struct Mutex {
+ int state;
+ pthread_rwlock_t m;
+};
+
+Mutex mtx[kMutexes];
+
+void check(int res) {
+ if (res != 0) {
+ printf("SOMETHING HAS FAILED\n");
+ exit(1);
+ }
+}
+
+bool cas(int *a, int oldval, int newval) {
+ return __atomic_compare_exchange_n(a, &oldval, newval, false,
+ __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
+
+void *Thread(void *seed) {
+ unsigned rnd = (unsigned)(unsigned long)seed;
+ int err;
+ std::vector<int> locked;
+ for (int i = 0; i < kIters; i++) {
+ int what = rand_r(&rnd) % 10;
+ if (what < 4 && locked.size() < kMaxPerThread) {
+ // lock
+ int max_locked = -1;
+ if (!locked.empty()) {
+ max_locked = *std::max_element(locked.begin(), locked.end());
+ if (max_locked == kMutexes - 1) {
+ i--;
+ continue;
+ }
+ }
+ int id = (rand_r(&rnd) % (kMutexes - max_locked - 1)) + max_locked + 1;
+ Mutex *m = &mtx[id];
+ // init the mutex if necessary or acquire a reference
+ for (;;) {
+ int old = __atomic_load_n(&m->state, __ATOMIC_RELAXED);
+ if (old == kStateLocked) {
+ pthread_yield();
+ continue;
+ }
+ int newv = old + 1;
+ if (old == kStateNotInited)
+ newv = kStateLocked;
+ if (cas(&m->state, old, newv)) {
+ if (old == kStateNotInited) {
+ if ((err = pthread_rwlock_init(&m->m, 0))) {
+ fprintf(stderr, "pthread_rwlock_init failed with %d\n", err);
+ exit(1);
+ }
+ if (!cas(&m->state, kStateLocked, 1)) {
+ fprintf(stderr, "init commit failed\n");
+ exit(1);
+ }
+ }
+ break;
+ }
+ }
+ // now we have an inited and referenced mutex, choose what to do
+ bool failed = false;
+ switch (rand_r(&rnd) % 4) {
+ case 0:
+ if ((err = pthread_rwlock_wrlock(&m->m))) {
+ fprintf(stderr, "pthread_rwlock_wrlock failed with %d\n", err);
+ exit(1);
+ }
+ break;
+ case 1:
+ if ((err = pthread_rwlock_rdlock(&m->m))) {
+ fprintf(stderr, "pthread_rwlock_rdlock failed with %d\n", err);
+ exit(1);
+ }
+ break;
+ case 2:
+ err = pthread_rwlock_trywrlock(&m->m);
+ if (err != 0 && err != EBUSY) {
+ fprintf(stderr, "pthread_rwlock_trywrlock failed with %d\n", err);
+ exit(1);
+ }
+ failed = err == EBUSY;
+ break;
+ case 3:
+ err = pthread_rwlock_tryrdlock(&m->m);
+ if (err != 0 && err != EBUSY) {
+ fprintf(stderr, "pthread_rwlock_tryrdlock failed with %d\n", err);
+ exit(1);
+ }
+ failed = err == EBUSY;
+ break;
+ }
+ if (failed) {
+ if (__atomic_fetch_sub(&m->state, 1, __ATOMIC_ACQ_REL) <= 0) {
+ fprintf(stderr, "failed to unref after failed trylock\n");
+ exit(1);
+ }
+ continue;
+ }
+ locked.push_back(id);
+ } else if (what < 9 && !locked.empty()) {
+ // unlock
+ int pos = rand_r(&rnd) % locked.size();
+ int id = locked[pos];
+ locked[pos] = locked[locked.size() - 1];
+ locked.pop_back();
+ Mutex *m = &mtx[id];
+ if ((err = pthread_rwlock_unlock(&m->m))) {
+ fprintf(stderr, "pthread_rwlock_unlock failed with %d\n", err);
+ exit(1);
+ }
+ if (__atomic_fetch_sub(&m->state, 1, __ATOMIC_ACQ_REL) <= 0) {
+ fprintf(stderr, "failed to unref after unlock\n");
+ exit(1);
+ }
+ } else {
+ // Destroy a random mutex.
+ int id = rand_r(&rnd) % kMutexes;
+ Mutex *m = &mtx[id];
+ if (!cas(&m->state, kStateInited, kStateLocked)) {
+ i--;
+ continue;
+ }
+ if ((err = pthread_rwlock_destroy(&m->m))) {
+ fprintf(stderr, "pthread_rwlock_destroy failed with %d\n", err);
+ exit(1);
+ }
+ if (!cas(&m->state, kStateLocked, kStateNotInited)) {
+ fprintf(stderr, "destroy commit failed\n");
+ exit(1);
+ }
+ }
+ }
+ // Unlock all previously locked mutexes, otherwise other threads can deadlock.
+ for (int i = 0; i < locked.size(); i++) {
+ int id = locked[i];
+ Mutex *m = &mtx[id];
+ if ((err = pthread_rwlock_unlock(&m->m))) {
+ fprintf(stderr, "pthread_rwlock_unlock failed with %d\n", err);
+ exit(1);
+ }
+ }
+ return 0;
+}
+
+int main() {
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ unsigned s = (unsigned)ts.tv_nsec;
+ fprintf(stderr, "seed %d\n", s);
+ srand(s);
+ for (int i = 0; i < kMutexes; i++)
+ mtx[i].state = kStateNotInited;
+ pthread_t t[kThreads];
+ for (int i = 0; i < kThreads; i++)
+ pthread_create(&t[i], 0, Thread, (void*)(unsigned long)rand());
+ for (int i = 0; i < kThreads; i++)
+ pthread_join(t[i], 0);
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer
+// CHECK: DONE
+
diff --git a/test/tsan/restore_stack.cc b/test/tsan/restore_stack.cc
new file mode 100644
index 000000000000..39c11011ca49
--- /dev/null
+++ b/test/tsan/restore_stack.cc
@@ -0,0 +1,50 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
+#include "test.h"
+
+int Global;
+volatile int x;
+const int kSize = 64 << 10;
+volatile long data[kSize];
+
+void __attribute__((noinline)) foo() {
+ for (int i = 0; i < kSize; i++)
+ data[i]++;
+}
+
+void *Thread(void *a) {
+ __atomic_store_n(&x, 1, __ATOMIC_RELEASE);
+ foo();
+ data[0]++;
+ if (a != 0)
+ barrier_wait(&barrier);
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ for (int i = 0; i < 50; i++) {
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ pthread_join(t, 0);
+ }
+ pthread_t t;
+ pthread_create(&t, 0, Thread, (void*)1);
+ barrier_wait(&barrier);
+ for (int i = 0; i < kSize; i++)
+ data[i]++;
+ pthread_join(t, 0);
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// Previously this test produced bogus stack traces like:
+// Previous write of size 8 at 0x0000006a8ff8 by thread T17:
+// #0 foo() restore_stack.cc:13:5 (restore_stack.cc.exe+0x00000040622c)
+// #1 Thread(void*) restore_stack.cc:18:3 (restore_stack.cc.exe+0x000000406283)
+// #2 __tsan_thread_start_func rtl/tsan_interceptors.cc:886 (restore_stack.cc.exe+0x00000040a749)
+// #3 Thread(void*) restore_stack.cc:18:3 (restore_stack.cc.exe+0x000000406283)
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK-NOT: __tsan_thread_start_func
+// CHECK-NOT: #3 Thread
+// CHECK: DONE
diff --git a/test/tsan/signal_errno.cc b/test/tsan/signal_errno.cc
index 1fa20f36810b..8305e84930f3 100644
--- a/test/tsan/signal_errno.cc
+++ b/test/tsan/signal_errno.cc
@@ -1,10 +1,7 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "test.h"
#include <signal.h>
#include <sys/types.h>
-#include <unistd.h>
#include <errno.h>
pthread_t mainth;
@@ -16,12 +13,13 @@ static void MyHandler(int, siginfo_t *s, void *c) {
}
static void* sendsignal(void *p) {
- sleep(1);
+ barrier_wait(&barrier);
pthread_kill(mainth, SIGPROF);
return 0;
}
static __attribute__((noinline)) void loop() {
+ barrier_wait(&barrier);
while (done == 0) {
volatile char *p = (char*)malloc(1);
p[0] = 0;
@@ -31,6 +29,7 @@ static __attribute__((noinline)) void loop() {
}
int main() {
+ barrier_init(&barrier, 2);
mainth = pthread_self();
struct sigaction act = {};
act.sa_sigaction = &MyHandler;
diff --git a/test/tsan/signal_malloc.cc b/test/tsan/signal_malloc.cc
index 06932fba42db..1dccb139c415 100644
--- a/test/tsan/signal_malloc.cc
+++ b/test/tsan/signal_malloc.cc
@@ -1,9 +1,7 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <stdio.h>
-#include <stdlib.h>
+#include "test.h"
#include <signal.h>
#include <sys/types.h>
-#include <unistd.h>
static void handler(int, siginfo_t*, void*) {
// CHECK: WARNING: ThreadSanitizer: signal-unsafe call inside of a signal
@@ -20,7 +18,7 @@ int main() {
act.sa_sigaction = &handler;
sigaction(SIGPROF, &act, 0);
kill(getpid(), SIGPROF);
- sleep(1);
+ sleep(1); // let the signal handler run
return 0;
}
diff --git a/test/tsan/signal_recursive.cc b/test/tsan/signal_recursive.cc
index bbb6807586a5..825338de9fba 100644
--- a/test/tsan/signal_recursive.cc
+++ b/test/tsan/signal_recursive.cc
@@ -3,19 +3,13 @@
// Test case for recursive signal handlers, adopted from:
// https://code.google.com/p/thread-sanitizer/issues/detail?id=71
-#include <pthread.h>
+#include "test.h"
#include <semaphore.h>
#include <signal.h>
-#include <unistd.h>
#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "process_sleep.h"
static const int kSigSuspend = SIGUSR1;
static const int kSigRestart = SIGUSR2;
-static sigset_t g_suspend_handler_mask;
static sem_t g_thread_suspend_ack_sem;
@@ -27,7 +21,7 @@ static void SaveRegistersInStack() {
// Mono walks thread stacks to detect unreferenced objects.
// If last object reference is kept in register the object will be collected
// This is why threads can't be suspended with something like pthread_suspend
-};
+}
static void fail(const char *what) {
fprintf(stderr, "FAILED: %s (errno=%d)\n", what, errno);
@@ -37,15 +31,19 @@ static void fail(const char *what) {
static void SuspendHandler(int sig) {
int old_errno = errno;
SaveRegistersInStack();
+
+ // Enable kSigRestart handling, tsan disables signals around signal handlers.
+ sigset_t sigset;
+ sigemptyset(&sigset);
+ pthread_sigmask(SIG_SETMASK, &sigset, 0);
+
// Acknowledge that thread is saved and suspended
if (sem_post(&g_thread_suspend_ack_sem) != 0)
fail("sem_post failed");
- do {
- g_busy_thread_received_restart = false;
- if (sigsuspend(&g_suspend_handler_mask) != -1 || errno != EINTR)
- fail("sigsuspend failed");
- } while (!g_busy_thread_received_restart);
+ // Wait for wakeup signal.
+ while (!g_busy_thread_received_restart)
+ usleep(100); // wait for kSigRestart signal
// Acknowledge that thread restarted
if (sem_post(&g_thread_suspend_ack_sem) != 0)
@@ -83,21 +81,15 @@ static void StartWorld(pthread_t thread) {
static void CollectGarbage(pthread_t thread) {
StopWorld(thread);
// Walk stacks
- process_sleep(1);
StartWorld(thread);
}
static void Init() {
- if (sigfillset(&g_suspend_handler_mask) != 0)
- fail("sigfillset failed");
- if (sigdelset(&g_suspend_handler_mask, kSigRestart) != 0)
- fail("sigdelset failed");
if (sem_init(&g_thread_suspend_ack_sem, 0, 0) != 0)
fail("sem_init failed");
struct sigaction act = {};
act.sa_flags = SA_RESTART;
- sigfillset(&act.sa_mask);
act.sa_handler = &SuspendHandler;
if (sigaction(kSigSuspend, &act, NULL) != 0)
fail("sigaction failed");
diff --git a/test/tsan/signal_reset.cc b/test/tsan/signal_reset.cc
new file mode 100644
index 000000000000..aec98dc399e9
--- /dev/null
+++ b/test/tsan/signal_reset.cc
@@ -0,0 +1,74 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <errno.h>
+
+volatile int X;
+int stop;
+
+static void handler(int sig) {
+ (void)sig;
+ if (X != 0)
+ printf("bad");
+}
+
+static void* busy(void *p) {
+ while (__atomic_load_n(&stop, __ATOMIC_RELAXED) == 0) {
+ }
+ return 0;
+}
+
+static void* reset(void *p) {
+ struct sigaction act = {};
+ for (int i = 0; i < 1000000; i++) {
+ act.sa_handler = &handler;
+ if (sigaction(SIGPROF, &act, 0)) {
+ perror("sigaction");
+ exit(1);
+ }
+ act.sa_handler = SIG_IGN;
+ if (sigaction(SIGPROF, &act, 0)) {
+ perror("sigaction");
+ exit(1);
+ }
+ }
+ return 0;
+}
+
+int main() {
+ struct sigaction act = {};
+ act.sa_handler = SIG_IGN;
+ if (sigaction(SIGPROF, &act, 0)) {
+ perror("sigaction");
+ exit(1);
+ }
+
+ itimerval t;
+ t.it_value.tv_sec = 0;
+ t.it_value.tv_usec = 10;
+ t.it_interval = t.it_value;
+ if (setitimer(ITIMER_PROF, &t, 0)) {
+ perror("setitimer");
+ exit(1);
+ }
+
+ pthread_t th[2];
+ pthread_create(&th[0], 0, busy, 0);
+ pthread_create(&th[1], 0, reset, 0);
+
+ pthread_join(th[1], 0);
+ __atomic_store_n(&stop, 1, __ATOMIC_RELAXED);
+ pthread_join(th[0], 0);
+
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer:
+// CHECK: DONE
+// CHECK-NOT: WARNING: ThreadSanitizer:
diff --git a/test/tsan/signal_sync.cc b/test/tsan/signal_sync.cc
index 15387b754dfb..6ff19d3bd120 100644
--- a/test/tsan/signal_sync.cc
+++ b/test/tsan/signal_sync.cc
@@ -1,11 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "test.h"
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
-#include <unistd.h>
#include <errno.h>
volatile int X;
@@ -18,7 +15,7 @@ static void handler(int sig) {
static void* thr(void *p) {
for (int i = 0; i != 1000; i++)
- usleep(1000);
+ usleep(1000); // process signals
return 0;
}
diff --git a/test/tsan/signal_thread.cc b/test/tsan/signal_thread.cc
new file mode 100644
index 000000000000..8eda80a52264
--- /dev/null
+++ b/test/tsan/signal_thread.cc
@@ -0,0 +1,52 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <errno.h>
+
+volatile int X;
+
+static void handler(int sig) {
+ (void)sig;
+ if (X != 0)
+ printf("bad");
+}
+
+static void* thr(void *p) {
+ return 0;
+}
+
+int main() {
+ struct sigaction act = {};
+ act.sa_handler = &handler;
+ if (sigaction(SIGPROF, &act, 0)) {
+ perror("sigaction");
+ exit(1);
+ }
+
+ itimerval t;
+ t.it_value.tv_sec = 0;
+ t.it_value.tv_usec = 10;
+ t.it_interval = t.it_value;
+ if (setitimer(ITIMER_PROF, &t, 0)) {
+ perror("setitimer");
+ exit(1);
+ }
+
+ for (int i = 0; i < 10000; i++) {
+ pthread_t th;
+ pthread_create(&th, 0, thr, 0);
+ pthread_join(th, 0);
+ }
+
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer:
+// CHECK: DONE
+// CHECK-NOT: WARNING: ThreadSanitizer:
diff --git a/test/tsan/signal_write.cc b/test/tsan/signal_write.cc
index 626d87a7acc7..edb3d2356bd2 100644
--- a/test/tsan/signal_write.cc
+++ b/test/tsan/signal_write.cc
@@ -16,7 +16,7 @@ int main() {
act.sa_sigaction = &handler;
sigaction(SIGPROF, &act, 0);
kill(getpid(), SIGPROF);
- sleep(1);
+ sleep(1); // let the signal handler run, can't use barrier in sig handler
fprintf(stderr, "DONE\n");
return 0;
}
diff --git a/test/tsan/simple_race.c b/test/tsan/simple_race.c
index 7b60c5ec249e..b4234acd7f89 100644
--- a/test/tsan/simple_race.c
+++ b/test/tsan/simple_race.c
@@ -1,22 +1,22 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
Global = 42;
return NULL;
}
void *Thread2(void *x) {
Global = 43;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/simple_race.cc b/test/tsan/simple_race.cc
index f711bb5d114d..612ce2dc0c4f 100644
--- a/test/tsan/simple_race.cc
+++ b/test/tsan/simple_race.cc
@@ -1,22 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
Global++;
return NULL;
}
void *Thread2(void *x) {
Global--;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/simple_stack.c b/test/tsan/simple_stack.c
index 87367033b4c9..6ef92fb46c68 100644
--- a/test/tsan/simple_stack.c
+++ b/test/tsan/simple_stack.c
@@ -1,7 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
@@ -24,13 +22,14 @@ void __attribute__((noinline)) bar2() {
}
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
bar1();
return NULL;
}
void *Thread2(void *x) {
bar2();
+ barrier_wait(&barrier);
return NULL;
}
@@ -39,6 +38,7 @@ void StartThread(pthread_t *t, void *(*f)(void*)) {
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
StartThread(&t[0], Thread1);
StartThread(&t[1], Thread2);
@@ -49,18 +49,18 @@ int main() {
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK-NEXT: Write of size 4 at {{.*}} by thread T1:
-// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack.c:9{{(:3)?}} ({{.*}})
-// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack.c:14{{(:3)?}} ({{.*}})
-// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack.c:28{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack.c:7{{(:10)?}} ({{.*}})
+// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack.c:12{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack.c:26{{(:3)?}} ({{.*}})
// CHECK: Previous read of size 4 at {{.*}} by thread T2:
-// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack.c:18{{(:3)?}} ({{.*}})
-// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack.c:23{{(:3)?}} ({{.*}})
-// CHECK-NEXT: #2 Thread2{{.*}} {{.*}}simple_stack.c:33{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack.c:16{{(:20)?}} ({{.*}})
+// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack.c:21{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #2 Thread2{{.*}} {{.*}}simple_stack.c:31{{(:3)?}} ({{.*}})
// CHECK: Thread T1 (tid={{.*}}, running) created by main thread at:
// CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}})
-// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:38{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:37{{(:3)?}} ({{.*}})
// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:43{{(:3)?}} ({{.*}})
// CHECK: Thread T2 ({{.*}}) created by main thread at:
// CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}})
-// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:38{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:37{{(:3)?}} ({{.*}})
// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:44{{(:3)?}} ({{.*}})
diff --git a/test/tsan/simple_stack2.cc b/test/tsan/simple_stack2.cc
index b07d863e4008..20ef729f7857 100644
--- a/test/tsan/simple_stack2.cc
+++ b/test/tsan/simple_stack2.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %T/simple_stack2.cc.exe && %deflake %run %T/simple_stack2.cc.exe | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
int Global;
@@ -30,24 +28,26 @@ void __attribute__((noinline)) bar2() {
}
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
bar1();
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, NULL, Thread1, NULL);
bar2();
+ barrier_wait(&barrier);
pthread_join(t, NULL);
}
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK-NEXT: Write of size 4 at {{.*}} by thread T1:
-// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack2.cc:9{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
-// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack2.cc:16{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
-// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack2.cc:34{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
+// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack2.cc:7{{(:10)?}} (simple_stack2.cc.exe+{{.*}})
+// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack2.cc:14{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
+// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack2.cc:32{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK: Previous read of size 4 at {{.*}} by main thread:
-// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack2.cc:20{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
-// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack2.cc:29{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
-// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack2.cc:41{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
+// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack2.cc:18{{(:22)?}} (simple_stack2.cc.exe+{{.*}})
+// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack2.cc:27{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
+// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack2.cc:40{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
diff --git a/test/tsan/sleep_sync.cc b/test/tsan/sleep_sync.cc
index c7614e16bf3e..b2c6a1220f42 100644
--- a/test/tsan/sleep_sync.cc
+++ b/test/tsan/sleep_sync.cc
@@ -1,23 +1,25 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
int X = 0;
void MySleep() {
- sleep(1);
+ sleep(1); // the sleep that must appear in the report
}
void *Thread(void *p) {
+ barrier_wait(&barrier);
MySleep(); // Assume the main thread has done the write.
X = 42;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
X = 43;
+ barrier_wait(&barrier);
pthread_join(t, 0);
return 0;
}
diff --git a/test/tsan/sleep_sync2.cc b/test/tsan/sleep_sync2.cc
index 4e616992ecc9..a1a7a3accb48 100644
--- a/test/tsan/sleep_sync2.cc
+++ b/test/tsan/sleep_sync2.cc
@@ -1,18 +1,20 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
int X = 0;
void *Thread(void *p) {
X = 42;
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
- sleep(1);
+ sleep(1); // must not appear in the report
pthread_create(&t, 0, Thread, 0);
+ barrier_wait(&barrier);
X = 43;
pthread_join(t, 0);
return 0;
diff --git a/test/tsan/stack_race.cc b/test/tsan/stack_race.cc
index 2e02f46a281f..1ada2953547b 100644
--- a/test/tsan/stack_race.cc
+++ b/test/tsan/stack_race.cc
@@ -1,19 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
void *Thread(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
*(int*)a = 43;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
int Var = 42;
pthread_t t;
pthread_create(&t, 0, Thread, &Var);
Var = 43;
+ barrier_wait(&barrier);
pthread_join(t, 0);
}
diff --git a/test/tsan/stack_race2.cc b/test/tsan/stack_race2.cc
index 818db367bab6..00e31fb96b08 100644
--- a/test/tsan/stack_race2.cc
+++ b/test/tsan/stack_race2.cc
@@ -1,10 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
void *Thread2(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
*(int*)a = 43;
return 0;
}
@@ -14,11 +12,13 @@ void *Thread(void *a) {
pthread_t t;
pthread_create(&t, 0, Thread2, &Var);
Var = 42;
+ barrier_wait(&barrier);
pthread_join(t, 0);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
pthread_join(t, 0);
diff --git a/test/tsan/stack_sync_reuse.cc b/test/tsan/stack_sync_reuse.cc
new file mode 100644
index 000000000000..5ea9e84b085a
--- /dev/null
+++ b/test/tsan/stack_sync_reuse.cc
@@ -0,0 +1,65 @@
+// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include "test.h"
+
+// Test case https://code.google.com/p/thread-sanitizer/issues/detail?id=87
+// Tsan sees false HB edge on address pointed to by syncp variable.
+// It is false because when acquire is done syncp points to a var in one frame,
+// and during release it points to a var in a different frame.
+// The code is somewhat tricky because it prevents compiler from optimizing
+// our accesses away, structured to not introduce other data races and
+// not introduce other synchronization, and to arrange the vars in different
+// frames to occupy the same address.
+
+// The data race CHECK-NOT below actually must be CHECK, because the program
+// does contain the data race on global.
+
+// CHECK-NOT: WARNING: ThreadSanitizer: data race
+// CHECK: DONE
+
+long global;
+long *syncp;
+long *addr;
+long sink;
+
+void *Thread(void *x) {
+ while (__atomic_load_n(&syncp, __ATOMIC_ACQUIRE) == 0)
+ usleep(1000); // spin wait
+ global = 42;
+ __atomic_store_n(syncp, 1, __ATOMIC_RELEASE);
+ __atomic_store_n(&syncp, 0, __ATOMIC_RELAXED);
+ return NULL;
+}
+
+void __attribute__((noinline)) foobar() {
+ long s;
+ addr = &s;
+ __atomic_store_n(&s, 0, __ATOMIC_RELAXED);
+ __atomic_store_n(&syncp, &s, __ATOMIC_RELEASE);
+ while (__atomic_load_n(&syncp, __ATOMIC_RELAXED) != 0)
+ usleep(1000); // spin wait
+}
+
+void __attribute__((noinline)) barfoo() {
+ long s;
+ if (addr != &s) {
+ printf("address mismatch addr=%p &s=%p\n", addr, &s);
+ exit(1);
+ }
+ __atomic_store_n(&addr, &s, __ATOMIC_RELAXED);
+ __atomic_store_n(&s, 0, __ATOMIC_RELAXED);
+ sink = __atomic_load_n(&s, __ATOMIC_ACQUIRE);
+ global = 43;
+}
+
+int main() {
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ foobar();
+ barfoo();
+ pthread_join(t, 0);
+ if (sink != 0)
+ exit(1);
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
diff --git a/test/tsan/suppress_same_address.cc b/test/tsan/suppress_same_address.cc
index df19da1cc7ae..3ec13ee8302f 100644
--- a/test/tsan/suppress_same_address.cc
+++ b/test/tsan/suppress_same_address.cc
@@ -1,11 +1,10 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
volatile int X;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
X = 42;
X = 66;
X = 78;
@@ -16,10 +15,12 @@ void *Thread2(void *x) {
X = 11;
X = 99;
X = 73;
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread1, 0);
Thread2(0);
diff --git a/test/tsan/suppressions_global.cc b/test/tsan/suppressions_global.cc
index c808a63d9e84..c7b9bb99eb17 100644
--- a/test/tsan/suppressions_global.cc
+++ b/test/tsan/suppressions_global.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %run %t 2>&1 | FileCheck %s
+// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
diff --git a/test/tsan/suppressions_race.cc b/test/tsan/suppressions_race.cc
index 1d72874d9586..45c30481f0cd 100644
--- a/test/tsan/suppressions_race.cc
+++ b/test/tsan/suppressions_race.cc
@@ -1,22 +1,22 @@
-// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s
+#include "test.h"
int Global;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
Global = 42;
return NULL;
}
void *Thread2(void *x) {
Global = 43;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/suppressions_race2.cc b/test/tsan/suppressions_race2.cc
index 4ababddf6311..24ecd8ef119f 100644
--- a/test/tsan/suppressions_race2.cc
+++ b/test/tsan/suppressions_race2.cc
@@ -1,22 +1,22 @@
-// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions=%s.supp" %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s
+#include "test.h"
int Global;
void *Thread1(void *x) {
Global = 42;
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
Global = 43;
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/test.h b/test/tsan/test.h
new file mode 100644
index 000000000000..4496e56cda87
--- /dev/null
+++ b/test/tsan/test.h
@@ -0,0 +1,31 @@
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <stddef.h>
+
+// TSan-invisible barrier.
+// Tests use it to establish necessary execution order in a way that does not
+// interfere with tsan (does not establish synchronization between threads).
+__typeof(pthread_barrier_wait) *barrier_wait;
+
+void barrier_init(pthread_barrier_t *barrier, unsigned count) {
+ if (barrier_wait == 0) {
+ void *h = dlopen("libpthread.so.0", RTLD_LAZY);
+ if (h == 0) {
+ fprintf(stderr, "failed to dlopen libpthread.so.0, exiting\n");
+ exit(1);
+ }
+ barrier_wait = (__typeof(barrier_wait))dlsym(h, "pthread_barrier_wait");
+ if (barrier_wait == 0) {
+ fprintf(stderr, "failed to resolve pthread_barrier_wait, exiting\n");
+ exit(1);
+ }
+ }
+ pthread_barrier_init(barrier, 0, count);
+}
+
+// Default instance of the barrier, but a test can declare more manually.
+pthread_barrier_t barrier;
+
diff --git a/test/tsan/thread_detach.c b/test/tsan/thread_detach.c
index 32cf641b141a..802d8ded0fad 100644
--- a/test/tsan/thread_detach.c
+++ b/test/tsan/thread_detach.c
@@ -1,16 +1,16 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
void *Thread(void *x) {
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
- sleep(1);
+ barrier_wait(&barrier);
pthread_detach(t);
printf("PASS\n");
return 0;
diff --git a/test/tsan/thread_leak3.c b/test/tsan/thread_leak3.c
index f4db484219a0..c09fb714d7ab 100644
--- a/test/tsan/thread_leak3.c
+++ b/test/tsan/thread_leak3.c
@@ -1,15 +1,17 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
void *Thread(void *x) {
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
- sleep(1);
+ barrier_wait(&barrier);
+ sleep(1); // wait for the thread to finish and exit
return 0;
}
diff --git a/test/tsan/thread_leak4.c b/test/tsan/thread_leak4.c
index 0d3b8307000a..1ebca58871ac 100644
--- a/test/tsan/thread_leak4.c
+++ b/test/tsan/thread_leak4.c
@@ -1,18 +1,18 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
+#include "test.h"
void *Thread(void *x) {
- sleep(10);
+ sleep(100); // leave the thread "running"
return 0;
}
int main() {
pthread_t t;
pthread_create(&t, 0, Thread, 0);
- printf("OK\n");
+ printf("DONE\n");
return 0;
}
+// CHECK: DONE
// CHECK-NOT: WARNING: ThreadSanitizer: thread leak
+
diff --git a/test/tsan/thread_leak5.c b/test/tsan/thread_leak5.c
index ca244a9f24e1..acdbd1d38a9b 100644
--- a/test/tsan/thread_leak5.c
+++ b/test/tsan/thread_leak5.c
@@ -1,18 +1,20 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
void *Thread(void *x) {
+ barrier_wait(&barrier);
return 0;
}
int main() {
volatile int N = 5; // prevent loop unrolling
+ barrier_init(&barrier, N + 1);
for (int i = 0; i < N; i++) {
pthread_t t;
pthread_create(&t, 0, Thread, 0);
}
- sleep(1);
+ barrier_wait(&barrier);
+ sleep(1); // wait for the threads to finish and exit
return 0;
}
diff --git a/test/tsan/thread_name.cc b/test/tsan/thread_name.cc
index a790c668c084..80d30b82d8b5 100644
--- a/test/tsan/thread_name.cc
+++ b/test/tsan/thread_name.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#if defined(__linux__)
#define USE_PTHREAD_SETNAME_NP __GLIBC_PREREQ(2, 12)
@@ -18,7 +16,7 @@ extern "C" void AnnotateThreadName(const char *f, int l, const char *name);
int Global;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
AnnotateThreadName(__FILE__, __LINE__, "Thread1");
Global++;
return NULL;
@@ -31,10 +29,12 @@ void *Thread2(void *x) {
AnnotateThreadName(__FILE__, __LINE__, "Thread2");
#endif
Global--;
+ barrier_wait(&barrier);
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/thread_name2.cc b/test/tsan/thread_name2.cc
index 6a3dafe9c763..a44f4b9d3247 100644
--- a/test/tsan/thread_name2.cc
+++ b/test/tsan/thread_name2.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#if defined(__FreeBSD__)
#include <pthread_np.h>
@@ -11,7 +9,7 @@
int Global;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
Global++;
return 0;
}
@@ -19,14 +17,17 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
pthread_setname_np(pthread_self(), "foobar2");
Global--;
+ barrier_wait(&barrier);
return 0;
}
int main() {
+ barrier_init(&barrier, 3);
pthread_t t[2];
pthread_create(&t[0], 0, Thread1, 0);
pthread_create(&t[1], 0, Thread2, 0);
pthread_setname_np(t[0], "foobar1");
+ barrier_wait(&barrier);
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
}
diff --git a/test/tsan/tiny_race.c b/test/tsan/tiny_race.c
index c10eab15c5a9..b6937febd117 100644
--- a/test/tsan/tiny_race.c
+++ b/test/tsan/tiny_race.c
@@ -1,19 +1,20 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
int Global;
void *Thread1(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
Global = 42;
return x;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread1, 0);
Global = 43;
+ barrier_wait(&barrier);
pthread_join(t, 0);
return Global;
}
diff --git a/test/tsan/tls_race.cc b/test/tsan/tls_race.cc
index 18589347e806..5e8172276708 100644
--- a/test/tsan/tls_race.cc
+++ b/test/tsan/tls_race.cc
@@ -1,19 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
void *Thread(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
*(int*)a = 43;
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
static __thread int Var = 42;
pthread_t t;
pthread_create(&t, 0, Thread, &Var);
Var = 43;
+ barrier_wait(&barrier);
pthread_join(t, 0);
}
diff --git a/test/tsan/tls_race2.cc b/test/tsan/tls_race2.cc
index 0ca629ada5cc..d0f7b03e09a1 100644
--- a/test/tsan/tls_race2.cc
+++ b/test/tsan/tls_race2.cc
@@ -1,10 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <unistd.h>
+#include "test.h"
void *Thread2(void *a) {
- sleep(1);
+ barrier_wait(&barrier);
*(int*)a = 43;
return 0;
}
@@ -14,11 +12,13 @@ void *Thread(void *a) {
pthread_t t;
pthread_create(&t, 0, Thread2, &Var);
Var = 42;
+ barrier_wait(&barrier);
pthread_join(t, 0);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
pthread_join(t, 0);
diff --git a/test/tsan/unaligned_norace.cc b/test/tsan/unaligned_norace.cc
index 20cb545f7426..94df1cf74cc1 100644
--- a/test/tsan/unaligned_norace.cc
+++ b/test/tsan/unaligned_norace.cc
@@ -7,20 +7,20 @@
uint64_t objs[8*3*3*2][3];
extern "C" {
-uint16_t __tsan_unaligned_read2(void *addr);
-uint32_t __tsan_unaligned_read4(void *addr);
-uint64_t __tsan_unaligned_read8(void *addr);
-void __tsan_unaligned_write2(void *addr, uint16_t v);
-void __tsan_unaligned_write4(void *addr, uint32_t v);
-void __tsan_unaligned_write8(void *addr, uint64_t v);
+void __tsan_unaligned_read2(void *addr);
+void __tsan_unaligned_read4(void *addr);
+void __tsan_unaligned_read8(void *addr);
+void __tsan_unaligned_write2(void *addr);
+void __tsan_unaligned_write4(void *addr);
+void __tsan_unaligned_write8(void *addr);
}
static void access(char *p, int sz, int rw) {
if (rw) {
switch (sz) {
- case 0: __tsan_unaligned_write2(p, 0); break;
- case 1: __tsan_unaligned_write4(p, 0); break;
- case 2: __tsan_unaligned_write8(p, 0); break;
+ case 0: __tsan_unaligned_write2(p); break;
+ case 1: __tsan_unaligned_write4(p); break;
+ case 2: __tsan_unaligned_write8(p); break;
default: exit(1);
}
} else {
diff --git a/test/tsan/unaligned_race.cc b/test/tsan/unaligned_race.cc
index 6e9b5a33f0da..030642a4ddfb 100644
--- a/test/tsan/unaligned_race.cc
+++ b/test/tsan/unaligned_race.cc
@@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "test.h"
#include <stdint.h>
-#include <unistd.h>
#define NOINLINE __attribute__((noinline))
@@ -123,15 +120,17 @@ NOINLINE void Test(bool main) {
void *Thread(void *p) {
(void)p;
- sleep(1);
+ barrier_wait(&barrier);
Test(false);
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t th;
pthread_create(&th, 0, Thread, 0);
Test(true);
+ barrier_wait(&barrier);
pthread_join(th, 0);
}
diff --git a/test/tsan/vptr_harmful_race.cc b/test/tsan/vptr_harmful_race.cc
index 68e12e8e7e89..d15b3969ab81 100644
--- a/test/tsan/vptr_harmful_race.cc
+++ b/test/tsan/vptr_harmful_race.cc
@@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
+#include "test.h"
#include <semaphore.h>
-#include <stdio.h>
-#include <unistd.h>
struct A {
A() {
@@ -31,16 +29,18 @@ static A *obj = new B;
void *Thread1(void *x) {
obj->F();
obj->Done();
+ barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
delete obj;
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/vptr_harmful_race2.cc b/test/tsan/vptr_harmful_race2.cc
index aa53bbb90fcf..a56b74c09689 100644
--- a/test/tsan/vptr_harmful_race2.cc
+++ b/test/tsan/vptr_harmful_race2.cc
@@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
+#include "test.h"
#include <semaphore.h>
-#include <stdio.h>
-#include <unistd.h>
struct A {
A() {
@@ -29,18 +27,20 @@ struct B : A {
static A *obj = new B;
void *Thread1(void *x) {
- sleep(1);
obj->F();
+ barrier_wait(&barrier);
obj->Done();
return NULL;
}
void *Thread2(void *x) {
+ barrier_wait(&barrier);
delete obj;
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/vptr_harmful_race3.cc b/test/tsan/vptr_harmful_race3.cc
index ac6ea94e51eb..3810a1068d64 100644
--- a/test/tsan/vptr_harmful_race3.cc
+++ b/test/tsan/vptr_harmful_race3.cc
@@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
+#include "test.h"
#include <semaphore.h>
-#include <stdio.h>
-#include <unistd.h>
struct A {
A() {
@@ -30,18 +28,20 @@ static A *obj = new B;
static void (A::*fn)() = &A::F;
void *Thread1(void *x) {
- sleep(1);
(obj->*fn)();
+ barrier_wait(&barrier);
obj->Done();
return NULL;
}
void *Thread2(void *x) {
+ barrier_wait(&barrier);
delete obj;
return NULL;
}
int main() {
+ barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
diff --git a/test/tsan/vptr_harmful_race4.cc b/test/tsan/vptr_harmful_race4.cc
index 969c9d58a016..543514de8387 100644
--- a/test/tsan/vptr_harmful_race4.cc
+++ b/test/tsan/vptr_harmful_race4.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
struct A {
virtual void F() {
@@ -17,16 +15,18 @@ struct B : A {
};
void *Thread(void *x) {
- sleep(1);
+ barrier_wait(&barrier);
((A*)x)->F();
return 0;
}
int main() {
+ barrier_init(&barrier, 2);
A *obj = new B;
pthread_t t;
pthread_create(&t, 0, Thread, obj);
delete obj;
+ barrier_wait(&barrier);
pthread_join(t, 0);
}
diff --git a/test/tsan/write_in_reader_lock.cc b/test/tsan/write_in_reader_lock.cc
index 55882139b153..3f7cb3579f77 100644
--- a/test/tsan/write_in_reader_lock.cc
+++ b/test/tsan/write_in_reader_lock.cc
@@ -1,6 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#include "test.h"
pthread_rwlock_t rwlock;
int GLOB;
@@ -8,14 +7,15 @@ int GLOB;
void *Thread1(void *p) {
(void)p;
pthread_rwlock_rdlock(&rwlock);
+ barrier_wait(&barrier);
// Write under reader lock.
- sleep(1);
GLOB++;
pthread_rwlock_unlock(&rwlock);
return 0;
}
int main(int argc, char *argv[]) {
+ barrier_init(&barrier, 2);
pthread_rwlock_init(&rwlock, NULL);
pthread_rwlock_rdlock(&rwlock);
pthread_t t;
@@ -23,6 +23,7 @@ int main(int argc, char *argv[]) {
volatile int x = GLOB;
(void)x;
pthread_rwlock_unlock(&rwlock);
+ barrier_wait(&barrier);
pthread_join(t, 0);
pthread_rwlock_destroy(&rwlock);
return 0;
@@ -30,6 +31,6 @@ int main(int argc, char *argv[]) {
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1{{.*}}:
-// CHECK: #0 Thread1(void*) {{.*}}write_in_reader_lock.cc:13
+// CHECK: #0 Thread1(void*) {{.*}}write_in_reader_lock.cc:12
// CHECK: Previous read of size 4 at {{.*}} by main thread{{.*}}:
// CHECK: #0 main {{.*}}write_in_reader_lock.cc:23
diff --git a/test/ubsan/TestCases/Float/cast-overflow.cpp b/test/ubsan/TestCases/Float/cast-overflow.cpp
index 22991e0a6c55..526817153d02 100644
--- a/test/ubsan/TestCases/Float/cast-overflow.cpp
+++ b/test/ubsan/TestCases/Float/cast-overflow.cpp
@@ -14,6 +14,7 @@
// This test assumes float and double are IEEE-754 single- and double-precision.
// XFAIL: armv7l-unknown-linux-gnueabihf
+// XFAIL: aarch64
#if defined(__APPLE__)
# include <machine/endian.h>
diff --git a/test/ubsan/TestCases/Integer/no-recover.cpp b/test/ubsan/TestCases/Integer/no-recover.cpp
index 575bd0a553fb..bbc2f8d2c1c4 100644
--- a/test/ubsan/TestCases/Integer/no-recover.cpp
+++ b/test/ubsan/TestCases/Integer/no-recover.cpp
@@ -1,6 +1,6 @@
// RUN: %clangxx -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
-// RUN: %clangxx -fsanitize=unsigned-integer-overflow -fsanitize-recover %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
-// RUN: %clangxx -fsanitize=unsigned-integer-overflow -fno-sanitize-recover %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=ABORT
+// RUN: %clangxx -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=all -fsanitize-recover=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+// RUN: %clangxx -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=unsigned-integer-overflow %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=ABORT
#include <stdint.h>
diff --git a/test/ubsan/TestCases/Misc/coverage-levels.cc b/test/ubsan/TestCases/Misc/coverage-levels.cc
new file mode 100644
index 000000000000..2fe12ffefd4b
--- /dev/null
+++ b/test/ubsan/TestCases/Misc/coverage-levels.cc
@@ -0,0 +1,38 @@
+// Test various levels of coverage
+//
+// RUN: mkdir -p %T/coverage-levels
+// RUN: OPT=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels
+// RUN: %clangxx -fsanitize=shift -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=1 %s -o %t
+// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
+// RUN: %clangxx -fsanitize=undefined -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=1 %s -o %t
+// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
+
+// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=1 %s -o %t
+// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN
+// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=2 %s -o %t
+// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN
+// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=3 %s -o %t
+// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
+
+// XFAIL: darwin
+
+volatile int sink;
+int main(int argc, char **argv) {
+ int shift = argc * 32;
+#if GOOD_SHIFT
+ shift = 3;
+#endif
+ if ((argc << shift) == 16) // False.
+ return 1;
+ return 0;
+}
+
+// CHECK_WARN: shift exponent 32 is too large
+// CHECK_NOWARN-NOT: ERROR
+// FIXME: Currently, coverage instrumentation kicks in after ubsan, so we get
+// more than the minimal number of instrumented blocks.
+// FIXME: Currently, ubsan with -fno-sanitize-recover and w/o asan will fail
+// to dump coverage.
+// CHECK1: 1 PCs written
+// CHECK2: 3 PCs written
+// CHECK3: 4 PCs written
diff --git a/test/ubsan/TestCases/Misc/nonnull-arg.cpp b/test/ubsan/TestCases/Misc/nonnull-arg.cpp
index b1061b757899..084dedc27b85 100644
--- a/test/ubsan/TestCases/Misc/nonnull-arg.cpp
+++ b/test/ubsan/TestCases/Misc/nonnull-arg.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=nonnull-attribute -fno-sanitize-recover %s -O3 -o %t
+// RUN: %clangxx -fsanitize=nonnull-attribute -fno-sanitize-recover=all %s -O3 -o %t
// RUN: %run %t nc
// RUN: %run %t nm
// RUN: %run %t nf
diff --git a/test/ubsan/TestCases/TypeCheck/misaligned.cpp b/test/ubsan/TestCases/TypeCheck/misaligned.cpp
index 79f5136db963..9c8455d5f1c3 100644
--- a/test/ubsan/TestCases/TypeCheck/misaligned.cpp
+++ b/test/ubsan/TestCases/TypeCheck/misaligned.cpp
@@ -9,9 +9,8 @@
// RUN: %run %t u1 2>&1 | FileCheck %s --check-prefix=CHECK-UPCAST
// RUN: UBSAN_OPTIONS=print_stacktrace=1 %run %t l1 2>&1 | FileCheck %s --check-prefix=CHECK-LOAD --check-prefix=CHECK-%os-STACK-LOAD
-// RUN: %clangxx -fsanitize=alignment -fno-sanitize-recover %s -O3 -o %t
+// RUN: %clangxx -fsanitize=alignment -fno-sanitize-recover=alignment %s -O3 -o %t
// RUN: not %run %t w1 2>&1 | FileCheck %s --check-prefix=CHECK-WILD
-// XFAIL: armv7l-unknown-linux-gnueabihf
#include <new>
@@ -81,7 +80,7 @@ int main(int, char **argv) {
return s->f() && 0;
case 'n':
- // CHECK-NEW: misaligned.cpp:[[@LINE+4]]:5: runtime error: constructor call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment
+ // CHECK-NEW: misaligned.cpp:[[@LINE+4]]:21: runtime error: constructor call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment
// CHECK-NEW-NEXT: [[PTR]]: note: pointer points here
// CHECK-NEW-NEXT: {{^ 00 00 00 01 02 03 04 05}}
// CHECK-NEW-NEXT: {{^ \^}}
@@ -97,8 +96,8 @@ int main(int, char **argv) {
}
case 'w':
- // CHECK-WILD: misaligned.cpp:[[@LINE+3]]:35: runtime error: member access within misaligned address 0x000000000123 for type 'S', which requires 4 byte alignment
- // CHECK-WILD-NEXT: 0x000000000123: note: pointer points here
+ // CHECK-WILD: misaligned.cpp:[[@LINE+3]]:35: runtime error: member access within misaligned address 0x{{0+}}123 for type 'S', which requires 4 byte alignment
+ // CHECK-WILD-NEXT: 0x{{0+}}123: note: pointer points here
// CHECK-WILD-NEXT: <memory cannot be printed>
return static_cast<S*>(wild)->k;
}
diff --git a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
index 5261e71c2d3d..033da24451c2 100644
--- a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
+++ b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=vptr -fno-sanitize-recover -g %s -O3 -o %t
+// RUN: %clangxx -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
// RUN: not %run %t 2>&1 | FileCheck %s
// FIXME: This test produces linker errors on Darwin.
diff --git a/test/ubsan/TestCases/TypeCheck/vptr.cpp b/test/ubsan/TestCases/TypeCheck/vptr.cpp
index 3a6b1553f9b3..98eac271c3a1 100644
--- a/test/ubsan/TestCases/TypeCheck/vptr.cpp
+++ b/test/ubsan/TestCases/TypeCheck/vptr.cpp
@@ -12,16 +12,16 @@
// RUN: %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --strict-whitespace
// RUN: (echo "vptr_check:S"; echo "vptr_check:T"; echo "vptr_check:U") > %t.supp
-// RUN: ASAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 UBSAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 %run %t mS 2>&1
-// RUN: ASAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 UBSAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 %run %t fS 2>&1
-// RUN: ASAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 UBSAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 %run %t cS 2>&1
-// RUN: ASAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 UBSAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 %run %t mV 2>&1
-// RUN: ASAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 UBSAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 %run %t fV 2>&1
-// RUN: ASAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 UBSAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 %run %t cV 2>&1
-// RUN: ASAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 UBSAN_OPTIONS=suppressions=%t.supp:halt_on_error=1 %run %t oU 2>&1
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mS 2>&1
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fS 2>&1
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cS 2>&1
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mV 2>&1
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fV 2>&1
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cV 2>&1
+// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t oU 2>&1
// RUN: echo "vptr_check:S" > %t.loc-supp
-// RUN: ASAN_OPTIONS=suppressions=%t.loc-supp:halt_on_error=1 UBSAN_OPTIONS=suppressions=%t.loc-supp:halt_on_error=1 not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
+// RUN: ASAN_OPTIONS="suppressions='%t.loc-supp'" UBSAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1" not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
// FIXME: This test produces linker errors on Darwin.
// XFAIL: darwin
@@ -48,8 +48,7 @@ struct T : S {
virtual int v() { return 1; }
};
-struct X {};
-struct U : S, T, virtual X { virtual int v() { return 2; } };
+struct U : S, T { virtual int v() { return 2; } };
struct V : S {};