Allow UBSan+MSan and UBSan+TSan combinations (Clang part).
Embed UBSan runtime into TSan and MSan runtimes in the same as we do in ASan. Extend UBSan test suite to also run tests for these combinations. llvm-svn: 235954
This commit is contained in:
parent
d60832eade
commit
b3053d9cbe
|
@ -32,9 +32,11 @@ foreach(arch ${MSAN_SUPPORTED_ARCH})
|
|||
$<TARGET_OBJECTS:RTInterception.${arch}>
|
||||
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
|
||||
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
|
||||
$<TARGET_OBJECTS:RTUbsan.${arch}>
|
||||
CFLAGS ${MSAN_RTL_CFLAGS})
|
||||
add_compiler_rt_runtime(clang_rt.msan_cxx-${arch} ${arch} STATIC
|
||||
SOURCES ${MSAN_RTL_CXX_SOURCES}
|
||||
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
|
||||
CFLAGS ${MSAN_RTL_CFLAGS})
|
||||
add_dependencies(msan clang_rt.msan-${arch}
|
||||
clang_rt.msan_cxx-${arch})
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "sanitizer_common/sanitizer_stacktrace.h"
|
||||
#include "sanitizer_common/sanitizer_symbolizer.h"
|
||||
#include "sanitizer_common/sanitizer_stackdepot.h"
|
||||
#include "ubsan/ubsan_flags.h"
|
||||
#include "ubsan/ubsan_init.h"
|
||||
|
||||
// ACHTUNG! No system header includes in this file.
|
||||
|
||||
|
@ -133,11 +135,6 @@ static void RegisterMsanFlags(FlagParser *parser, Flags *f) {
|
|||
}
|
||||
|
||||
static void InitializeFlags() {
|
||||
Flags *f = flags();
|
||||
FlagParser parser;
|
||||
RegisterMsanFlags(&parser, f);
|
||||
RegisterCommonFlags(&parser);
|
||||
|
||||
SetCommonFlagsDefaults();
|
||||
{
|
||||
CommonFlags cf;
|
||||
|
@ -151,14 +148,35 @@ static void InitializeFlags() {
|
|||
OverrideCommonFlags(cf);
|
||||
}
|
||||
|
||||
Flags *f = flags();
|
||||
f->SetDefaults();
|
||||
|
||||
FlagParser parser;
|
||||
RegisterMsanFlags(&parser, f);
|
||||
RegisterCommonFlags(&parser);
|
||||
|
||||
#if MSAN_CONTAINS_UBSAN
|
||||
__ubsan::Flags *uf = __ubsan::flags();
|
||||
uf->SetDefaults();
|
||||
|
||||
FlagParser ubsan_parser;
|
||||
__ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
|
||||
RegisterCommonFlags(&ubsan_parser);
|
||||
#endif
|
||||
|
||||
// Override from user-specified string.
|
||||
if (__msan_default_options)
|
||||
parser.ParseString(__msan_default_options());
|
||||
#if MSAN_CONTAINS_UBSAN
|
||||
const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
|
||||
ubsan_parser.ParseString(ubsan_default_options);
|
||||
#endif
|
||||
|
||||
const char *msan_options = GetEnv("MSAN_OPTIONS");
|
||||
parser.ParseString(msan_options);
|
||||
#if MSAN_CONTAINS_UBSAN
|
||||
ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
|
||||
#endif
|
||||
VPrintf(1, "MSAN_OPTIONS: %s\n", msan_options ? msan_options : "<empty>");
|
||||
|
||||
SetVerbosity(common_flags()->verbosity);
|
||||
|
@ -392,6 +410,10 @@ void __msan_init() {
|
|||
SetCurrentThread(main_thread);
|
||||
main_thread->ThreadStart();
|
||||
|
||||
#if MSAN_CONTAINS_UBSAN
|
||||
__ubsan::InitAsPlugin();
|
||||
#endif
|
||||
|
||||
VPrintf(1, "MemorySanitizer init done\n");
|
||||
|
||||
msan_init_is_running = 0;
|
||||
|
|
|
@ -20,11 +20,16 @@
|
|||
#include "sanitizer_common/sanitizer_stacktrace.h"
|
||||
#include "msan_interface_internal.h"
|
||||
#include "msan_flags.h"
|
||||
#include "ubsan/ubsan_platform.h"
|
||||
|
||||
#ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
|
||||
# define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1
|
||||
#endif
|
||||
|
||||
#ifndef MSAN_CONTAINS_UBSAN
|
||||
# define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB
|
||||
#endif
|
||||
|
||||
struct MappingDesc {
|
||||
uptr start;
|
||||
uptr end;
|
||||
|
|
|
@ -107,9 +107,11 @@ if(UNIX AND NOT APPLE)
|
|||
$<TARGET_OBJECTS:RTInterception.${arch}>
|
||||
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
|
||||
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
|
||||
$<TARGET_OBJECTS:RTUbsan.${arch}>
|
||||
CFLAGS ${TSAN_RTL_CFLAGS})
|
||||
add_compiler_rt_runtime(clang_rt.tsan_cxx-${arch} ${arch} STATIC
|
||||
SOURCES ${TSAN_CXX_SOURCES}
|
||||
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
|
||||
CFLAGS ${TSAN_RTL_CFLAGS})
|
||||
list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch}
|
||||
clang_rt.tsan_cxx-${arch})
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "sanitizer_common/sanitizer_internal_defs.h"
|
||||
#include "sanitizer_common/sanitizer_libc.h"
|
||||
#include "tsan_stat.h"
|
||||
#include "ubsan/ubsan_platform.h"
|
||||
|
||||
// Setup defaults for compile definitions.
|
||||
#ifndef TSAN_NO_HISTORY
|
||||
|
@ -27,6 +28,10 @@
|
|||
# define TSAN_COLLECT_STATS 0
|
||||
#endif
|
||||
|
||||
#ifndef TSAN_CONTAINS_UBSAN
|
||||
# define TSAN_CONTAINS_UBSAN (CAN_SANITIZE_UB && !defined(SANITIZER_GO))
|
||||
#endif
|
||||
|
||||
namespace __tsan {
|
||||
|
||||
#ifdef SANITIZER_GO
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "tsan_flags.h"
|
||||
#include "tsan_rtl.h"
|
||||
#include "tsan_mman.h"
|
||||
#include "ubsan/ubsan_flags.h"
|
||||
|
||||
namespace __tsan {
|
||||
|
||||
|
@ -54,12 +55,6 @@ void RegisterTsanFlags(FlagParser *parser, Flags *f) {
|
|||
}
|
||||
|
||||
void InitializeFlags(Flags *f, const char *env) {
|
||||
FlagParser parser;
|
||||
RegisterTsanFlags(&parser, f);
|
||||
RegisterCommonFlags(&parser);
|
||||
|
||||
f->SetDefaults();
|
||||
|
||||
SetCommonFlagsDefaults();
|
||||
{
|
||||
// Override some common flags defaults.
|
||||
|
@ -74,10 +69,32 @@ void InitializeFlags(Flags *f, const char *env) {
|
|||
OverrideCommonFlags(cf);
|
||||
}
|
||||
|
||||
f->SetDefaults();
|
||||
|
||||
FlagParser parser;
|
||||
RegisterTsanFlags(&parser, f);
|
||||
RegisterCommonFlags(&parser);
|
||||
|
||||
#if TSAN_CONTAINS_UBSAN
|
||||
__ubsan::Flags *uf = __ubsan::flags();
|
||||
uf->SetDefaults();
|
||||
|
||||
FlagParser ubsan_parser;
|
||||
__ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
|
||||
RegisterCommonFlags(&ubsan_parser);
|
||||
#endif
|
||||
|
||||
// Let a frontend override.
|
||||
parser.ParseString(__tsan_default_options());
|
||||
#if TSAN_CONTAINS_UBSAN
|
||||
const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
|
||||
ubsan_parser.ParseString(ubsan_default_options);
|
||||
#endif
|
||||
// Override from command line.
|
||||
parser.ParseString(env);
|
||||
#if TSAN_CONTAINS_UBSAN
|
||||
ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
|
||||
#endif
|
||||
|
||||
// Sanity check.
|
||||
if (!f->report_bugs) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "tsan_mman.h"
|
||||
#include "tsan_suppressions.h"
|
||||
#include "tsan_symbolize.h"
|
||||
#include "ubsan/ubsan_init.h"
|
||||
|
||||
#ifdef __SSE3__
|
||||
// <emmintrin.h> transitively includes <stdlib.h>,
|
||||
|
@ -350,6 +351,9 @@ void Initialize(ThreadState *thr) {
|
|||
int tid = ThreadCreate(thr, 0, 0, true);
|
||||
CHECK_EQ(tid, 0);
|
||||
ThreadStart(thr, tid, internal_getpid());
|
||||
#if TSAN_CONTAINS_UBSAN
|
||||
__ubsan::InitAsPlugin();
|
||||
#endif
|
||||
ctx->initialized = true;
|
||||
|
||||
if (flags()->stop_on_start) {
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
set(UBSAN_LIT_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(UBSAN_TESTSUITES)
|
||||
set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
|
||||
|
||||
macro(add_ubsan_testsuite test_mode sanitizer arch)
|
||||
set(UBSAN_LIT_TEST_MODE "${test_mode}")
|
||||
set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch})
|
||||
configure_lit_site_cfg(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
|
||||
list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
|
||||
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
||||
list(APPEND UBSAN_TEST_DEPS ${sanitizer})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
foreach(arch ${UBSAN_SUPPORTED_ARCH})
|
||||
set(UBSAN_TEST_TARGET_ARCH ${arch})
|
||||
if(${arch} MATCHES "arm|aarch64")
|
||||
|
@ -9,28 +23,19 @@ foreach(arch ${UBSAN_SUPPORTED_ARCH})
|
|||
else()
|
||||
get_target_flags_for_arch(${arch} UBSAN_TEST_TARGET_CFLAGS)
|
||||
endif()
|
||||
set(UBSAN_LIT_TEST_MODE "Standalone")
|
||||
set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch})
|
||||
configure_lit_site_cfg(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
|
||||
list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
|
||||
add_ubsan_testsuite("Standalone" ubsan ${arch})
|
||||
|
||||
if(COMPILER_RT_HAS_ASAN)
|
||||
set(UBSAN_LIT_TEST_MODE "AddressSanitizer")
|
||||
set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch})
|
||||
configure_lit_site_cfg(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
|
||||
list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
|
||||
if(";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
|
||||
add_ubsan_testsuite("AddressSanitizer" asan ${arch})
|
||||
endif()
|
||||
if(";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
|
||||
add_ubsan_testsuite("MemorySanitizer" msan ${arch})
|
||||
endif()
|
||||
if(";${TSAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
|
||||
add_ubsan_testsuite("ThreadSanitizer" tsan ${arch})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
|
||||
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
||||
list(APPEND UBSAN_TEST_DEPS ubsan asan)
|
||||
endif()
|
||||
|
||||
add_lit_testsuite(check-ubsan "Running UndefinedBehaviorSanitizer tests"
|
||||
${UBSAN_TESTSUITES}
|
||||
DEPENDS ${UBSAN_TEST_DEPS})
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=3 %s -o %t
|
||||
// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
|
||||
|
||||
// Coverage is not yet implemented in TSan.
|
||||
// XFAIL: ubsan-tsan
|
||||
|
||||
volatile int sink;
|
||||
int main(int argc, char **argv) {
|
||||
int shift = argc * 32;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
int f() {
|
||||
// Slow stack unwinding is disabled on Darwin for now, see
|
||||
// https://code.google.com/p/address-sanitizer/issues/detail?id=137
|
||||
// CHECK-Linux-STACKTRACE: #0 {{.*}} in f(){{.*}}missing_return.cpp:[[@LINE-3]]
|
||||
// CHECK-FreeBSD-STACKTRACE: #0 {{.*}} in f(void){{.*}}missing_return.cpp:[[@LINE-4]]
|
||||
// CHECK-Linux-STACKTRACE: #0 {{.*}}f(){{.*}}missing_return.cpp:[[@LINE-3]]
|
||||
// CHECK-FreeBSD-STACKTRACE: #0 {{.*}}f(void){{.*}}missing_return.cpp:[[@LINE-4]]
|
||||
// Check for already checked line to avoid lit error reports.
|
||||
// CHECK-Darwin-STACKTRACE: missing_return.cpp
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ int main(int, char **argv) {
|
|||
return *p && 0;
|
||||
// Slow stack unwinding is disabled on Darwin for now, see
|
||||
// https://code.google.com/p/address-sanitizer/issues/detail?id=137
|
||||
// CHECK-Linux-STACK-LOAD: #0 {{.*}} in main{{.*}}misaligned.cpp
|
||||
// CHECK-Linux-STACK-LOAD: #0 {{.*}}main{{.*}}misaligned.cpp
|
||||
// Check for the already checked line to avoid lit error reports.
|
||||
// CHECK-Darwin-STACK-LOAD: {{ }}
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ int access_p(T *p, char type) {
|
|||
// CHECK-MEMBER-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }}
|
||||
// CHECK-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
|
||||
// CHECK-MEMBER-NEXT: {{^ vptr for}} [[DYN_TYPE]]
|
||||
// CHECK-MEMBER-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]]
|
||||
// CHECK-MEMBER-NEXT: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
|
||||
return p->b;
|
||||
|
||||
// CHECK-NULL-MEMBER: vptr.cpp:[[@LINE-2]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
|
||||
|
@ -136,7 +136,7 @@ int access_p(T *p, char type) {
|
|||
// CHECK-NULL-MEMBER-NEXT: {{^ ?.. .. .. .. ?00 00 00 00 ?00 00 00 00 ?}}
|
||||
// CHECK-NULL-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
|
||||
// CHECK-NULL-MEMBER-NEXT: {{^ invalid vptr}}
|
||||
// CHECK-NULL-MEMBER-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE-7]]
|
||||
// CHECK-NULL-MEMBER-NEXT: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE-7]]
|
||||
|
||||
case 'f':
|
||||
// CHECK-MEMFUN: vptr.cpp:[[@LINE+6]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
|
||||
|
@ -153,7 +153,7 @@ int access_p(T *p, char type) {
|
|||
// CHECK-OFFSET-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. }}
|
||||
// CHECK-OFFSET-NEXT: {{^ \^ ( ~~~~~~~~~~~~)?~~~~~~~~~~~ *$}}
|
||||
// CHECK-OFFSET-NEXT: {{^ ( )?vptr for}} 'T' base class of [[DYN_TYPE]]
|
||||
// CHECK-OFFSET-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]]
|
||||
// CHECK-OFFSET-NEXT: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
|
||||
return reinterpret_cast<U*>(p)->v() - 2;
|
||||
|
||||
case 'c':
|
||||
|
@ -162,7 +162,7 @@ int access_p(T *p, char type) {
|
|||
// CHECK-DOWNCAST-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }}
|
||||
// CHECK-DOWNCAST-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
|
||||
// CHECK-DOWNCAST-NEXT: {{^ vptr for}} [[DYN_TYPE]]
|
||||
// CHECK-DOWNCAST-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]]
|
||||
// CHECK-DOWNCAST-NEXT: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
|
||||
static_cast<T*>(reinterpret_cast<S*>(p));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,14 @@ elif ubsan_lit_test_mode == "AddressSanitizer":
|
|||
config.available_features.add("ubsan-asan")
|
||||
clang_ubsan_cflags = ["-fsanitize=address"]
|
||||
config.environment['ASAN_OPTIONS'] = 'detect_leaks=0'
|
||||
elif ubsan_lit_test_mode == "MemorySanitizer":
|
||||
config.name = 'UBSan-MSan-' + config.target_arch
|
||||
config.available_features.add("ubsan-msan")
|
||||
clang_ubsan_cflags = ["-fsanitize=memory"]
|
||||
elif ubsan_lit_test_mode == "ThreadSanitizer":
|
||||
config.name = 'UBSan-TSan-' + config.target_arch
|
||||
config.available_features.add("ubsan-tsan")
|
||||
clang_ubsan_cflags = ["-fsanitize=thread"]
|
||||
else:
|
||||
lit_config.fatal("Unknown UBSan test mode: %r" % ubsan_lit_test_mode)
|
||||
|
||||
|
|
Loading…
Reference in New Issue