aboutsummaryrefslogtreecommitdiff
path: root/test/asan
diff options
context:
space:
mode:
Diffstat (limited to 'test/asan')
-rw-r--r--test/asan/CMakeLists.txt9
-rw-r--r--test/asan/TestCases/Darwin/interface_symbols_darwin.c82
-rw-r--r--test/asan/TestCases/Darwin/malloc_set_zone_name-mprotect.cc1
-rw-r--r--test/asan/TestCases/Darwin/scribble.cc58
-rw-r--r--test/asan/TestCases/Darwin/suppressions-darwin.cc1
-rw-r--r--test/asan/TestCases/Darwin/suppressions-sandbox.cc1
-rw-r--r--test/asan/TestCases/Linux/asan_dlopen_test.cc2
-rw-r--r--test/asan/TestCases/Linux/clang_gcc_abi.cc2
-rw-r--r--test/asan/TestCases/Linux/coverage-missing.cc22
-rw-r--r--test/asan/TestCases/Linux/interface_symbols_linux.c77
-rw-r--r--test/asan/TestCases/Linux/memmem_test.cc4
-rw-r--r--test/asan/TestCases/Linux/print_memory_profile_test.cc26
-rw-r--r--test/asan/TestCases/Linux/release_to_os_test.cc4
-rw-r--r--test/asan/TestCases/Linux/swapcontext_annotation.cc9
-rw-r--r--test/asan/TestCases/Linux/thread_local_quarantine_pthread_join.cc56
-rw-r--r--test/asan/TestCases/Linux/thread_local_quarantine_size_kb.cc38
-rw-r--r--test/asan/TestCases/Posix/asan-sigbus.cpp40
-rw-r--r--test/asan/TestCases/Posix/closed-fds.cc3
-rw-r--r--test/asan/TestCases/Posix/coverage-maybe-open-file.cc3
-rw-r--r--test/asan/TestCases/Posix/coverage-sandboxing.cc6
-rw-r--r--test/asan/TestCases/Posix/coverage.cc12
-rw-r--r--test/asan/TestCases/Posix/deep_call_stack.cc5
-rw-r--r--test/asan/TestCases/Posix/fread_fwrite.cc34
-rw-r--r--test/asan/TestCases/Posix/halt_on_error-torture.cc2
-rw-r--r--test/asan/TestCases/Posix/halt_on_error_suppress_equal_pcs.cc4
-rw-r--r--test/asan/TestCases/Posix/stack-use-after-return.cc40
-rw-r--r--test/asan/TestCases/Posix/start-deactivated.cc2
-rw-r--r--test/asan/TestCases/Windows/dll_heap_allocation.cc30
-rw-r--r--test/asan/TestCases/Windows/dll_host.cc30
-rw-r--r--test/asan/TestCases/Windows/dll_intercept_memchr.cc2
-rw-r--r--test/asan/TestCases/Windows/dll_intercept_memcpy.cc2
-rw-r--r--test/asan/TestCases/Windows/dll_intercept_memcpy_indirect.cc2
-rw-r--r--test/asan/TestCases/Windows/dll_intercept_memset.cc2
-rw-r--r--test/asan/TestCases/Windows/dll_noreturn.cc2
-rw-r--r--test/asan/TestCases/Windows/dll_poison_unpoison.cc2
-rw-r--r--test/asan/TestCases/Windows/dll_stack_use_after_return.cc2
-rw-r--r--test/asan/TestCases/Windows/dll_thread_stack_array_left_oob.cc2
-rw-r--r--test/asan/TestCases/Windows/fuse-lld.cc4
-rw-r--r--test/asan/TestCases/Windows/intercept_memcpy.cc2
-rw-r--r--test/asan/TestCases/Windows/intercept_strlen.cc2
-rw-r--r--test/asan/TestCases/Windows/interface_symbols_windows.c51
-rw-r--r--test/asan/TestCases/Windows/stack_array_left_oob.cc2
-rw-r--r--test/asan/TestCases/Windows/stack_array_right_oob.cc2
-rw-r--r--test/asan/TestCases/Windows/stack_use_after_return.cc2
-rw-r--r--test/asan/TestCases/Windows/tls_init.cc2
-rw-r--r--test/asan/TestCases/Windows/wrong_downcast_on_stack.cc2
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs.cc6
-rw-r--r--test/asan/TestCases/non-executable-pc.cpp33
-rw-r--r--test/asan/TestCases/realloc.cc21
-rw-r--r--test/asan/TestCases/stack-buffer-overflow-with-position.cc24
-rw-r--r--test/asan/TestCases/strcasestr-1.c2
-rw-r--r--test/asan/TestCases/strcasestr-2.c2
-rw-r--r--test/asan/TestCases/strcspn-1.c2
-rw-r--r--test/asan/TestCases/strcspn-2.c2
-rw-r--r--test/asan/TestCases/strpbrk-1.c2
-rw-r--r--test/asan/TestCases/strpbrk-2.c2
-rw-r--r--test/asan/TestCases/strspn-1.c2
-rw-r--r--test/asan/TestCases/strspn-2.c2
-rw-r--r--test/asan/TestCases/strstr-1.c2
-rw-r--r--test/asan/TestCases/strstr-2.c2
-rw-r--r--test/asan/TestCases/strtok.c103
-rw-r--r--test/asan/TestCases/use-after-scope-inlined.cc8
-rw-r--r--test/asan/TestCases/use-after-scope.cc4
-rw-r--r--test/asan/Unit/lit.site.cfg.in3
-rw-r--r--test/asan/lit.cfg37
65 files changed, 694 insertions, 253 deletions
diff --git a/test/asan/CMakeLists.txt b/test/asan/CMakeLists.txt
index 637c5b80802c..4b4fdf19d18c 100644
--- a/test/asan/CMakeLists.txt
+++ b/test/asan/CMakeLists.txt
@@ -3,8 +3,8 @@ set(ASAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(ASAN_TESTSUITES)
set(ASAN_DYNAMIC_TESTSUITES)
-# TODO(wwchrome): Re-enable Win64 asan tests when ready.
-# Disable tests for asan Win64 temporarily.
+# FIXME: Shadow memory for 64-bit asan easily exhausts swap on most machines.
+# Find a way to make these tests pass reliably, and re-enable them.
if(OS_NAME MATCHES "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
set(EXCLUDE_FROM_ALL TRUE)
endif()
@@ -22,7 +22,7 @@ endmacro()
set(ASAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
if(NOT COMPILER_RT_STANDALONE_BUILD)
list(APPEND ASAN_TEST_DEPS asan)
- if(WIN32 AND COMPILER_RT_HAS_LLD_SOURCES)
+ if(WIN32 AND COMPILER_RT_HAS_LLD)
list(APPEND ASAN_TEST_DEPS
lld
)
@@ -115,7 +115,8 @@ if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
endif()
endif()
-# TODO(wwchrome): Re-enable the tests for asan Win64 when ready.
+# Reset EXCLUDE_FROM_ALL to its initial value.
+# FIXME: Remove when we run Win64 asan tests.
if(OS_NAME MATCHES "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
set(EXCLUDE_FROM_ALL FALSE)
endif()
diff --git a/test/asan/TestCases/Darwin/interface_symbols_darwin.c b/test/asan/TestCases/Darwin/interface_symbols_darwin.c
index ed5779ebe220..9450575b4ecd 100644
--- a/test/asan/TestCases/Darwin/interface_symbols_darwin.c
+++ b/test/asan/TestCases/Darwin/interface_symbols_darwin.c
@@ -3,62 +3,32 @@
// ../Linux/interface_symbols.c
// RUN: %clang_asan -dead_strip -O2 %s -o %t.exe
-// RUN: rm -f %t.symbols %t.interface
-
+//
+// note: we can not use -D on Darwin.
// RUN: nm -g `%clang_asan %s -fsanitize=address -### 2>&1 | grep "libclang_rt.asan_osx_dynamic.dylib" | sed -e 's/.*"\(.*libclang_rt.asan_osx_dynamic.dylib\)".*/\1/'` \
-// RUN: | grep " T " | sed "s/.* T //" \
-// RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \
-// RUN: | sed -E "s/__asan_version_mismatch_check_v[0-9]+/__asan_version_mismatch_check/" \
-// RUN: | grep -v "__asan_default_options" \
-// RUN: | grep -v "__asan_on_error" > %t.symbols
-
-// RUN: cat %p/../../../../lib/asan/asan_interface_internal.h \
-// RUN: | sed "s/\/\/.*//" | sed "s/typedef.*//" \
-// RUN: | grep -v "OPTIONAL" \
-// RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \
-// RUN: > %t.interface
-// RUN: echo __asan_report_load1 >> %t.interface
-// RUN: echo __asan_report_load2 >> %t.interface
-// RUN: echo __asan_report_load4 >> %t.interface
-// RUN: echo __asan_report_load8 >> %t.interface
-// RUN: echo __asan_report_load16 >> %t.interface
-// RUN: echo __asan_report_store1 >> %t.interface
-// RUN: echo __asan_report_store2 >> %t.interface
-// RUN: echo __asan_report_store4 >> %t.interface
-// RUN: echo __asan_report_store8 >> %t.interface
-// RUN: echo __asan_report_store16 >> %t.interface
-// RUN: echo __asan_report_load_n >> %t.interface
-// RUN: echo __asan_report_store_n >> %t.interface
-// RUN: echo __asan_report_load1_noabort >> %t.interface
-// RUN: echo __asan_report_load2_noabort >> %t.interface
-// RUN: echo __asan_report_load4_noabort >> %t.interface
-// RUN: echo __asan_report_load8_noabort >> %t.interface
-// RUN: echo __asan_report_load16_noabort >> %t.interface
-// RUN: echo __asan_report_store1_noabort >> %t.interface
-// RUN: echo __asan_report_store2_noabort >> %t.interface
-// RUN: echo __asan_report_store4_noabort >> %t.interface
-// RUN: echo __asan_report_store8_noabort >> %t.interface
-// RUN: echo __asan_report_store16_noabort >> %t.interface
-// RUN: echo __asan_report_load_n_noabort >> %t.interface
-// RUN: echo __asan_report_store_n_noabort >> %t.interface
-// RUN: echo __asan_report_exp_load1 >> %t.interface
-// RUN: echo __asan_report_exp_load2 >> %t.interface
-// RUN: echo __asan_report_exp_load4 >> %t.interface
-// RUN: echo __asan_report_exp_load8 >> %t.interface
-// RUN: echo __asan_report_exp_load16 >> %t.interface
-// RUN: echo __asan_report_exp_store1 >> %t.interface
-// RUN: echo __asan_report_exp_store2 >> %t.interface
-// RUN: echo __asan_report_exp_store4 >> %t.interface
-// RUN: echo __asan_report_exp_store8 >> %t.interface
-// RUN: echo __asan_report_exp_store16 >> %t.interface
-// RUN: echo __asan_report_exp_load_n >> %t.interface
-// RUN: echo __asan_report_exp_store_n >> %t.interface
-// RUN: echo __asan_get_current_fake_stack >> %t.interface
-// RUN: echo __asan_addr_is_in_fake_stack >> %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
-
-// RUN: cat %t.interface | sort -u | diff %t.symbols -
+// RUN: | grep " [TU] " \
+// RUN: | grep -o "\(__asan_\|__ubsan_\|__sancov_\|__sanitizer_\)[^ ]*" \
+// RUN: | grep -v "__sanitizer_syscall" \
+// RUN: | grep -v "__sanitizer_weak_hook" \
+// RUN: | grep -v "__sanitizer_mz" \
+// RUN: | grep -v "__ubsan_handle_dynamic_type_cache_miss" \
+// RUN: | sed -e "s/__asan_version_mismatch_check_v[0-9]+/__asan_version_mismatch_check/" \
+// RUN: > %t.exports
+//
+// RUN: grep -e "INTERFACE_\(WEAK_\)\?FUNCTION" \
+// RUN: %p/../../../../lib/asan/asan_interface.inc \
+// RUN: %p/../../../../lib/ubsan/ubsan_interface.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_common_interface.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_common_interface_posix.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_coverage_interface.inc \
+// RUN: | grep -v "__sanitizer_weak_hook" \
+// RUN: | sed -e "s/.*(//" -e "s/).*//" > %t.imports
+//
+// RUN: cat %t.imports | sort | uniq > %t.imports-sorted
+// RUN: cat %t.exports | sort | uniq > %t.exports-sorted
+//
+// RUN: echo
+// RUN: echo "=== NOTE === If you see a mismatch below, please update sanitizer_interface.inc files."
+// RUN: diff %t.imports-sorted %t.exports-sorted
int main() { return 0; }
diff --git a/test/asan/TestCases/Darwin/malloc_set_zone_name-mprotect.cc b/test/asan/TestCases/Darwin/malloc_set_zone_name-mprotect.cc
index 2c643bc03c52..b9b96ef0504e 100644
--- a/test/asan/TestCases/Darwin/malloc_set_zone_name-mprotect.cc
+++ b/test/asan/TestCases/Darwin/malloc_set_zone_name-mprotect.cc
@@ -47,5 +47,6 @@ int main() {
memset(mem[i], 'a', 8 * (i % kNumIter));
free(mem[i]);
}
+ malloc_destroy_zone(zone);
return 0;
}
diff --git a/test/asan/TestCases/Darwin/scribble.cc b/test/asan/TestCases/Darwin/scribble.cc
new file mode 100644
index 000000000000..0ddee6b5eef5
--- /dev/null
+++ b/test/asan/TestCases/Darwin/scribble.cc
@@ -0,0 +1,58 @@
+// RUN: %clang_asan -O2 %s -o %t
+// RUN: %run %t 2>&1 | FileCheck --check-prefix=CHECK-NOSCRIBBLE %s
+// RUN: env MallocScribble=1 MallocPreScribble=1 %run %t 2>&1 | FileCheck --check-prefix=CHECK-SCRIBBLE %s
+// RUN: %env_asan_opts=max_free_fill_size=4096 %run %t 2>&1 | FileCheck --check-prefix=CHECK-SCRIBBLE %s
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct Isa {
+ const char *class_name;
+};
+
+struct MyClass {
+ long padding;
+ Isa *isa;
+ long data;
+
+ void print_my_class_name();
+};
+
+__attribute__((no_sanitize("address")))
+void MyClass::print_my_class_name() {
+ fprintf(stderr, "this = %p\n", this);
+ fprintf(stderr, "padding = 0x%lx\n", this->padding);
+ fprintf(stderr, "isa = %p\n", this->isa);
+
+ if ((uint32_t)(uintptr_t)this->isa != 0x55555555) {
+ fprintf(stderr, "class name: %s\n", this->isa->class_name);
+ }
+}
+
+int main() {
+ Isa *my_class_isa = (Isa *)malloc(sizeof(Isa));
+ memset(my_class_isa, 0x77, sizeof(Isa));
+ my_class_isa->class_name = "MyClass";
+
+ MyClass *my_object = (MyClass *)malloc(sizeof(MyClass));
+ memset(my_object, 0x88, sizeof(MyClass));
+ my_object->isa = my_class_isa;
+ my_object->data = 42;
+
+ my_object->print_my_class_name();
+ // CHECK-SCRIBBLE: class name: MyClass
+ // CHECK-NOSCRIBBLE: class name: MyClass
+
+ free(my_object);
+
+ my_object->print_my_class_name();
+ // CHECK-NOSCRIBBLE: class name: MyClass
+ // CHECK-SCRIBBLE: isa = {{(0x)?}}{{5555555555555555|55555555}}
+
+ fprintf(stderr, "okthxbai!\n");
+ // CHECK-SCRIBBLE: okthxbai!
+ // CHECK-NOSCRIBBLE: okthxbai!
+ free(my_class_isa);
+}
diff --git a/test/asan/TestCases/Darwin/suppressions-darwin.cc b/test/asan/TestCases/Darwin/suppressions-darwin.cc
index a177c4e17ec4..8c207b102cb0 100644
--- a/test/asan/TestCases/Darwin/suppressions-darwin.cc
+++ b/test/asan/TestCases/Darwin/suppressions-darwin.cc
@@ -27,6 +27,7 @@ int main() {
kCFStringEncodingUTF8, FALSE); // BOOM
fprintf(stderr, "Ignored.\n");
free(a);
+ CFRelease(str);
}
// CHECK-CRASH: AddressSanitizer: heap-buffer-overflow
diff --git a/test/asan/TestCases/Darwin/suppressions-sandbox.cc b/test/asan/TestCases/Darwin/suppressions-sandbox.cc
index ddbad466f7bf..c0b84addaa81 100644
--- a/test/asan/TestCases/Darwin/suppressions-sandbox.cc
+++ b/test/asan/TestCases/Darwin/suppressions-sandbox.cc
@@ -18,6 +18,7 @@ int main() {
kCFStringEncodingUTF8, FALSE); // BOOM
fprintf(stderr, "Ignored.\n");
free(a);
+ CFRelease(str);
}
// CHECK-CRASH: AddressSanitizer: heap-buffer-overflow
diff --git a/test/asan/TestCases/Linux/asan_dlopen_test.cc b/test/asan/TestCases/Linux/asan_dlopen_test.cc
index f1e31b0a0553..5081b7753211 100644
--- a/test/asan/TestCases/Linux/asan_dlopen_test.cc
+++ b/test/asan/TestCases/Linux/asan_dlopen_test.cc
@@ -2,6 +2,8 @@
//
// RUN: %clangxx %s -DRT=\"%shared_libasan\" -o %t -ldl
// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=verify_asan_link_order=true not %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=verify_asan_link_order=false %run %t 2>&1
// REQUIRES: asan-dynamic-runtime
// XFAIL: android
diff --git a/test/asan/TestCases/Linux/clang_gcc_abi.cc b/test/asan/TestCases/Linux/clang_gcc_abi.cc
index 845f4121adcc..79710dc837b9 100644
--- a/test/asan/TestCases/Linux/clang_gcc_abi.cc
+++ b/test/asan/TestCases/Linux/clang_gcc_abi.cc
@@ -3,7 +3,7 @@
// RUN: %clangxx_asan -O2 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
-// REQUIRES: arm-target-arch
+// REQUIRES: arm-target-arch, fast-unwinder-works
// XFAIL: armv7l-unknown-linux-gnueabihf
#include <stdlib.h>
diff --git a/test/asan/TestCases/Linux/coverage-missing.cc b/test/asan/TestCases/Linux/coverage-missing.cc
index 49487d39a15b..16093498fa2c 100644
--- a/test/asan/TestCases/Linux/coverage-missing.cc
+++ b/test/asan/TestCases/Linux/coverage-missing.cc
@@ -8,40 +8,42 @@
// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t
// RUN: %sancov print *.sancov > main.txt
// RUN: rm *.sancov
-// RUN: [ $(cat main.txt | wc -l) == 1 ]
+// RUN: count 1 < main.txt
// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t x
// RUN: %sancov print *.sancov > foo.txt
// RUN: rm *.sancov
-// RUN: [ $(cat foo.txt | wc -l) == 3 ]
+// RUN: count 3 < foo.txt
// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t x x
// RUN: %sancov print *.sancov > bar.txt
// RUN: rm *.sancov
-// RUN: [ $(cat bar.txt | wc -l) == 4 ]
+// RUN: count 4 < bar.txt
// RUN: %sancov missing %t < foo.txt > foo-missing.txt
// RUN: sort main.txt foo-missing.txt -o foo-missing-with-main.txt
// The "missing from foo" set may contain a few bogus PCs from the sanitizer
// runtime, but it must include the entire "bar" code path as a subset. Sorted
// lists can be tested for set inclusion with diff + grep.
-// RUN: ( diff bar.txt foo-missing-with-main.txt || true ) | not grep "^<"
+// RUN: diff bar.txt foo-missing-with-main.txt > %t.log || true
+// RUN: not grep "^<" %t.log
// Second case: coverage from DSO.
// cd %T
// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %dynamiclib -DFOOBAR -shared -fPIC
// RUN: %clangxx_asan -fsanitize-coverage=func %s %dynamiclib -o %t -DMAIN
-// RUN: export LIBNAME=`basename %dynamiclib`
+// RUN: cd ..
// RUN: rm -rf %T/coverage-missing
// RUN: mkdir -p %T/coverage-missing
// RUN: cd %T/coverage-missing
// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t x
-// RUN: %sancov print $LIBNAME.*.sancov > foo.txt
+// RUN: %sancov print %xdynamiclib_filename.*.sancov > foo.txt
// RUN: rm *.sancov
-// RUN: [ $(cat foo.txt | wc -l) == 2 ]
+// RUN: count 2 < foo.txt
// RUN: %env_asan_opts=coverage=1:coverage_dir=%T/coverage-missing %run %t x x
-// RUN: %sancov print $LIBNAME.*.sancov > bar.txt
+// RUN: %sancov print %xdynamiclib_filename.*.sancov > bar.txt
// RUN: rm *.sancov
-// RUN: [ $(cat bar.txt | wc -l) == 3 ]
+// RUN: count 3 < bar.txt
// RUN: %sancov missing %dynamiclib < foo.txt > foo-missing.txt
-// RUN: ( diff bar.txt foo-missing.txt || true ) | not grep "^<"
+// RUN: diff bar.txt foo-missing.txt > %t.log || true
+// RUN: not grep "^<" %t.log
// REQUIRES: x86-target-arch
// XFAIL: android
diff --git a/test/asan/TestCases/Linux/interface_symbols_linux.c b/test/asan/TestCases/Linux/interface_symbols_linux.c
index 2e648575f28c..33fdd5ca1d82 100644
--- a/test/asan/TestCases/Linux/interface_symbols_linux.c
+++ b/test/asan/TestCases/Linux/interface_symbols_linux.c
@@ -1,59 +1,30 @@
// Check the presence of interface symbols in compiled file.
// RUN: %clang_asan -O2 %s -o %t.exe
-// RUN: nm -D %t.exe | grep " T " | sed "s/.* T //" \
-// RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \
-// RUN: | sed -E "s/__asan_version_mismatch_check_v[0-9]+/__asan_version_mismatch_check/" \
-// RUN: | grep -v "__asan_default_options" \
-// RUN: | grep -v "__asan_stack_" \
-// RUN: | grep -v "__asan_on_error" > %t.symbols
-// RUN: cat %p/../../../../lib/asan/asan_interface_internal.h \
-// RUN: | sed "s/\/\/.*//" | sed "s/typedef.*//" \
-// RUN: | grep -v "OPTIONAL" \
-// RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \
-// RUN: > %t.interface
-// RUN: echo __asan_report_load1 >> %t.interface
-// RUN: echo __asan_report_load2 >> %t.interface
-// RUN: echo __asan_report_load4 >> %t.interface
-// RUN: echo __asan_report_load8 >> %t.interface
-// RUN: echo __asan_report_load16 >> %t.interface
-// RUN: echo __asan_report_store1 >> %t.interface
-// RUN: echo __asan_report_store2 >> %t.interface
-// RUN: echo __asan_report_store4 >> %t.interface
-// RUN: echo __asan_report_store8 >> %t.interface
-// RUN: echo __asan_report_store16 >> %t.interface
-// RUN: echo __asan_report_load_n >> %t.interface
-// RUN: echo __asan_report_store_n >> %t.interface
-// RUN: echo __asan_report_load1_noabort >> %t.interface
-// RUN: echo __asan_report_load2_noabort >> %t.interface
-// RUN: echo __asan_report_load4_noabort >> %t.interface
-// RUN: echo __asan_report_load8_noabort >> %t.interface
-// RUN: echo __asan_report_load16_noabort >> %t.interface
-// RUN: echo __asan_report_store1_noabort >> %t.interface
-// RUN: echo __asan_report_store2_noabort >> %t.interface
-// RUN: echo __asan_report_store4_noabort >> %t.interface
-// RUN: echo __asan_report_store8_noabort >> %t.interface
-// RUN: echo __asan_report_store16_noabort >> %t.interface
-// RUN: echo __asan_report_load_n_noabort >> %t.interface
-// RUN: echo __asan_report_store_n_noabort >> %t.interface
-// RUN: echo __asan_report_exp_load1 >> %t.interface
-// RUN: echo __asan_report_exp_load2 >> %t.interface
-// RUN: echo __asan_report_exp_load4 >> %t.interface
-// RUN: echo __asan_report_exp_load8 >> %t.interface
-// RUN: echo __asan_report_exp_load16 >> %t.interface
-// RUN: echo __asan_report_exp_store1 >> %t.interface
-// RUN: echo __asan_report_exp_store2 >> %t.interface
-// RUN: echo __asan_report_exp_store4 >> %t.interface
-// RUN: echo __asan_report_exp_store8 >> %t.interface
-// RUN: echo __asan_report_exp_store16 >> %t.interface
-// RUN: echo __asan_report_exp_load_n >> %t.interface
-// RUN: echo __asan_report_exp_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_alloca_poison >> %t.interface
-// RUN: echo __asan_allocas_unpoison >> %t.interface
-// RUN: cat %t.interface | sort -u | diff %t.symbols -
-
+// RUN: nm -D %t.exe | grep " [TWw] " \
+// RUN: | grep -o "\(__asan_\|__ubsan_\|__sancov_\|__sanitizer_\)[^ ]*" \
+// RUN: | grep -v "__sanitizer_syscall" \
+// RUN: | grep -v "__sanitizer_weak_hook" \
+// RUN: | grep -v "__ubsan_handle_dynamic_type_cache_miss" \
+// RUN: | sed -e "s/__asan_version_mismatch_check_v[0-9]+/__asan_version_mismatch_check/" \
+// RUN: > %t.exports
+//
+// RUN: grep -e "INTERFACE_\(WEAK_\)\?FUNCTION" \
+// RUN: %p/../../../../lib/asan/asan_interface.inc \
+// RUN: %p/../../../../lib/ubsan/ubsan_interface.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_common_interface.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_common_interface_posix.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_coverage_interface.inc \
+// RUN: | grep -v "__sanitizer_weak_hook" \
+// RUN: | sed -e "s/.*(//" -e "s/).*//" > %t.imports
+//
+// RUN: cat %t.imports | sort | uniq > %t.imports-sorted
+// RUN: cat %t.exports | sort | uniq > %t.exports-sorted
+//
+// RUN: echo
+// RUN: echo "=== NOTE === If you see a mismatch below, please update sanitizer_interface.inc files."
+// RUN: diff %t.imports-sorted %t.exports-sorted
+//
// FIXME: nm -D on powerpc somewhy shows ASan interface symbols residing
// in "initialized data section".
// REQUIRES: x86-target-arch,asan-static-runtime
diff --git a/test/asan/TestCases/Linux/memmem_test.cc b/test/asan/TestCases/Linux/memmem_test.cc
index 661381cdd7b7..a838cb56af5a 100644
--- a/test/asan/TestCases/Linux/memmem_test.cc
+++ b/test/asan/TestCases/Linux/memmem_test.cc
@@ -15,10 +15,10 @@ int main(int argc, char **argv) {
// A1: AddressSanitizer: stack-buffer-overflow
// A1: {{#0.*memmem}}
// A1-NEXT: {{#1.*main}}
- // A1: 'a1' <== Memory access at offset
+ // A1: 'a1'{{.*}} <== Memory access at offset
//
// A2: AddressSanitizer: stack-buffer-overflow
// A2: {{#0.*memmem}}
- // A2: 'a2' <== Memory access at offset
+ // A2: 'a2'{{.*}} <== Memory access at offset
return res == NULL;
}
diff --git a/test/asan/TestCases/Linux/print_memory_profile_test.cc b/test/asan/TestCases/Linux/print_memory_profile_test.cc
index 8909ccad08d4..e7896be4059b 100644
--- a/test/asan/TestCases/Linux/print_memory_profile_test.cc
+++ b/test/asan/TestCases/Linux/print_memory_profile_test.cc
@@ -3,8 +3,9 @@
// REQUIRES: leak-detection
//
// RUN: %clangxx_asan %s -o %t
-// RUN: %run %t 100 2>&1 | FileCheck %s --check-prefix=CHECK-100
-// RUN: %run %t 50 2>&1 | FileCheck %s --check-prefix=CHECK-50
+// RUN: %run %t 100 10 2>&1 | FileCheck %s --check-prefix=CHECK-100-10
+// RUN: %run %t 100 1 2>&1 | FileCheck %s --check-prefix=CHECK-100-1
+// RUN: %run %t 50 10 2>&1 | FileCheck %s --check-prefix=CHECK-50-10
#include <sanitizer/common_interface_defs.h>
#include <stdio.h>
@@ -13,7 +14,7 @@
char *sink[1000];
int main(int argc, char **argv) {
- if (argc < 2)
+ if (argc < 3)
return 1;
int idx = 0;
@@ -22,12 +23,17 @@ int main(int argc, char **argv) {
for (int i = 0; i < 28; i++)
sink[idx++] = new char[24000];
- __sanitizer_print_memory_profile(atoi(argv[1]));
+ __sanitizer_print_memory_profile(atoi(argv[1]), atoi(argv[2]));
}
-// CHECK-100: Live Heap Allocations: {{.*}}; showing top 100%
-// CHECK-100: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
-// CHECK-100: 672000 byte(s) ({{.*}}%) in 28 allocation(s)
-// CHECK-50: Live Heap Allocations: {{.*}}; showing top 50%
-// CHECK-50: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
-// CHECK-50-NOT: allocation
+// CHECK-100-10: Live Heap Allocations: {{.*}}; showing top 100% (at most 10 unique contexts)
+// CHECK-100-10: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
+// CHECK-100-10: 672000 byte(s) ({{.*}}%) in 28 allocation(s)
+
+// CHECK-100-1: Live Heap Allocations: {{.*}}; showing top 100% (at most 1 unique contexts)
+// CHECK-100-1: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
+// CHECK-100-1-NOT: allocation
+
+// CHECK-50-10: Live Heap Allocations: {{.*}}; showing top 50% (at most 10 unique contexts)
+// CHECK-50-10: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
+// CHECK-50-10-NOT: allocation
diff --git a/test/asan/TestCases/Linux/release_to_os_test.cc b/test/asan/TestCases/Linux/release_to_os_test.cc
index 26402167d6b1..c85bcbb7f15b 100644
--- a/test/asan/TestCases/Linux/release_to_os_test.cc
+++ b/test/asan/TestCases/Linux/release_to_os_test.cc
@@ -11,6 +11,7 @@
#include <algorithm>
#include <stdint.h>
#include <assert.h>
+#include <random>
#include <sanitizer/asan_interface.h>
@@ -19,9 +20,10 @@ void MallocReleaseStress() {
const size_t kAllocSize = 100;
const size_t kNumIter = 100;
uintptr_t *chunks[kNumChunks] = {0};
+ std::mt19937 r;
for (size_t iter = 0; iter < kNumIter; iter++) {
- std::random_shuffle(chunks, chunks + kNumChunks);
+ std::shuffle(chunks, chunks + kNumChunks, r);
size_t to_replace = rand() % kNumChunks;
for (size_t i = 0; i < kNumChunks; i++) {
if (chunks[i])
diff --git a/test/asan/TestCases/Linux/swapcontext_annotation.cc b/test/asan/TestCases/Linux/swapcontext_annotation.cc
index 56e811942b88..44189c060815 100644
--- a/test/asan/TestCases/Linux/swapcontext_annotation.cc
+++ b/test/asan/TestCases/Linux/swapcontext_annotation.cc
@@ -4,10 +4,11 @@
// RUN: %clangxx_asan -std=c++11 -lpthread -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -std=c++11 -lpthread -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -std=c++11 -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -std=c++11 -lpthread -O0 %s -o %t && %run %t 2>&1 | FileCheck <( seq 60 | xargs -i -- grep LOOPCHECK %s ) --check-prefix LOOPCHECK
-// RUN: %clangxx_asan -std=c++11 -lpthread -O1 %s -o %t && %run %t 2>&1 | FileCheck <( seq 60 | xargs -i -- grep LOOPCHECK %s ) --check-prefix LOOPCHECK
-// RUN: %clangxx_asan -std=c++11 -lpthread -O2 %s -o %t && %run %t 2>&1 | FileCheck <( seq 60 | xargs -i -- grep LOOPCHECK %s ) --check-prefix LOOPCHECK
-// RUN: %clangxx_asan -std=c++11 -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck <( seq 60 | xargs -i -- grep LOOPCHECK %s ) --check-prefix LOOPCHECK
+// RUN: seq 60 | xargs -i -- grep LOOPCHECK %s > %t.checks
+// RUN: %clangxx_asan -std=c++11 -lpthread -O0 %s -o %t && %run %t 2>&1 | FileCheck %t.checks --check-prefix LOOPCHECK
+// RUN: %clangxx_asan -std=c++11 -lpthread -O1 %s -o %t && %run %t 2>&1 | FileCheck %t.checks --check-prefix LOOPCHECK
+// RUN: %clangxx_asan -std=c++11 -lpthread -O2 %s -o %t && %run %t 2>&1 | FileCheck %t.checks --check-prefix LOOPCHECK
+// RUN: %clangxx_asan -std=c++11 -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck %t.checks --check-prefix LOOPCHECK
//
// This test is too subtle to try on non-x86 arch for now.
diff --git a/test/asan/TestCases/Linux/thread_local_quarantine_pthread_join.cc b/test/asan/TestCases/Linux/thread_local_quarantine_pthread_join.cc
new file mode 100644
index 000000000000..8a5bb25ee75c
--- /dev/null
+++ b/test/asan/TestCases/Linux/thread_local_quarantine_pthread_join.cc
@@ -0,0 +1,56 @@
+// Test how creating and joining a lot of threads making only a few allocations
+// each affect total quarantine (and overall heap) size.
+
+// RUN: %clangxx_asan %s -o %t
+// RUN: %env_asan_opts=thread_local_quarantine_size_kb=64:quarantine_size_mb=1:allocator_release_to_os_interval_ms=-1 %run %t 2>&1 | \
+// RUN: FileCheck %s --allow-empty --check-prefix=CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sanitizer/allocator_interface.h>
+
+// Thread local quarantine is merged to the global one when thread exits and
+// this scenario (a few allocations per thread) used to generate a huge overhead
+// of practically empty quarantine batches (one per thread).
+static const size_t kHeapSizeIncrementLimit = 2 << 20;
+static const int kNumThreads = 2048;
+// The allocation size is so small because all we want to test is that
+// quarantine block merging process does not leak memory used for quarantine
+// blocks.
+// TODO(alekseyshl): Add more comprehensive test verifying quarantine size
+// directly (requires quarantine stats exposed in allocator stats and API).
+static const int kAllocSize = 1;
+
+void *ThreadFn(void *unused) {
+ char *temp = new char[kAllocSize];
+ memset(temp, -1, kAllocSize);
+ delete [] (temp);
+ return NULL;
+}
+
+int main() {
+ // Warm up all internal structures.
+ pthread_t t;
+ pthread_create(&t, 0, ThreadFn, 0);
+ pthread_join(t, 0);
+
+ size_t heap_size = __sanitizer_get_heap_size();
+ fprintf(stderr, "Heap size: %zd\n", heap_size);
+
+ for (int i = 0; i < kNumThreads; i++) {
+ pthread_t t;
+ pthread_create(&t, 0, ThreadFn, 0);
+ pthread_join(t, 0);
+
+ size_t new_heap_size = __sanitizer_get_heap_size();
+ }
+
+ size_t new_heap_size = __sanitizer_get_heap_size();
+ fprintf(stderr, "New heap size: %zd\n", new_heap_size);
+ if (new_heap_size - heap_size < kHeapSizeIncrementLimit)
+ fprintf(stderr, "Heap growth is within limits\n");
+}
+
+// CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD: Heap growth is within limits
diff --git a/test/asan/TestCases/Linux/thread_local_quarantine_size_kb.cc b/test/asan/TestCases/Linux/thread_local_quarantine_size_kb.cc
index 24022a140c90..46af1a0e0207 100644
--- a/test/asan/TestCases/Linux/thread_local_quarantine_size_kb.cc
+++ b/test/asan/TestCases/Linux/thread_local_quarantine_size_kb.cc
@@ -1,12 +1,10 @@
// Test thread_local_quarantine_size_kb
// RUN: %clangxx_asan %s -o %t
-// RUN: %env_asan_opts=thread_local_quarantine_size_kb=256:verbosity=1 %run %t 2>&1 | \
-// RUN: FileCheck %s --check-prefix=CHECK-VALUE
-// RUN: %env_asan_opts=thread_local_quarantine_size_kb=64:quarantine_size_mb=64 %run %t 2>&1 | \
+// RUN: %env_asan_opts=thread_local_quarantine_size_kb=64:quarantine_size_mb=64:verbosity=1 %run %t 2>&1 | \
// RUN: FileCheck %s --allow-empty --check-prefix=CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=0:quarantine_size_mb=0 %run %t 2>&1 | \
-// RUN: FileCheck %s --check-prefix=CHECK-QUARANTINE-DISABLED
+// RUN: FileCheck %s --check-prefix=CHECK-QUARANTINE-DISABLED-SMALL-OVERHEAD
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=0:quarantine_size_mb=64 not %run %t 2>&1 | \
// RUN: FileCheck %s --check-prefix=CHECK-FOR-PARAMETER-ERROR
@@ -15,29 +13,33 @@
#include <string.h>
#include <sanitizer/allocator_interface.h>
-// The idea is allocate a lot of small blocks, totaling 5Mb of user memory
-// total, and verify that quarantine does not incur too much memory overhead.
+// The idea is allocate a lot of small blocks, totaling 5Mb of user memory,
+// and verify that quarantine does not incur too much memory overhead.
// There's always an overhead for red zones, shadow memory and such, but
// quarantine accounting should not significantly contribute to that.
+// The zero sized thread local cache is specifically tested since it used to
+// generate a huge overhead of almost empty quarantine batches.
+static const size_t kHeapSizeIncrementLimit = 12 << 20;
static const int kNumAllocs = 20000;
static const int kAllocSize = 256;
-static const size_t kHeapSizeLimit = 12 << 20;
int main() {
- size_t old_heap_size = __sanitizer_get_heap_size();
+ size_t heap_size = __sanitizer_get_heap_size();
+ fprintf(stderr, "Heap size: %zd\n", heap_size);
+
for (int i = 0; i < kNumAllocs; i++) {
- char *g = new char[kAllocSize];
- memset(g, -1, kAllocSize);
- delete [] (g);
+ char *temp = new char[kAllocSize];
+ memset(temp, -1, kAllocSize);
+ delete [] (temp);
}
+
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 (new_heap_size - old_heap_size > kHeapSizeLimit)
- fprintf(stderr, "Heap size limit exceeded");
+ fprintf(stderr, "New heap size: %zd\n", new_heap_size);
+ if (new_heap_size - heap_size < kHeapSizeIncrementLimit)
+ fprintf(stderr, "Heap growth is within limits\n");
}
-// CHECK-VALUE: thread_local_quarantine_size_kb=256K
-// CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD-NOT: Heap size limit exceeded
-// CHECK-QUARANTINE-DISABLED-NOT: Heap size limit exceeded
+// CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD: thread_local_quarantine_size_kb=64K
+// CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD: Heap growth is within limits
+// CHECK-QUARANTINE-DISABLED-SMALL-OVERHEAD: Heap growth is within limits
// CHECK-FOR-PARAMETER-ERROR: thread_local_quarantine_size_kb can be set to 0 only when quarantine_size_mb is set to 0
diff --git a/test/asan/TestCases/Posix/asan-sigbus.cpp b/test/asan/TestCases/Posix/asan-sigbus.cpp
new file mode 100644
index 000000000000..e07392b4cd4b
--- /dev/null
+++ b/test/asan/TestCases/Posix/asan-sigbus.cpp
@@ -0,0 +1,40 @@
+// Check handle_bus flag
+// Defaults to true
+// RUN: %clangxx_asan -std=c++11 %s -o %t
+// RUN: not %run %t %T/file 2>&1 | FileCheck %s -check-prefix=CHECK-BUS
+// RUN: %env_asan_opts=handle_sigbus=false not --crash %run %t %T/file 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+char array[4096];
+int main(int argc, char **argv) {
+ assert(argc > 1);
+ int fd = open(argv[1], O_RDWR | O_CREAT, 0700);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ assert(write(fd, array, sizeof(array)) == sizeof(array));
+
+ // Write some zeroes to the file, then mmap it while it has a 4KiB size
+ char *addr = (char *)mmap(nullptr, sizeof(array), PROT_READ,
+ MAP_FILE | MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED) {
+ perror("mmap");
+ exit(1);
+ }
+
+ // Truncate the file so our memory isn't valid any more
+ assert(ftruncate(fd, 0) == 0);
+
+ // Try to access the memory
+ return addr[42];
+ // CHECK-NOT: DEADLYSIGNAL
+ // CHECK-BUS: DEADLYSIGNAL
+ // CHECK-BUS: ERROR: AddressSanitizer: BUS
+}
diff --git a/test/asan/TestCases/Posix/closed-fds.cc b/test/asan/TestCases/Posix/closed-fds.cc
index b7bca26c305d..75e3216aab5a 100644
--- a/test/asan/TestCases/Posix/closed-fds.cc
+++ b/test/asan/TestCases/Posix/closed-fds.cc
@@ -2,7 +2,8 @@
// symbolizer still works.
// RUN: rm -f %t.log.*
-// RUN: %clangxx_asan -O0 %s -o %t 2>&1 && %env_asan_opts=log_path='"%t.log"':verbosity=2 not %run %t 2>&1
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: %env_asan_opts=log_path='"%t.log"':verbosity=2 not %run %t
// RUN: FileCheck %s --check-prefix=CHECK-FILE < %t.log.*
// FIXME: copy %t.log back from the device and re-enable on Android.
diff --git a/test/asan/TestCases/Posix/coverage-maybe-open-file.cc b/test/asan/TestCases/Posix/coverage-maybe-open-file.cc
index cab3d5770aa5..95f2b5449e83 100644
--- a/test/asan/TestCases/Posix/coverage-maybe-open-file.cc
+++ b/test/asan/TestCases/Posix/coverage-maybe-open-file.cc
@@ -6,7 +6,7 @@
// RUN: mkdir -p %T/coverage-maybe-open-file && cd %T/coverage-maybe-open-file
// RUN: %env_asan_opts=coverage=1 %run %t | FileCheck %s --check-prefix=CHECK-success
// RUN: %env_asan_opts=coverage=0 %run %t | FileCheck %s --check-prefix=CHECK-fail
-// RUN: [ "$(cat test.sancov.packed)" == "test" ]
+// RUN: FileCheck %s < test.sancov.packed -implicit-check-not={{.}} --check-prefix=CHECK-test
// RUN: cd .. && rm -rf %T/coverage-maybe-open-file
#include <stdio.h>
@@ -30,3 +30,4 @@ int main(int argc, char **argv) {
// CHECK-success: SUCCESS
// CHECK-fail: FAIL
+// CHECK-test: {{^}}test{{$}}
diff --git a/test/asan/TestCases/Posix/coverage-sandboxing.cc b/test/asan/TestCases/Posix/coverage-sandboxing.cc
index c4e6bc7eef8a..431dce149525 100644
--- a/test/asan/TestCases/Posix/coverage-sandboxing.cc
+++ b/test/asan/TestCases/Posix/coverage-sandboxing.cc
@@ -12,9 +12,9 @@
// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t a b 2>&1 | FileCheck %s --check-prefix=CHECK-sandbox
// RUN: %sancov unpack coverage_sandboxing_test.sancov.packed
// RUN: cd ..
-// RUN: %sancov print vanilla/`basename %dynamiclib`*.sancov > vanilla.txt
-// RUN: %sancov print sandbox1/`basename %dynamiclib`*.sancov > sandbox1.txt
-// RUN: %sancov print sandbox2/`basename %dynamiclib`*.sancov > sandbox2.txt
+// RUN: %sancov print vanilla/%xdynamiclib_filename*.sancov > vanilla.txt
+// RUN: %sancov print sandbox1/%xdynamiclib_filename*.sancov > sandbox1.txt
+// RUN: %sancov print sandbox2/%xdynamiclib_filename*.sancov > sandbox2.txt
// RUN: diff vanilla.txt sandbox1.txt
// RUN: diff vanilla.txt sandbox2.txt
// RUN: rm -r %T/coverage_sandboxing_test
diff --git a/test/asan/TestCases/Posix/coverage.cc b/test/asan/TestCases/Posix/coverage.cc
index 7c1c4949f60c..3d1dccfbd549 100644
--- a/test/asan/TestCases/Posix/coverage.cc
+++ b/test/asan/TestCases/Posix/coverage.cc
@@ -2,15 +2,15 @@
// RUN: %clangxx_asan -fsanitize-coverage=func %s %ld_flags_rpath_exe -o %t
// RUN: rm -rf %T/coverage && mkdir -p %T/coverage && cd %T/coverage
// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-main
-// RUN: %sancov print `ls coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1
+// RUN: %sancov print coverage.*sancov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1
// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-foo
-// RUN: %sancov print `ls coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2
+// RUN: %sancov print coverage.*sancov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2
// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t bar 2>&1 | FileCheck %s --check-prefix=CHECK-bar
-// RUN: %sancov print `ls *coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2
+// RUN: %sancov print coverage.*sancov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2
// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t foo bar 2>&1 | FileCheck %s --check-prefix=CHECK-foo-bar
-// RUN: %sancov print `ls *coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2
-// RUN: %sancov print `ls *coverage.*sancov | grep '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1
-// RUN: %sancov merge `ls *coverage.*sancov | grep -v '.so'` > merged-cov
+// RUN: %sancov print coverage.*sancov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2
+// RUN: %sancov print libcoverage.*sancov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1
+// RUN: %sancov merge coverage.*sancov > merged-cov
// RUN: %sancov print merged-cov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2
// RUN: %env_asan_opts=coverage=1:verbosity=1 not %run %t foo bar 4 2>&1 | FileCheck %s --check-prefix=CHECK-report
// RUN: %env_asan_opts=coverage=1:verbosity=1 not %run %t foo bar 4 5 2>&1 | FileCheck %s --check-prefix=CHECK-segv
diff --git a/test/asan/TestCases/Posix/deep_call_stack.cc b/test/asan/TestCases/Posix/deep_call_stack.cc
index 18ba563dbd21..2d2b056d638d 100644
--- a/test/asan/TestCases/Posix/deep_call_stack.cc
+++ b/test/asan/TestCases/Posix/deep_call_stack.cc
@@ -1,6 +1,7 @@
// Check that UAR mode can handle very deep recusrion.
-// RUN: %clangxx_asan -O2 %s -o %t && \
-// RUN: (ulimit -s 4096; %env_asan_opts=detect_stack_use_after_return=1 %run %t) 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: ulimit -s 4096
+// RUN: %env_asan_opts=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s
// Also check that use_sigaltstack+verbosity doesn't crash.
// RUN: %env_asan_opts=verbosity=1:use_sigaltstack=1:detect_stack_use_after_return=1 %run %t | FileCheck %s
diff --git a/test/asan/TestCases/Posix/fread_fwrite.cc b/test/asan/TestCases/Posix/fread_fwrite.cc
new file mode 100644
index 000000000000..97d44b7528ba
--- /dev/null
+++ b/test/asan/TestCases/Posix/fread_fwrite.cc
@@ -0,0 +1,34 @@
+// RUN: %clangxx_asan -g %s -o %t
+// RUN: not %t 2>&1 | FileCheck %s --check-prefix=CHECK-FWRITE
+// RUN: not %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-FREAD
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int test_fread() {
+ FILE *f = fopen("/dev/zero", "r");
+ char buf[2];
+ fread(buf, sizeof(buf), 2, f); // BOOM
+ fclose(f);
+ return 0;
+}
+
+int test_fwrite() {
+ FILE *f = fopen("/dev/null", "w");
+ char buf[2];
+ fwrite(buf, sizeof(buf), 2, f); // BOOM
+ return fclose(f);
+}
+
+int main(int argc, char *argv[]) {
+ if (argc > 1)
+ test_fread();
+ else
+ test_fwrite();
+ return 0;
+}
+
+// CHECK-FREAD: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
+// CHECK-FREAD: #{{.*}} in {{(wrap_|__interceptor_)?}}fread
+// CHECK-FWRITE: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
+// CHECK-FWRITE: #{{.*}} in {{(wrap_|__interceptor_)?}}fwrite
diff --git a/test/asan/TestCases/Posix/halt_on_error-torture.cc b/test/asan/TestCases/Posix/halt_on_error-torture.cc
index 5d7eff06e34e..1b26173d713f 100644
--- a/test/asan/TestCases/Posix/halt_on_error-torture.cc
+++ b/test/asan/TestCases/Posix/halt_on_error-torture.cc
@@ -5,7 +5,7 @@
// RUN: rm -f 1.txt
// RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t 1 10 >>1.txt 2>&1
// RUN: FileCheck %s < 1.txt
-// RUN: [ $(grep -c 'ERROR: AddressSanitizer: use-after-poison' 1.txt) -eq 10 ]
+// RUN: grep 'ERROR: AddressSanitizer: use-after-poison' 1.txt | count 10
// RUN: FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt
//
// Collisions are unlikely but still possible so we need the ||.
diff --git a/test/asan/TestCases/Posix/halt_on_error_suppress_equal_pcs.cc b/test/asan/TestCases/Posix/halt_on_error_suppress_equal_pcs.cc
index 98ef851657b7..b9d85ef94b23 100644
--- a/test/asan/TestCases/Posix/halt_on_error_suppress_equal_pcs.cc
+++ b/test/asan/TestCases/Posix/halt_on_error_suppress_equal_pcs.cc
@@ -8,7 +8,7 @@
// Check that we die after reaching different reports number threshold.
// RUN: rm -f %t1.log
// RUN: %env_asan_opts=halt_on_error=false not %run %t 1 >> %t1.log 2>&1
-// RUN: [ $(grep -c 'ERROR: AddressSanitizer: stack-buffer-overflow' %t1.log) -eq 25 ]
+// RUN: grep 'ERROR: AddressSanitizer: stack-buffer-overflow' %t1.log | count 25
//
// Check suppress_equal_pcs=true behavior is equal to default one.
// RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=true %run %t 2>&1 | FileCheck %s
@@ -16,7 +16,7 @@
// Check suppress_equal_pcs=false behavior isn't equal to default one.
// RUN: rm -f %t2.log
// RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t >> %t2.log 2>&1
-// RUN: [ $(grep -c 'ERROR: AddressSanitizer: stack-buffer-overflow' %t2.log) -eq 30 ]
+// RUN: grep 'ERROR: AddressSanitizer: stack-buffer-overflow' %t2.log | count 30
#define ACCESS_ARRAY_FIVE_ELEMENTS(array, i) \
array[i] = i; \
diff --git a/test/asan/TestCases/Posix/stack-use-after-return.cc b/test/asan/TestCases/Posix/stack-use-after-return.cc
index cf114be97d51..822d5be9491e 100644
--- a/test/asan/TestCases/Posix/stack-use-after-return.cc
+++ b/test/asan/TestCases/Posix/stack-use-after-return.cc
@@ -4,7 +4,7 @@
// RUN: %clangxx_asan -O3 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
// RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t
// Regression test for a CHECK failure with small stack size and large frame.
-// RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=65536 && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
+// RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=131072 && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
//
// Test that we can find UAR in a thread other than main:
// RUN: %clangxx_asan -DUseThread -O2 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
@@ -14,8 +14,13 @@
// RUN: %env_asan_opts=detect_stack_use_after_return=1:max_uar_stack_size_log=20:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s
// RUN: %env_asan_opts=detect_stack_use_after_return=1:min_uar_stack_size_log=24:max_uar_stack_size_log=24:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s
-#include <stdio.h>
+// This test runs out of stack on AArch64.
+// UNSUPPORTED: aarch64
+
+#include <limits.h>
#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
#ifndef kSize
# define kSize 1
@@ -48,11 +53,11 @@ void Func2(char *x) {
// CHECK: WRITE of size 1 {{.*}} thread T0
// CHECK: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-2]]
// CHECK: is located in stack of thread T0 at offset
- // CHECK: 'local' <== Memory access at offset {{16|32}} is inside this variable
+ // CHECK: 'local'{{.*}} <== Memory access at offset {{16|32}} is inside this variable
// THREAD: WRITE of size 1 {{.*}} thread T{{[1-9]}}
// THREAD: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-6]]
// THREAD: is located in stack of thread T{{[1-9]}} at offset
- // THREAD: 'local' <== Memory access at offset {{16|32}} is inside this variable
+ // THREAD: 'local'{{.*}} <== Memory access at offset {{16|32}} is inside this variable
// CHECK-20: T0: FakeStack created:{{.*}} stack_size_log: 20
// CHECK-24: T0: FakeStack created:{{.*}} stack_size_log: 24
}
@@ -66,8 +71,31 @@ int main(int argc, char **argv) {
#if UseThread
pthread_attr_t attr;
pthread_attr_init(&attr);
- if (kStackSize > 0)
- pthread_attr_setstacksize(&attr, kStackSize);
+ if (kStackSize > 0) {
+ size_t desired_stack_size = kStackSize;
+ if (desired_stack_size < PTHREAD_STACK_MIN) {
+ desired_stack_size = PTHREAD_STACK_MIN;
+ }
+
+ int ret = pthread_attr_setstacksize(&attr, desired_stack_size);
+ if (ret != 0) {
+ fprintf(stderr, "pthread_attr_setstacksize returned %d\n", ret);
+ abort();
+ }
+
+ size_t stacksize_check;
+ ret = pthread_attr_getstacksize(&attr, &stacksize_check);
+ if (ret != 0) {
+ fprintf(stderr, "pthread_attr_getstacksize returned %d\n", ret);
+ abort();
+ }
+
+ if (stacksize_check != desired_stack_size) {
+ fprintf(stderr, "Unable to set stack size to %d, the stack size is %d.\n",
+ desired_stack_size, stacksize_check);
+ abort();
+ }
+ }
pthread_t t;
pthread_create(&t, &attr, Thread, 0);
pthread_attr_destroy(&attr);
diff --git a/test/asan/TestCases/Posix/start-deactivated.cc b/test/asan/TestCases/Posix/start-deactivated.cc
index b223f04e46a9..2a2aa674c04c 100644
--- a/test/asan/TestCases/Posix/start-deactivated.cc
+++ b/test/asan/TestCases/Posix/start-deactivated.cc
@@ -20,6 +20,8 @@
// XFAIL: arm-linux-gnueabi
+// END.
+
#if !defined(SHARED_LIB)
#include <assert.h>
diff --git a/test/asan/TestCases/Windows/dll_heap_allocation.cc b/test/asan/TestCases/Windows/dll_heap_allocation.cc
new file mode 100644
index 000000000000..b4df9d4f2221
--- /dev/null
+++ b/test/asan/TestCases/Windows/dll_heap_allocation.cc
@@ -0,0 +1,30 @@
+
+// RUN: %clang_cl -LD %s -Fe%t.dll -DHEAP_LIBRARY -MD
+// RUN: %clang_cl %s %t.lib -Fe%t -fsanitize=address -MT
+// RUN: %run %t 2>&1 | FileCheck %s
+
+// Check that ASan does not fail when releasing allocations that occurred within
+// an uninstrumented DLL.
+
+#ifdef HEAP_LIBRARY
+#include <memory>
+#include <windows.h>
+
+std::unique_ptr<int> __declspec(dllexport) myglobal(new int(42));
+BOOL WINAPI DllMain(PVOID h, DWORD reason, PVOID reserved) {
+ return TRUE;
+}
+
+#else
+
+#include <memory>
+extern std::unique_ptr<int> __declspec(dllimport) myglobal;
+int main(int argc, char **argv) {
+ printf("myglobal: %d\n", *myglobal);
+ return 0;
+}
+
+#endif
+
+// CHECK: myglobal: 42
+// CHECK-NOT: ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed
diff --git a/test/asan/TestCases/Windows/dll_host.cc b/test/asan/TestCases/Windows/dll_host.cc
index 6a029c96d4d8..512f930bc34f 100644
--- a/test/asan/TestCases/Windows/dll_host.cc
+++ b/test/asan/TestCases/Windows/dll_host.cc
@@ -7,18 +7,23 @@
// Get the list of ASan wrappers exported by the main module RTL:
// note: The mangling decoration (i.e. @4 )is removed because calling convention
// differ from 32-bit and 64-bit.
-// RUN: dumpbin /EXPORTS %t | grep -o "__asan_wrap[^ ]*" | sed -e s/@.*// > %t.exported_wrappers1
-// FIXME: we should really check the other __asan exports too.
-// RUN: dumpbin /EXPORTS %t | grep -o "__sanitizer_[^ ]*" | sed -e s/@.*// > %t.exported_wrappers2
+// RUN: dumpbin /EXPORTS %t | grep -o "__asan_wrap[^ ]*" | sed -e s/@.*// > %t.exports1
+//
+// The exception handlers differ in 32-bit and 64-bit, so we ignore them:
+// RUN: grep '[E]XPORT:' %s | sed -e 's/.*[E]XPORT: //' > %t.exports2
+// EXPORT: __asan_wrap__except_handler3
+// EXPORT: __asan_wrap__except_handler4
+// EXPORT: __asan_wrap___C_specific_handler
//
// Get the list of ASan wrappers imported by the DLL RTL:
// [BEWARE: be really careful with the sed commands, as this test can be run
// from different environemnts with different shells and seds]
-// RUN: grep INTERCEPT_LIBRARY_FUNCTION %p/../../../../lib/asan/asan_win_dll_thunk.cc | grep -v define | sed -e s/.*(/__asan_wrap_/ | sed -e s/).*// > %t.dll_imports1
-// RUN: grep "^INTERFACE_FUNCTION.*sanitizer" %p/../../../../lib/asan/asan_win_dll_thunk.cc | grep -v define | sed -e s/.*(// | sed -e s/).*// > %t.dll_imports2
+// RUN: grep INTERCEPT_LIBRARY_FUNCTION %p/../../../../lib/asan/asan_win_dll_thunk.cc \
+// RUN: | grep -v define | sed -e s/.*(/__asan_wrap_/ -e s/).*// \
+// RUN: > %t.imports1
//
// Add functions interecepted in asan_malloc.win.cc and asan_win.cc.
-// RUN: grep '[I]MPORT:' %s | sed -e 's/.*[I]MPORT: //' > %t.dll_imports3
+// RUN: grep '[I]MPORT:' %s | sed -e 's/.*[I]MPORT: //' > %t.imports2
// IMPORT: __asan_wrap_HeapAlloc
// IMPORT: __asan_wrap_HeapFree
// IMPORT: __asan_wrap_HeapReAlloc
@@ -26,20 +31,15 @@
// IMPORT: __asan_wrap_CreateThread
// IMPORT: __asan_wrap_RaiseException
// IMPORT: __asan_wrap_RtlRaiseException
+// IMPORT: __asan_wrap_SetUnhandledExceptionFilter
//
-// The exception handlers differ in 32-bit and 64-bit, so we ignore them:
-// RUN: grep '[E]XPORT:' %s | sed -e 's/.*[E]XPORT: //' > %t.exported_wrappers3
-// EXPORT: __asan_wrap__except_handler3
-// EXPORT: __asan_wrap__except_handler4
-// EXPORT: __asan_wrap___C_specific_handler
-//
-// RUN: cat %t.dll_imports1 %t.dll_imports2 %t.dll_imports3 | sort | uniq > %t.dll_imports-sorted
-// RUN: cat %t.exported_wrappers1 %t.exported_wrappers2 %t.exported_wrappers3 | sort | uniq > %t.exported_wrappers-sorted
+// RUN: cat %t.imports1 %t.imports2 | sort | uniq > %t.imports-sorted
+// RUN: cat %t.exports1 %t.exports2 | sort | uniq > %t.exports-sorted
//
// Now make sure the DLL thunk imports everything:
// RUN: echo
// RUN: echo "=== NOTE === If you see a mismatch below, please update asan_win_dll_thunk.cc"
-// RUN: diff %t.dll_imports-sorted %t.exported_wrappers-sorted
+// RUN: diff %t.imports-sorted %t.exports-sorted
// REQUIRES: asan-static-runtime
#include <stdio.h>
diff --git a/test/asan/TestCases/Windows/dll_intercept_memchr.cc b/test/asan/TestCases/Windows/dll_intercept_memchr.cc
index 4f794a212706..6360cec87e5d 100644
--- a/test/asan/TestCases/Windows/dll_intercept_memchr.cc
+++ b/test/asan/TestCases/Windows/dll_intercept_memchr.cc
@@ -22,6 +22,6 @@ int test_function() {
// CHECK-NEXT: test_function {{.*}}dll_intercept_memchr.cc:[[@LINE-5]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame
// CHECK-NEXT: test_function {{.*}}dll_intercept_memchr.cc
-// CHECK: 'buff' <== Memory access at offset {{.*}} overflows this variable
+// CHECK: 'buff'{{.*}} <== Memory access at offset {{.*}} overflows this variable
return 0;
}
diff --git a/test/asan/TestCases/Windows/dll_intercept_memcpy.cc b/test/asan/TestCases/Windows/dll_intercept_memcpy.cc
index 736e6969d521..a5981fa5b2d5 100644
--- a/test/asan/TestCases/Windows/dll_intercept_memcpy.cc
+++ b/test/asan/TestCases/Windows/dll_intercept_memcpy.cc
@@ -27,6 +27,6 @@ int test_function() {
// CHECK-NEXT: test_function {{.*}}dll_intercept_memcpy.cc:[[@LINE-4]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame
// CHECK-NEXT: test_function {{.*}}dll_intercept_memcpy.cc
-// CHECK: 'buff2' <== Memory access at offset {{.*}} overflows this variable
+// CHECK: 'buff2'{{.*}} <== Memory access at offset {{.*}} overflows this variable
return 0;
}
diff --git a/test/asan/TestCases/Windows/dll_intercept_memcpy_indirect.cc b/test/asan/TestCases/Windows/dll_intercept_memcpy_indirect.cc
index 4e28905923cc..f05ee212116b 100644
--- a/test/asan/TestCases/Windows/dll_intercept_memcpy_indirect.cc
+++ b/test/asan/TestCases/Windows/dll_intercept_memcpy_indirect.cc
@@ -29,6 +29,6 @@ int test_function() {
// CHECK-NEXT: test_function {{.*}}dll_intercept_memcpy_indirect.cc:[[@LINE-5]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame
// CHECK-NEXT: test_function {{.*}}dll_intercept_memcpy_indirect.cc
-// CHECK: 'buff2' <== Memory access at offset {{.*}} overflows this variable
+// CHECK: 'buff2'{{.*}} <== Memory access at offset {{.*}} overflows this variable
return 0;
}
diff --git a/test/asan/TestCases/Windows/dll_intercept_memset.cc b/test/asan/TestCases/Windows/dll_intercept_memset.cc
index d4be376f2458..4baa0a1610f9 100644
--- a/test/asan/TestCases/Windows/dll_intercept_memset.cc
+++ b/test/asan/TestCases/Windows/dll_intercept_memset.cc
@@ -27,6 +27,6 @@ int test_function() {
// CHECK-NEXT: test_function {{.*}}dll_intercept_memset.cc:[[@LINE-4]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame
// CHECK-NEXT: test_function {{.*}}dll_intercept_memset.cc
-// CHECK: 'buff' <== Memory access at offset {{.*}} overflows this variable
+// CHECK: 'buff'{{.*}} <== Memory access at offset {{.*}} overflows this variable
return 0;
}
diff --git a/test/asan/TestCases/Windows/dll_noreturn.cc b/test/asan/TestCases/Windows/dll_noreturn.cc
index 8b5e3d005875..2f6f0c755cc1 100644
--- a/test/asan/TestCases/Windows/dll_noreturn.cc
+++ b/test/asan/TestCases/Windows/dll_noreturn.cc
@@ -17,7 +17,7 @@ void noreturn_f() {
//
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset [[OFFSET:.*]] in frame
// CHECK-NEXT: noreturn_f{{.*}}dll_noreturn.cc
-// CHECK: 'buffer' <== Memory access at offset [[OFFSET]] underflows this variable
+// CHECK: 'buffer'{{.*}} <== Memory access at offset [[OFFSET]] underflows this variable
// CHECK-LABEL: SUMMARY
}
diff --git a/test/asan/TestCases/Windows/dll_poison_unpoison.cc b/test/asan/TestCases/Windows/dll_poison_unpoison.cc
index 9b25a126ef6b..6bd58eca2193 100644
--- a/test/asan/TestCases/Windows/dll_poison_unpoison.cc
+++ b/test/asan/TestCases/Windows/dll_poison_unpoison.cc
@@ -30,6 +30,6 @@ int test_function() {
//
// CHECK: [[ADDR]] is located in stack of thread T0 at offset [[OFFSET:.*]] in frame
// CHECK-NEXT: test_function{{.*}}\dll_poison_unpoison.cc
-// CHECK: 'buffer' <== Memory access at offset [[OFFSET]] is inside this variable
+// CHECK: 'buffer'{{.*}} <== Memory access at offset [[OFFSET]] is inside this variable
return 0;
}
diff --git a/test/asan/TestCases/Windows/dll_stack_use_after_return.cc b/test/asan/TestCases/Windows/dll_stack_use_after_return.cc
index 642871846926..b6166d681209 100644
--- a/test/asan/TestCases/Windows/dll_stack_use_after_return.cc
+++ b/test/asan/TestCases/Windows/dll_stack_use_after_return.cc
@@ -22,7 +22,7 @@ int test_function() {
//
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset [[OFFSET:.*]] in frame
// CHECK-NEXT: #0 {{.*}} foo{{.*}}dll_stack_use_after_return.cc
-// CHECK: 'stack_buffer' <== Memory access at offset [[OFFSET]] is inside this variable
+// CHECK: 'stack_buffer'{{.*}} <== Memory access at offset [[OFFSET]] is inside this variable
return 0;
}
diff --git a/test/asan/TestCases/Windows/dll_thread_stack_array_left_oob.cc b/test/asan/TestCases/Windows/dll_thread_stack_array_left_oob.cc
index dc7c7c6ad7e2..75a094e548cd 100644
--- a/test/asan/TestCases/Windows/dll_thread_stack_array_left_oob.cc
+++ b/test/asan/TestCases/Windows/dll_thread_stack_array_left_oob.cc
@@ -16,7 +16,7 @@ DWORD WINAPI thread_proc(void *context) {
// CHECK: Address [[ADDR]] is located in stack of thread T1 at offset [[OFFSET:.*]] in frame
// CHECK-NEXT: thread_proc{{.*}}dll_thread_stack_array_left_oob.cc
//
-// CHECK: 'stack_buffer' <== Memory access at offset [[OFFSET]] underflows this variable
+// CHECK: 'stack_buffer'{{.*}} <== Memory access at offset [[OFFSET]] underflows this variable
return 0;
}
diff --git a/test/asan/TestCases/Windows/fuse-lld.cc b/test/asan/TestCases/Windows/fuse-lld.cc
index 76c36d828fb7..7fa5d4e8a80a 100644
--- a/test/asan/TestCases/Windows/fuse-lld.cc
+++ b/test/asan/TestCases/Windows/fuse-lld.cc
@@ -5,8 +5,8 @@
// FIXME: Use -fuse-ld=lld after the old COFF linker is removed.
// FIXME: Test will fail until we add flags for requesting dwarf or cv.
// RUNX: %clangxx_asan -O2 %s -o %t.exe -fuse-ld=lld -Wl,-debug
-// RUN: %clangxx_asan -c -O2 %s -o %t.o -gdwarf
-// RUN: lld-link %t.o -out:%t.exe -debug -defaultlib:libcmt %asan_lib %asan_cxx_lib
+// RUN: %clangxx_asan -c -O2 %s -o %t.o -g -gdwarf
+// RUN: lld-link %t.o -out:%t.exe -debug -nopdb -defaultlib:libcmt %asan_lib %asan_cxx_lib
// RUN: not %run %t.exe 2>&1 | FileCheck %s
#include <stdlib.h>
diff --git a/test/asan/TestCases/Windows/intercept_memcpy.cc b/test/asan/TestCases/Windows/intercept_memcpy.cc
index 6e45e7fc6b30..d71333d0b77d 100644
--- a/test/asan/TestCases/Windows/intercept_memcpy.cc
+++ b/test/asan/TestCases/Windows/intercept_memcpy.cc
@@ -27,5 +27,5 @@ int main() {
// CHECK-NEXT: main {{.*}}intercept_memcpy.cc:[[@LINE-5]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame
// CHECK-NEXT: #0 {{.*}} main
-// CHECK: 'buff2' <== Memory access at offset {{.*}} overflows this variable
+// CHECK: 'buff2'{{.*}} <== Memory access at offset {{.*}} overflows this variable
}
diff --git a/test/asan/TestCases/Windows/intercept_strlen.cc b/test/asan/TestCases/Windows/intercept_strlen.cc
index 928a286bedfa..938e6c9b5bac 100644
--- a/test/asan/TestCases/Windows/intercept_strlen.cc
+++ b/test/asan/TestCases/Windows/intercept_strlen.cc
@@ -22,6 +22,6 @@ int main() {
// CHECK-NEXT: main {{.*}}intercept_strlen.cc:[[@LINE-5]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame
// CHECK-NEXT: main {{.*}}intercept_strlen.cc
-// CHECK: 'str' <== Memory access at offset {{.*}} overflows this variable
+// CHECK: 'str'{{.*}} <== Memory access at offset {{.*}} overflows this variable
return len < 6;
}
diff --git a/test/asan/TestCases/Windows/interface_symbols_windows.c b/test/asan/TestCases/Windows/interface_symbols_windows.c
new file mode 100644
index 000000000000..a08f358726d7
--- /dev/null
+++ b/test/asan/TestCases/Windows/interface_symbols_windows.c
@@ -0,0 +1,51 @@
+// Check that the interface exported by asan static lib matches the list of
+// functions mentioned in sanitizer_interface.inc.
+//
+// Just make sure we can compile this.
+// RUN: %clang_cl_asan -O0 %s -Fe%t
+//
+// note: The mangling decoration (i.e. @4 )is removed because calling convention
+// differ from 32-bit and 64-bit.
+//
+// RUN: dumpbin /EXPORTS %t | sed "s/=.*//" \
+// RUN: | grep -o "\(__asan_\|__ubsan_\|__sanitizer_\|__sancov_\)[^ ]*" \
+// RUN: | grep -v "__asan_wrap" \
+// RUN: | sed -e s/@.*// > %t.exports
+//
+// [BEWARE: be really careful with the sed commands, as this test can be run
+// from different environemnts with different shells and seds]
+//
+// RUN: grep -e "INTERFACE_FUNCTION" \
+// RUN: %p/../../../../lib/asan/asan_interface.inc \
+// RUN: %p/../../../../lib/ubsan/ubsan_interface.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_common_interface.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_coverage_interface.inc \
+// RUN: | sed -e "s/.*(//" -e "s/).*//" > %t.imports1
+//
+// RUN: grep -e "INTERFACE_WEAK_FUNCTION" \
+// RUN: %p/../../../../lib/asan/asan_interface.inc \
+// RUN: %p/../../../../lib/ubsan/ubsan_interface.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_common_interface.inc \
+// RUN: %p/../../../../lib/sanitizer_common/sanitizer_coverage_interface.inc \
+// RUN: | sed -e "s/.*(//" -e "s/).*/__dll/" > %t.imports2
+//
+// Add functions not included in the interface lists:
+// RUN: grep '[I]MPORT:' %s | sed -e 's/.*[I]MPORT: //' > %t.imports3
+// IMPORT: __asan_shadow_memory_dynamic_address
+// IMPORT: __asan_get_shadow_memory_dynamic_address
+// IMPORT: __asan_option_detect_stack_use_after_return
+// IMPORT: __asan_should_detect_stack_use_after_return
+// IMPORT: __asan_set_seh_filter
+// IMPORT: __asan_unhandled_exception_filter
+// IMPORT: __asan_test_only_reported_buggy_pointer
+//
+// RUN: cat %t.imports1 %t.imports2 %t.imports3 | sort | uniq > %t.imports-sorted
+// RUN: cat %t.exports | sort | uniq > %t.exports-sorted
+//
+// Now make sure the DLL thunk imports everything:
+// RUN: echo
+// RUN: echo "=== NOTE === If you see a mismatch below, please update interface.inc files."
+// RUN: diff %t.imports-sorted %t.exports-sorted
+// REQUIRES: asan-static-runtime
+
+int main() { return 0; }
diff --git a/test/asan/TestCases/Windows/stack_array_left_oob.cc b/test/asan/TestCases/Windows/stack_array_left_oob.cc
index 845a1f33261f..8d601fc8d42f 100644
--- a/test/asan/TestCases/Windows/stack_array_left_oob.cc
+++ b/test/asan/TestCases/Windows/stack_array_left_oob.cc
@@ -12,5 +12,5 @@ int main() {
// CHECK-NEXT: {{#0 .* main .*stack_array_left_oob.cc}}:[[@LINE-3]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset [[OFFSET:.*]] in frame
// CHECK-NEXT: {{#0 .* main .*stack_array_left_oob.cc}}
-// CHECK: 'buffer' <== Memory access at offset [[OFFSET]] underflows this variable
+// CHECK: 'buffer'{{.*}} <== Memory access at offset [[OFFSET]] underflows this variable
}
diff --git a/test/asan/TestCases/Windows/stack_array_right_oob.cc b/test/asan/TestCases/Windows/stack_array_right_oob.cc
index a370246aa072..721834d1ad27 100644
--- a/test/asan/TestCases/Windows/stack_array_right_oob.cc
+++ b/test/asan/TestCases/Windows/stack_array_right_oob.cc
@@ -12,5 +12,5 @@ int main() {
// CHECK-NEXT: {{#0 .* main .*stack_array_right_oob.cc}}:[[@LINE-3]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset [[OFFSET:.*]] in frame
// CHECK-NEXT: {{#0 .* main .*stack_array_right_oob.cc}}
-// CHECK: 'buffer' <== Memory access at offset [[OFFSET]] overflows this variable
+// CHECK: 'buffer'{{.*}} <== Memory access at offset [[OFFSET]] overflows this variable
}
diff --git a/test/asan/TestCases/Windows/stack_use_after_return.cc b/test/asan/TestCases/Windows/stack_use_after_return.cc
index 9c31922af1de..ca1c142af21d 100644
--- a/test/asan/TestCases/Windows/stack_use_after_return.cc
+++ b/test/asan/TestCases/Windows/stack_use_after_return.cc
@@ -18,5 +18,5 @@ int main() {
// CHECK: is located in stack of thread T0 at offset [[OFFSET:.*]] in frame
// CHECK-NEXT: {{#0 0x.* in foo.*stack_use_after_return.cc}}
//
-// CHECK: 'stack_buffer' <== Memory access at offset [[OFFSET]] is inside this variable
+// CHECK: 'stack_buffer'{{.*}} <== Memory access at offset [[OFFSET]] is inside this variable
}
diff --git a/test/asan/TestCases/Windows/tls_init.cc b/test/asan/TestCases/Windows/tls_init.cc
index c29c4a377834..a8569f8025c8 100644
--- a/test/asan/TestCases/Windows/tls_init.cc
+++ b/test/asan/TestCases/Windows/tls_init.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_cl_asan %s -Fe%t.exe
+// RUN: %clang_cl_asan %s -Fe%t.exe /MD
// RUN: %run %t.exe | FileCheck %s
// CHECK: my_thread_callback
diff --git a/test/asan/TestCases/Windows/wrong_downcast_on_stack.cc b/test/asan/TestCases/Windows/wrong_downcast_on_stack.cc
index 2859ecc521d2..7848cf3be92a 100644
--- a/test/asan/TestCases/Windows/wrong_downcast_on_stack.cc
+++ b/test/asan/TestCases/Windows/wrong_downcast_on_stack.cc
@@ -20,7 +20,7 @@ int main(void) {
// CHECK-NEXT: {{#0 0x[0-9a-f]* in main .*wrong_downcast_on_stack.cc}}:[[@LINE-3]]
// CHECK: [[ADDR]] is located in stack of thread T0 at offset [[OFFSET:[0-9]+]] in frame
// CHECK-NEXT: {{#0 0x[0-9a-f]* in main }}
-// CHECK: 'p' <== Memory access at offset [[OFFSET]] overflows this variable
+// CHECK: 'p'{{.*}} <== Memory access at offset [[OFFSET]] overflows this variable
return 0;
}
diff --git a/test/asan/TestCases/invalid-pointer-pairs.cc b/test/asan/TestCases/invalid-pointer-pairs.cc
index b36e6cd9c10a..e1df151d1365 100644
--- a/test/asan/TestCases/invalid-pointer-pairs.cc
+++ b/test/asan/TestCases/invalid-pointer-pairs.cc
@@ -13,10 +13,10 @@ int f(char c, char *p, char *q) {
// [[PTR1:0x[0-9a-f]+]] [[PTR2:0x[0-9a-f]+]]
switch (c) {
case 'g':
- // CMP: #{{[0-9]+ .*}} in f({{char, char\*, char\*|char,char \*,char \*}}) {{.*}}invalid-pointer-pairs.cc:[[@LINE+1]]:14
+ // CMP: #{{[0-9]+ .*}} in f({{char, char\*, char\*|char,char \*,char \*}}) {{.*}}invalid-pointer-pairs.cc:[[@LINE+1]]
return p > q;
case 's':
- // SUB: #{{[0-9]+ .*}} in f({{char, char\*, char\*|char,char \*,char \*}}) {{.*}}invalid-pointer-pairs.cc:[[@LINE+1]]:14
+ // SUB: #{{[0-9]+ .*}} in f({{char, char\*, char\*|char,char \*,char \*}}) {{.*}}invalid-pointer-pairs.cc:[[@LINE+1]]
return p - q;
case 'k': {
// OK-NOT: ERROR
@@ -26,7 +26,7 @@ int f(char c, char *p, char *q) {
case 'f': {
char *p3 = p + 20;
free(p);
- // FREE: #{{[0-9]+ .*}} in f({{char, char\*, char\*|char,char \*,char \*}}) {{.*}}invalid-pointer-pairs.cc:[[@LINE+2]]:14
+ // FREE: #{{[0-9]+ .*}} in f({{char, char\*, char\*|char,char \*,char \*}}) {{.*}}invalid-pointer-pairs.cc:[[@LINE+2]]
// FREE: freed by thread
return p < p3;
}
diff --git a/test/asan/TestCases/non-executable-pc.cpp b/test/asan/TestCases/non-executable-pc.cpp
new file mode 100644
index 000000000000..f8adee613b09
--- /dev/null
+++ b/test/asan/TestCases/non-executable-pc.cpp
@@ -0,0 +1,33 @@
+// RUN: %clangxx_asan %s -o %t
+// RUN: not %run %t 0 2>&1 | FileCheck %s
+// RUN: not %run %t n 2>&1 | FileCheck %s -check-prefix=CHECK -check-prefix=NON_EXEC
+
+// Only Linux and FreeBSD list every memory region in MemoryMappingLayout, for now.
+// REQUIRES: linux || freebsd
+
+#include <assert.h>
+
+typedef void void_f();
+int main(int argc, char **argv) {
+ char *array = new char[42];
+ void_f *func;
+ assert(argc > 1);
+ if (argv[1][0] == '0') {
+ func = (void_f *)0x04;
+ } else {
+ assert(argv[1][0] == 'n');
+ func = (void_f *)array;
+ }
+
+ func();
+ // x86 reports the SEGV with both address=X and pc=X.
+ // 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 X, X+0x8 or X+0x10. The pc is still in main() because it has not
+ // actually made the call when the faulting access occurs.
+ // CHECK: DEADLYSIGNAL
+ // CHECK: {{AddressSanitizer: (SEGV|access-violation).*(address|pc) }}
+ // NON_EXEC: PC is at a non-executable region. Maybe a wild jump?
+ return 0;
+}
diff --git a/test/asan/TestCases/realloc.cc b/test/asan/TestCases/realloc.cc
new file mode 100644
index 000000000000..fcf383b1a737
--- /dev/null
+++ b/test/asan/TestCases/realloc.cc
@@ -0,0 +1,21 @@
+// RUN: %clangxx_asan -O0 %s -o %t
+// Default is true (free on realloc to 0 size)
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=allocator_frees_and_returns_null_on_realloc_zero=true %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=allocator_frees_and_returns_null_on_realloc_zero=false %run %t 2>&1 | FileCheck %s --check-prefix=NO-FREE
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main() {
+ void *p = malloc(42);
+ p = realloc(p, 0);
+ if (p) {
+ // NO-FREE: Allocated something on realloc(p, 0)
+ fprintf(stderr, "Allocated something on realloc(p, 0)\n");
+ } else {
+ // CHECK: realloc(p, 0) returned nullptr
+ fprintf(stderr, "realloc(p, 0) returned nullptr\n");
+ }
+ free(p);
+}
diff --git a/test/asan/TestCases/stack-buffer-overflow-with-position.cc b/test/asan/TestCases/stack-buffer-overflow-with-position.cc
index 88f5825baf42..2a575f7755ff 100644
--- a/test/asan/TestCases/stack-buffer-overflow-with-position.cc
+++ b/test/asan/TestCases/stack-buffer-overflow-with-position.cc
@@ -30,15 +30,15 @@ int main(int argc, char **argv) {
// make sure BBB and CCC are not removed;
return *(short*)(p) + BBB[argc % 2] + CCC[argc % 2];
}
-// CHECK-m2: 'AAA' <== {{.*}}underflows this variable
-// CHECK-m1: 'AAA' <== {{.*}}partially underflows this variable
-// CHECK-9: 'AAA' <== {{.*}}partially overflows this variable
-// CHECK-10: 'AAA' <== {{.*}}overflows this variable
-// CHECK-30: 'BBB' <== {{.*}}underflows this variable
-// CHECK-31: 'BBB' <== {{.*}}partially underflows this variable
-// CHECK-41: 'BBB' <== {{.*}}partially overflows this variable
-// CHECK-42: 'BBB' <== {{.*}}overflows this variable
-// CHECK-62: 'CCC' <== {{.*}}underflows this variable
-// CHECK-63: 'CCC' <== {{.*}}partially underflows this variable
-// CHECK-73: 'CCC' <== {{.*}}partially overflows this variable
-// CHECK-74: 'CCC' <== {{.*}}overflows this variable
+// CHECK-m2: 'AAA'{{.*}} <== {{.*}}underflows this variable
+// CHECK-m1: 'AAA'{{.*}} <== {{.*}}partially underflows this variable
+// CHECK-9: 'AAA'{{.*}} <== {{.*}}partially overflows this variable
+// CHECK-10: 'AAA'{{.*}} <== {{.*}}overflows this variable
+// CHECK-30: 'BBB'{{.*}} <== {{.*}}underflows this variable
+// CHECK-31: 'BBB'{{.*}} <== {{.*}}partially underflows this variable
+// CHECK-41: 'BBB'{{.*}} <== {{.*}}partially overflows this variable
+// CHECK-42: 'BBB'{{.*}} <== {{.*}}overflows this variable
+// CHECK-62: 'CCC'{{.*}} <== {{.*}}underflows this variable
+// CHECK-63: 'CCC'{{.*}} <== {{.*}}partially underflows this variable
+// CHECK-73: 'CCC'{{.*}} <== {{.*}}partially overflows this variable
+// CHECK-74: 'CCC'{{.*}} <== {{.*}}overflows this variable
diff --git a/test/asan/TestCases/strcasestr-1.c b/test/asan/TestCases/strcasestr-1.c
index c38871ea5362..dccfbcde7709 100644
--- a/test/asan/TestCases/strcasestr-1.c
+++ b/test/asan/TestCases/strcasestr-1.c
@@ -19,7 +19,7 @@ int main(int argc, char **argv) {
char s1[4] = "abC";
__asan_poison_memory_region ((char *)&s1[2], 2);
r = strcasestr(s1, s2);
- // CHECK:'s1' <== Memory access at offset {{[0-9]+}} partially overflows this variable
+ // CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
assert(r == s1 + 2);
return 0;
}
diff --git a/test/asan/TestCases/strcasestr-2.c b/test/asan/TestCases/strcasestr-2.c
index 47fd69225de6..70de2dda437d 100644
--- a/test/asan/TestCases/strcasestr-2.c
+++ b/test/asan/TestCases/strcasestr-2.c
@@ -20,6 +20,6 @@ int main(int argc, char **argv) {
__asan_poison_memory_region ((char *)&s2[2], 2);
r = strcasestr(s1, s2);
assert(r == 0);
- // CHECK:'s2' <== Memory access at offset {{[0-9]+}} partially overflows this variable
+ // CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
return 0;
}
diff --git a/test/asan/TestCases/strcspn-1.c b/test/asan/TestCases/strcspn-1.c
index 6cda2e210cba..2a9f7d7fbddf 100644
--- a/test/asan/TestCases/strcspn-1.c
+++ b/test/asan/TestCases/strcspn-1.c
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
char s1[4] = "caB";
__asan_poison_memory_region ((char *)&s1[2], 2);
r = strcspn(s1, s2);
- // CHECK:'s1' <== Memory access at offset {{[0-9]+}} partially overflows this variable
+ // CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
assert(r == 1);
return 0;
}
diff --git a/test/asan/TestCases/strcspn-2.c b/test/asan/TestCases/strcspn-2.c
index 8bb4b8a57eec..a51fb911e802 100644
--- a/test/asan/TestCases/strcspn-2.c
+++ b/test/asan/TestCases/strcspn-2.c
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
char s2[4] = "abc";
__asan_poison_memory_region ((char *)&s2[2], 2);
r = strcspn(s1, s2);
- // CHECK:'s2' <== Memory access at offset {{[0-9]+}} partially overflows this variable
+ // CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
assert(r == 0);
return 0;
}
diff --git a/test/asan/TestCases/strpbrk-1.c b/test/asan/TestCases/strpbrk-1.c
index 626e8777e1ef..eb323267828b 100644
--- a/test/asan/TestCases/strpbrk-1.c
+++ b/test/asan/TestCases/strpbrk-1.c
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
char s1[4] = "cab";
__asan_poison_memory_region ((char *)&s1[2], 2);
r = strpbrk(s1, s2);
- // CHECK:'s1' <== Memory access at offset {{[0-9]+}} partially overflows this variable
+ // CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
assert(r == s1 + 1);
return 0;
}
diff --git a/test/asan/TestCases/strpbrk-2.c b/test/asan/TestCases/strpbrk-2.c
index 29f3150e667f..1f24656dcb58 100644
--- a/test/asan/TestCases/strpbrk-2.c
+++ b/test/asan/TestCases/strpbrk-2.c
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
char s2[4] = "bca";
__asan_poison_memory_region ((char *)&s2[2], 2);
r = strpbrk(s1, s2);
- // CHECK:'s2' <== Memory access at offset {{[0-9]+}} partially overflows this variable
+ // CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
assert(r == s1);
return 0;
}
diff --git a/test/asan/TestCases/strspn-1.c b/test/asan/TestCases/strspn-1.c
index b0c40ea4d725..5ddb14f507ff 100644
--- a/test/asan/TestCases/strspn-1.c
+++ b/test/asan/TestCases/strspn-1.c
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
char s1[4] = "acb";
__asan_poison_memory_region ((char *)&s1[2], 2);
r = strspn(s1, s2);
- // CHECK:'s1' <== Memory access at offset {{[0-9]+}} partially overflows this variable
+ // CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
assert(r == 1);
return 0;
}
diff --git a/test/asan/TestCases/strspn-2.c b/test/asan/TestCases/strspn-2.c
index 4c899108de90..d564ef8aefb9 100644
--- a/test/asan/TestCases/strspn-2.c
+++ b/test/asan/TestCases/strspn-2.c
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
char s2[5] = "abcd";
__asan_poison_memory_region ((char *)&s2[3], 2);
r = strspn(s1, s2);
- // CHECK:'s2' <== Memory access at offset {{[0-9]+}} partially overflows this variable
+ // CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
assert(r >= 2);
return 0;
}
diff --git a/test/asan/TestCases/strstr-1.c b/test/asan/TestCases/strstr-1.c
index 06a8a8a55d99..319cff546d19 100644
--- a/test/asan/TestCases/strstr-1.c
+++ b/test/asan/TestCases/strstr-1.c
@@ -15,7 +15,7 @@ int main(int argc, char **argv) {
char s1[4] = "acb";
__asan_poison_memory_region ((char *)&s1[2], 2);
r = strstr(s1, s2);
- // CHECK:'s1' <== Memory access at offset {{[0-9]+}} {{partially overflows this variable|is inside this variable}}
+ // CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} {{partially overflows this variable|is inside this variable}}
assert(r == s1 + 1);
return 0;
}
diff --git a/test/asan/TestCases/strstr-2.c b/test/asan/TestCases/strstr-2.c
index 8bc6e9902dd0..4d00c6e632bb 100644
--- a/test/asan/TestCases/strstr-2.c
+++ b/test/asan/TestCases/strstr-2.c
@@ -15,7 +15,7 @@ int main(int argc, char **argv) {
char s2[4] = "cab";
__asan_poison_memory_region ((char *)&s2[2], 2);
r = strstr(s1, s2);
- // CHECK:'s2' <== Memory access at offset {{[0-9]+}} partially overflows this variable
+ // CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
assert(r == 0);
return 0;
}
diff --git a/test/asan/TestCases/strtok.c b/test/asan/TestCases/strtok.c
new file mode 100644
index 000000000000..e1eee89ee709
--- /dev/null
+++ b/test/asan/TestCases/strtok.c
@@ -0,0 +1,103 @@
+// RUN: %clang_asan %s -o %t
+
+// Test overflows with strict_string_checks
+
+// RUN: %env_asan_opts=strict_string_checks=true not %run %t test1 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK1
+// RUN: %env_asan_opts=intercept_strtok=false%run %t test1 2>&1
+// RUN: %env_asan_opts=strict_string_checks=true not %run %t test2 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK2
+// RUN: %env_asan_opts=intercept_strtok=false %run %t test2 2>&1
+// RUN: %env_asan_opts=strict_string_checks=true not %run %t test3 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK3
+// RUN: %env_asan_opts=intercept_strtok=false %run %t test3 2>&1
+// RUN: %env_asan_opts=strict_string_checks=true %run %t test4 2>&1
+// RUN: %env_asan_opts=intercept_strtok=false %run %t test4 2>&1
+
+// Test overflows with !strict_string_checks
+// RUN: %env_asan_opts=strict_string_checks=false not %run %t test5 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK5
+// RUN: %env_asan_opts=intercept_strtok=false %run %t test5 2>&1
+// RUN: %env_asan_opts=strict_string_checks=false not %run %t test6 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CHECK6
+// RUN: %env_asan_opts=intercept_strtok=false %run %t test6 2>&1
+
+
+#include <assert.h>
+#include <string.h>
+#include <sanitizer/asan_interface.h>
+
+// Check that we find overflows in the delimiters on the first call
+// with strict_string_checks.
+void test1() {
+ char *token;
+ char s[4] = "abc";
+ char token_delimiter[2] = "b";
+ __asan_poison_memory_region ((char *)&token_delimiter[1], 2);
+ token = strtok(s, token_delimiter);
+ // CHECK1: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
+}
+
+// Check that we find overflows in the delimiters on the second call (str == NULL)
+// with strict_string_checks.
+void test2() {
+ char *token;
+ char s[4] = "abc";
+ char token_delimiter[2] = "b";
+ token = strtok(s, token_delimiter);
+ assert(strcmp(token, "a") == 0);
+ __asan_poison_memory_region ((char *)&token_delimiter[1], 2);
+ token = strtok(NULL, token_delimiter);
+ // CHECK2: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
+}
+
+// Check that we find overflows in the string (only on the first call) with strict_string_checks.
+void test3() {
+ char *token;
+ char s[4] = "abc";
+ char token_delimiter[2] = "b";
+ __asan_poison_memory_region ((char *)&s[3], 2);
+ token = strtok(s, token_delimiter);
+ // CHECK3: 's'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
+}
+
+// Check that we do not crash when strtok returns NULL with strict_string_checks.
+void test4() {
+ char *token;
+ char s[] = "";
+ char token_delimiter[] = "a";
+ token = strtok(s, token_delimiter);
+ assert(token == NULL);
+}
+
+// Check that we find overflows in the string (only on the first call) with !strict_string_checks.
+void test5() {
+ char *token;
+ char s[4] = "abc";
+ char token_delimiter[2] = "d";
+ __asan_poison_memory_region ((char *)&s[2], 2);
+ __asan_poison_memory_region ((char *)&token_delimiter[1], 2);
+ token = strtok(s, token_delimiter);
+ // CHECK5: 's'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
+}
+
+// Check that we find overflows in the delimiters (only on the first call) with !strict_string_checks.
+void test6() {
+ char *token;
+ char s[4] = "abc";
+ char token_delimiter[1] = {'d'};
+ __asan_poison_memory_region ((char *)&token_delimiter[1], 2);
+ token = strtok(s, &token_delimiter[1]);
+ // CHECK6: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} overflows this variable
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) return 1;
+ if (!strcmp(argv[1], "test1")) test1();
+ if (!strcmp(argv[1], "test2")) test2();
+ if (!strcmp(argv[1], "test3")) test3();
+ if (!strcmp(argv[1], "test4")) test4();
+ if (!strcmp(argv[1], "test5")) test5();
+ if (!strcmp(argv[1], "test6")) test6();
+ return 0;
+}
diff --git a/test/asan/TestCases/use-after-scope-inlined.cc b/test/asan/TestCases/use-after-scope-inlined.cc
index 98a455cbc0c7..bed9814c8b70 100644
--- a/test/asan/TestCases/use-after-scope-inlined.cc
+++ b/test/asan/TestCases/use-after-scope-inlined.cc
@@ -21,8 +21,8 @@ int main(int argc, char *argv[]) {
// CHECK: READ of size 4 at 0x{{.*}} thread T0
// CHECK: #0 0x{{.*}} in main
// CHECK: {{.*}}use-after-scope-inlined.cc:[[@LINE-4]]
- // CHECK: Address 0x{{.*}} is located in stack of thread T0 at offset
- // CHECK: [[OFFSET:[^ ]*]] in frame
- // CHECK: main
- // CHECK: {{\[}}[[OFFSET]], {{.*}}) 'x.i:[[@LINE-15]]'
+ // CHECK: Address 0x{{.*}} is located in stack of thread T0 at offset [[OFFSET:[^ ]*]] in frame
+ // CHECK: {{.*}} in main
+ // CHECK: This frame has
+ // CHECK: {{\[}}[[OFFSET]], {{.*}}) 'x.i' (line [[@LINE-15]])
}
diff --git a/test/asan/TestCases/use-after-scope.cc b/test/asan/TestCases/use-after-scope.cc
index d92dae6572ce..4c5998abe20a 100644
--- a/test/asan/TestCases/use-after-scope.cc
+++ b/test/asan/TestCases/use-after-scope.cc
@@ -1,6 +1,10 @@
// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && \
// RUN: not %run %t 2>&1 | FileCheck %s
+// -fsanitize-address-use-after-scope is now on by default:
+// RUN: %clangxx_asan -O1 %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
+
volatile int *p = 0;
int main() {
diff --git a/test/asan/Unit/lit.site.cfg.in b/test/asan/Unit/lit.site.cfg.in
index 55631a6d927f..1c59a6bad233 100644
--- a/test/asan/Unit/lit.site.cfg.in
+++ b/test/asan/Unit/lit.site.cfg.in
@@ -27,3 +27,6 @@ config.test_source_root = config.test_exec_root
# Set LD_LIBRARY_PATH to pick dynamic runtime up properly.
push_ld_library_path(config, config.compiler_rt_libdir)
+
+if config.host_os == 'Darwin':
+ config.parallelism_group = config.darwin_sanitizer_parallelism_group_func
diff --git a/test/asan/lit.cfg b/test/asan/lit.cfg
index 7703f5a31b0d..7d684a1ae7a7 100644
--- a/test/asan/lit.cfg
+++ b/test/asan/lit.cfg
@@ -2,6 +2,7 @@
import os
import platform
+import re
import lit.formats
@@ -132,16 +133,22 @@ if config.asan_dynamic:
# Windows-specific tests might also use the clang-cl.exe driver.
if platform.system() == 'Windows':
- clang_cl_asan_cxxflags = ["-fsanitize=address",
- "-Wno-deprecated-declarations",
- "-WX",
- "-D_HAS_EXCEPTIONS=0",
- "-Zi"] + target_cflags
+ clang_cl_cxxflags = ["-Wno-deprecated-declarations",
+ "-WX",
+ "-D_HAS_EXCEPTIONS=0",
+ "-Zi"] + target_cflags
+ clang_cl_asan_cxxflags = ["-fsanitize=address"] + clang_cl_cxxflags
if config.asan_dynamic:
clang_cl_asan_cxxflags.append("-MD")
- clang_invocation = build_invocation(clang_cl_asan_cxxflags)
- clang_cl_invocation = clang_invocation.replace("clang.exe","clang-cl.exe")
- config.substitutions.append( ("%clang_cl_asan ", clang_cl_invocation) )
+
+ clang_cl_invocation = build_invocation(clang_cl_cxxflags)
+ clang_cl_invocation = clang_cl_invocation.replace("clang.exe","clang-cl.exe")
+ config.substitutions.append( ("%clang_cl ", clang_cl_invocation) )
+
+ clang_cl_asan_invocation = build_invocation(clang_cl_asan_cxxflags)
+ clang_cl_asan_invocation = clang_cl_asan_invocation.replace("clang.exe","clang-cl.exe")
+ config.substitutions.append( ("%clang_cl_asan ", clang_cl_asan_invocation) )
+
base_lib = os.path.join(config.compiler_rt_libdir, "clang_rt.asan%%s-%s.lib" % config.target_arch)
config.substitutions.append( ("%asan_lib", base_lib % "") )
config.substitutions.append( ("%asan_cxx_lib", base_lib % "_cxx") )
@@ -196,16 +203,21 @@ elif config.host_os == 'Linux':
config.substitutions.append( ("%ld_flags_rpath_so", '') )
# Must be defined after the substitutions that use %dynamiclib.
-config.substitutions.append( ("%dynamiclib", '%T/lib%xdynamiclib_namespec.so') )
-config.substitutions.append( ("%xdynamiclib_namespec", '$(basename %t).dynamic') )
+config.substitutions.append( ("%dynamiclib", '%T/%xdynamiclib_filename') )
+config.substitutions.append( ("%xdynamiclib_filename", 'lib%xdynamiclib_namespec.so') )
+config.substitutions.append( ("%xdynamiclib_namespec", '%basename_t.dynamic') )
# Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL
# because the test hangs. Adding armhf as we now have two modes.
if config.target_arch != 'arm' and config.target_arch != 'armhf' and config.target_arch != 'aarch64':
config.available_features.add('stable-runtime')
+# Fast unwinder doesn't work with Thumb
+if re.search('mthumb', config.target_cflags) is not None:
+ config.available_features.add('fast-unwinder-works')
+
# Turn on leak detection on 64-bit Linux.
-if config.host_os == 'Linux' and config.target_arch == 'x86_64':
+if config.host_os == 'Linux' and (config.target_arch == 'x86_64' or config.target_arch == 'i386'):
config.available_features.add('leak-detection')
# Set LD_LIBRARY_PATH to pick dynamic runtime up properly.
@@ -241,3 +253,6 @@ else:
# Only run the tests on supported OSs.
if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows']:
config.unsupported = True
+
+if config.host_os == 'Darwin' and config.target_arch in ["x86_64", "x86_64h"]:
+ config.parallelism_group = "darwin-64bit-sanitizer"