forked from OSchip/llvm-project
[TSan] Build TSan-instrumented version of libcxx and use it in lit tests.
TSan can produce false positives in code that uses C++11 threading, as it doesn't see synchronization inside standard library. See http://lists.cs.uiuc.edu/pipermail/cfe-dev/2014-February/035408.html for an example of such case. We may build custom TSan-instrumented version libcxx to fight with that. This change adds build rules for libcxx_tsan and integrates it into testing infrastructure. llvm-svn: 208737
This commit is contained in:
parent
060ca7596c
commit
5716928ae2
|
@ -75,6 +75,7 @@ set(TSAN_HEADERS
|
|||
rtl/tsan_update_shadow_word_inl.h
|
||||
rtl/tsan_vector.h)
|
||||
|
||||
set(TSAN_RUNTIME_LIBRARIES)
|
||||
add_custom_target(tsan)
|
||||
# TSan is currently supported on 64-bit Linux only.
|
||||
if(CAN_TARGET_x86_64 AND UNIX AND NOT APPLE)
|
||||
|
@ -90,6 +91,7 @@ if(CAN_TARGET_x86_64 AND UNIX AND NOT APPLE)
|
|||
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
|
||||
CFLAGS ${TSAN_RTL_CFLAGS}
|
||||
DEFS ${TSAN_COMMON_DEFINITIONS})
|
||||
list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch})
|
||||
add_sanitizer_rt_symbols(clang_rt.tsan-${arch} rtl/tsan.syms.extra)
|
||||
add_dependencies(tsan clang_rt.tsan-${arch}
|
||||
clang_rt.tsan-${arch}-symbols)
|
||||
|
@ -97,6 +99,14 @@ endif()
|
|||
|
||||
add_dependencies(compiler-rt tsan)
|
||||
|
||||
# Build libcxx instrumented with TSan.
|
||||
if(COMPILER_RT_HAS_LIBCXX_SOURCES)
|
||||
set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_tsan)
|
||||
add_custom_libcxx(libcxx_tsan ${LIBCXX_PREFIX}
|
||||
DEPS ${TSAN_RUNTIME_LIBRARIES}
|
||||
CFLAGS -fsanitize=thread)
|
||||
endif()
|
||||
|
||||
if(COMPILER_RT_INCLUDE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
|
|
@ -16,6 +16,7 @@ set_default("llvm_build_mode", "@LLVM_BUILD_MODE@")
|
|||
set_default("llvm_src_root", "@LLVM_SOURCE_DIR@")
|
||||
set_default("llvm_obj_root", "@LLVM_BINARY_DIR@")
|
||||
set_default("compiler_rt_src_root", "@COMPILER_RT_SOURCE_DIR@")
|
||||
set_default("compiler_rt_obj_root", "@COMPILER_RT_BINARY_DIR@")
|
||||
set_default("llvm_tools_dir", "@LLVM_TOOLS_DIR@")
|
||||
set_default("clang", "@COMPILER_RT_TEST_COMPILER@")
|
||||
set_default("compiler_id", "@COMPILER_RT_TEST_COMPILER_ID@")
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
configure_lit_site_cfg(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg)
|
||||
|
||||
set(TSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
|
||||
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
||||
list(APPEND TSAN_TEST_DEPS tsan)
|
||||
endif()
|
||||
if(COMPILER_RT_HAS_LIBCXX_SOURCES)
|
||||
list(APPEND TSAN_TEST_DEPS libcxx_tsan)
|
||||
set(TSAN_HAS_LIBCXX True)
|
||||
else()
|
||||
set(TSAN_HAS_LIBCXX False)
|
||||
endif()
|
||||
|
||||
configure_lit_site_cfg(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg)
|
||||
|
||||
if(COMPILER_RT_INCLUDE_TESTS)
|
||||
configure_lit_site_cfg(
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
def getRoot(config):
|
||||
if not config.parent:
|
||||
return config
|
||||
return getRoot(config.parent)
|
||||
|
||||
root = getRoot(config)
|
||||
|
||||
if not root.has_libcxx:
|
||||
config.unsupported = True
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
|
||||
#include <stdio.h>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
int main() {
|
||||
int v1 = 0;
|
||||
int v2 = 0;
|
||||
std::thread t1;
|
||||
std::thread t2;
|
||||
|
||||
{
|
||||
auto thingy = std::make_shared<int>(42);
|
||||
t1 = std::thread([thingy, &v1] { v1 = *thingy; });
|
||||
t2 = std::thread([thingy, &v2] { v2 = *thingy; });
|
||||
}
|
||||
|
||||
t1.join();
|
||||
t2.join();
|
||||
printf("%d %d\n", v1, v2);
|
||||
// CHECK-NOT: ThreadSanitizer: data race
|
||||
// CHECK: 42 42
|
||||
return 0;
|
||||
}
|
|
@ -31,6 +31,18 @@ clang_tsan_cflags = ["-fsanitize=thread",
|
|||
"-ldl",
|
||||
"-m64"]
|
||||
clang_tsan_cxxflags = config.cxx_mode_flags + clang_tsan_cflags
|
||||
# Add additional flags if we're using instrumented libc++.
|
||||
if config.has_libcxx:
|
||||
# FIXME: Dehardcode this path somehow.
|
||||
libcxx_path = os.path.join(config.compiler_rt_obj_root, "lib",
|
||||
"tsan", "libcxx_tsan")
|
||||
libcxx_incdir = os.path.join(libcxx_path, "include", "c++", "v1")
|
||||
libcxx_libdir = os.path.join(libcxx_path, "lib")
|
||||
libcxx_so = os.path.join(libcxx_libdir, "libc++.so")
|
||||
clang_tsan_cxxflags += ["-std=c++11",
|
||||
"-I%s" % libcxx_incdir,
|
||||
libcxx_so,
|
||||
"-Wl,-rpath=%s" % libcxx_libdir]
|
||||
|
||||
def build_invocation(compile_flags):
|
||||
return " " + " ".join([config.clang] + compile_flags) + " "
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
## Autogenerated by LLVM/Clang configuration.
|
||||
# Do not edit!
|
||||
|
||||
config.has_libcxx = @TSAN_HAS_LIBCXX@
|
||||
|
||||
# Load common config for all compiler-rt lit tests.
|
||||
lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
|
||||
|
||||
|
|
Loading…
Reference in New Issue