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/TestCases/Linux | |
| parent | ca9211ecdede9bdedb812b2243a4abdb8dacd1b9 (diff) | |
Notes
Diffstat (limited to 'test/asan/TestCases/Linux')
20 files changed, 418 insertions, 35 deletions
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 |
