From a026cf148aced25c12fbaf445b51e8d555330494 Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Wed, 19 Jul 2017 21:45:34 +0200 Subject: [PATCH] Add ASan runtime testing --- tests/CMakeLists.txt | 1 + tests/codegen/dcompute_cl_addrspaces.d | 3 ++- tests/lit.site.cfg.in | 6 ++---- tests/sanitizers/asan_stackoverflow.d | 26 ++++++++++++++++++++++++ tests/sanitizers/lit.local.cfg | 28 ++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 tests/sanitizers/asan_stackoverflow.d create mode 100644 tests/sanitizers/lit.local.cfg diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6b6fa56c2d..a79e153ecc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,6 +3,7 @@ set( LDCPROFDATA_BIN ${PROJECT_BINARY_DIR}/bin/${LDCPROFDATA_EXE} ) set( LDCPRUNECACHE_BIN ${PROJECT_BINARY_DIR}/bin/${LDCPRUNECACHE_EXE} ) set( LLVM_TOOLS_DIR ${LLVM_ROOT_DIR}/bin ) set( LDC2_BIN_DIR ${PROJECT_BINARY_DIR}/bin ) +set( LDC2_LIB_DIR ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX} ) set( TESTS_IR_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) if(CMAKE_SIZEOF_VOID_P EQUAL 8) diff --git a/tests/codegen/dcompute_cl_addrspaces.d b/tests/codegen/dcompute_cl_addrspaces.d index ca19845289..f43ddfc173 100644 --- a/tests/codegen/dcompute_cl_addrspaces.d +++ b/tests/codegen/dcompute_cl_addrspaces.d @@ -1,5 +1,6 @@ // REQUIRES: target_SPIRV -// RUN: %ldc -c -mdcompute-targets=ocl-220 -m64 -output-ll -output-o %s && FileCheck %s --check-prefix=LL < kernels_ocl220_64.ll && llvm-spirv -to-text kernels_ocl220_64.spv && FileCheck %s --check-prefix=SPT < kernels_ocl220_64.spt +// RUN: %ldc -c -mdcompute-targets=ocl-220 -m64 -output-ll -output-o %s && FileCheck %s --check-prefix=LL < kernels_ocl220_64.ll \ +// RUN: && %llvm-spirv -to-text kernels_ocl220_64.spv && FileCheck %s --check-prefix=SPT < kernels_ocl220_64.spt @compute(CompileFor.deviceOnly) module dcompute_cl_addrspaces; import ldc.dcompute; diff --git a/tests/lit.site.cfg.in b/tests/lit.site.cfg.in index f244b97dab..388eb1cf09 100644 --- a/tests/lit.site.cfg.in +++ b/tests/lit.site.cfg.in @@ -13,6 +13,7 @@ config.ldc2_bin = "@LDC2_BIN@" config.ldcprofdata_bin = "@LDCPROFDATA_BIN@" config.ldcprunecache_bin = "@LDCPRUNECACHE_BIN@" config.ldc2_bin_dir = "@LDC2_BIN_DIR@" +config.ldc2_lib_dir = "@LDC2_LIB_DIR@" config.test_source_root = "@TESTS_IR_DIR@" config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" config.llvm_version = @LDC_LLVM_VER@ @@ -95,10 +96,6 @@ config.target_triple = '(unused)' # test_exec_root: The root path where tests should be run. config.test_exec_root = os.path.dirname(__file__) -# add LLVM tools bin dir to the path -path = os.path.pathsep.join( (config.llvm_tools_dir, config.environment['PATH']) ) -config.environment['PATH'] = path - # add test root dir to the path (FileCheck might sit there) path = os.path.pathsep.join( (config.test_source_root, config.environment['PATH']) ) config.environment['PATH'] = path @@ -112,6 +109,7 @@ config.environment['PATH'] = path config.substitutions.append( ('%ldc', config.ldc2_bin) ) config.substitutions.append( ('%profdata', config.ldcprofdata_bin) ) config.substitutions.append( ('%prunecache', config.ldcprunecache_bin) ) +config.substitutions.append( ('%llvm-spirv', os.path.join(config.llvm_tools_dir, 'llvm-spirv')) ) # Add platform-dependent file extension substitutions if (platform.system() == 'Windows'): diff --git a/tests/sanitizers/asan_stackoverflow.d b/tests/sanitizers/asan_stackoverflow.d new file mode 100644 index 0000000000..af32e5fb63 --- /dev/null +++ b/tests/sanitizers/asan_stackoverflow.d @@ -0,0 +1,26 @@ +// Test stack overflow detection with AddressSanitizer + +// REQUIRES: ASan + +// RUN: %ldc -g -fsanitize=address %s -of=%t%exe +// RUN: not %t%exe 2>&1 | FileCheck %s + +void foo(int* arr) +{ + // CHECK: stack-buffer-overflow + // CHECK: WRITE of size 4 + // CHECK-NEXT: #0 {{.*}} in {{.*foo.*}} {{.*}}asan_stackoverflow.d:[[@LINE+1]] + arr[10] = 1; +} + +// CHECK: Address {{.*}} is located in stack of +// CHECK-NEXT: #0 {{.*}} in {{.*main.*}} {{.*}}asan_stackoverflow.d:[[@LINE+1]] +void main() +{ + // TODO: add test for the name of the variable that is overflown. Right now we get this message: + //[32, 72) '' <== Memory access at offset 72 overflows this variable + // C HECK: 'a'{{.*}} <== {{.*}} overflows this variable + int[10] a; + int b; + foo(&a[0]); +} diff --git a/tests/sanitizers/lit.local.cfg b/tests/sanitizers/lit.local.cfg new file mode 100644 index 0000000000..7a7a6edec6 --- /dev/null +++ b/tests/sanitizers/lit.local.cfg @@ -0,0 +1,28 @@ +import os +import platform +import re + +# Add "ASan" and "Fuzzer" feature if the runtime library is available +if (platform.system() == 'Darwin') or (platform.system() == 'Linux'): + for file in os.listdir(config.ldc2_lib_dir): + m = re.match('.*asan.*', file) + if m is not None: + config.available_features.add('ASan') + continue + m = re.match('.*Fuzzer.*', file) + if m is not None: + config.available_features.add('Fuzzer') + continue +if 'ASan' in config.available_features: + # On Darwin, ASan defaults to `abort_on_error=1`, which would make tests run + # much slower. Let's override this and run lit tests with 'abort_on_error=0'. + # Also, make sure we do not overwhelm the syslog while testing. + config.environment['ASAN_OPTIONS'] = 'abort_on_error=0:log_to_syslog=0' + +# Note: To get line numbers in stack traces on Darwin, we need to run dsymutil on the binary, +# because llvm-symbolizer does not look at the object file for debug info. +# However, when llvm-symbolizer is not on the path we do get nice line information in the stack trace. +# But... on Linux, we _do_ need llvm-symbolizer on the path... +if (platform.system() == 'Linux'): + path = os.path.pathsep.join( (config.environment['PATH'], config.llvm_tools_dir) ) + config.environment['PATH'] = path