diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-02-10 07:45:43 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-02-10 07:45:43 +0000 |
commit | 476c4db3dc56bee43df384704c75ccc71cfa7a1d (patch) | |
tree | 5d0dcec3cc12fc53532fc84029892b98711a2596 /test/asan | |
parent | ca9211ecdede9bdedb812b2243a4abdb8dacd1b9 (diff) | |
download | src-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/asan')
56 files changed, 958 insertions, 221 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 |