aboutsummaryrefslogtreecommitdiff
path: root/lib/asan/lit_tests
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asan/lit_tests')
-rw-r--r--lib/asan/lit_tests/CMakeLists.txt4
-rw-r--r--lib/asan/lit_tests/Darwin/interface_symbols_darwin.c39
-rw-r--r--lib/asan/lit_tests/Darwin/lit.local.cfg9
-rw-r--r--lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc20
-rw-r--r--lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc20
-rw-r--r--lib/asan/lit_tests/Helpers/init-order-atexit-extra.cc16
-rw-r--r--lib/asan/lit_tests/Helpers/initialization-blacklist-extra2.cc4
-rw-r--r--lib/asan/lit_tests/Helpers/initialization-blacklist.txt1
-rw-r--r--lib/asan/lit_tests/Helpers/initialization-constexpr-extra.cc3
-rw-r--r--lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc6
-rw-r--r--lib/asan/lit_tests/Linux/asan_prelink_test.cc28
-rw-r--r--lib/asan/lit_tests/Linux/glob.cc30
-rw-r--r--lib/asan/lit_tests/Linux/glob_test_root/aa0
-rw-r--r--lib/asan/lit_tests/Linux/glob_test_root/ab0
-rw-r--r--lib/asan/lit_tests/Linux/glob_test_root/ba0
-rw-r--r--lib/asan/lit_tests/Linux/heavy_uar_test.cc55
-rw-r--r--lib/asan/lit_tests/Linux/initialization-bug-any-order.cc11
-rw-r--r--lib/asan/lit_tests/Linux/interface_symbols_linux.c (renamed from lib/asan/lit_tests/interface_symbols.c)12
-rw-r--r--lib/asan/lit_tests/Linux/malloc-in-qsort.cc6
-rw-r--r--lib/asan/lit_tests/Linux/malloc_delete_mismatch.cc (renamed from lib/asan/lit_tests/malloc_delete_mismatch.cc)0
-rw-r--r--lib/asan/lit_tests/Linux/overflow-in-qsort.cc6
-rw-r--r--lib/asan/lit_tests/Linux/preinit_test.cc27
-rw-r--r--lib/asan/lit_tests/Linux/rlimit_mmap_test.cc2
-rw-r--r--lib/asan/lit_tests/Linux/swapcontext_test.cc38
-rw-r--r--lib/asan/lit_tests/Linux/syscalls.cc22
-rw-r--r--lib/asan/lit_tests/Linux/time_null_regtest.cc20
-rw-r--r--lib/asan/lit_tests/Linux/zero-base-shadow.cc31
-rw-r--r--lib/asan/lit_tests/SharedLibs/darwin-dummy-shared-lib-so.cc13
-rw-r--r--lib/asan/lit_tests/SharedLibs/init-order-dlopen-so.cc12
-rw-r--r--lib/asan/lit_tests/Unit/lit.cfg5
-rw-r--r--lib/asan/lit_tests/Unit/lit.site.cfg.in9
-rw-r--r--lib/asan/lit_tests/allow_user_segv.cc50
-rw-r--r--lib/asan/lit_tests/default_blacklist.cc3
-rw-r--r--lib/asan/lit_tests/default_options.cc2
-rw-r--r--lib/asan/lit_tests/dlclose-test.cc13
-rw-r--r--lib/asan/lit_tests/double-free.cc18
-rw-r--r--lib/asan/lit_tests/global-demangle.cc18
-rw-r--r--lib/asan/lit_tests/heap-overflow.cc6
-rw-r--r--lib/asan/lit_tests/huge_negative_hea_oob.cc13
-rw-r--r--lib/asan/lit_tests/init-order-atexit.cc31
-rw-r--r--lib/asan/lit_tests/init-order-dlopen.cc52
-rw-r--r--lib/asan/lit_tests/initialization-blacklist.cc29
-rw-r--r--lib/asan/lit_tests/initialization-bug.cc11
-rw-r--r--lib/asan/lit_tests/initialization-constexpr.cc43
-rw-r--r--lib/asan/lit_tests/initialization-nobug.cc53
-rw-r--r--lib/asan/lit_tests/interface_test.cc8
-rw-r--r--lib/asan/lit_tests/invalid-free.cc16
-rw-r--r--lib/asan/lit_tests/large_func_test.cc9
-rw-r--r--lib/asan/lit_tests/lit.cfg21
-rw-r--r--lib/asan/lit_tests/lit.site.cfg.in2
-rw-r--r--lib/asan/lit_tests/log_path_fork_test.cc.disabled (renamed from lib/asan/lit_tests/log_path_fork_test.cc)0
-rw-r--r--lib/asan/lit_tests/malloc_fill.cc22
-rw-r--r--lib/asan/lit_tests/memcmp_strict_test.cc16
-rw-r--r--lib/asan/lit_tests/partial_right.cc17
-rw-r--r--lib/asan/lit_tests/stack-frame-demangle.cc14
-rw-r--r--lib/asan/lit_tests/stack-oob-frames.cc59
-rw-r--r--lib/asan/lit_tests/stack-overflow.cc3
-rw-r--r--lib/asan/lit_tests/strncpy-overflow.cc8
-rw-r--r--lib/asan/lit_tests/throw_call_test.cc45
-rw-r--r--lib/asan/lit_tests/throw_invoke_test.cc50
-rw-r--r--lib/asan/lit_tests/time_interceptor.cc16
-rw-r--r--lib/asan/lit_tests/unaligned_loads_and_stores.cc52
-rw-r--r--lib/asan/lit_tests/use-after-free-right.cc46
-rw-r--r--lib/asan/lit_tests/use-after-free.cc13
-rw-r--r--lib/asan/lit_tests/use-after-poison.cc20
-rw-r--r--lib/asan/lit_tests/use-after-scope-inlined.cc5
-rw-r--r--lib/asan/lit_tests/wait.cc77
67 files changed, 1194 insertions, 116 deletions
diff --git a/lib/asan/lit_tests/CMakeLists.txt b/lib/asan/lit_tests/CMakeLists.txt
index 1609032d4670..d2420b50da83 100644
--- a/lib/asan/lit_tests/CMakeLists.txt
+++ b/lib/asan/lit_tests/CMakeLists.txt
@@ -14,9 +14,9 @@ configure_lit_site_cfg(
if(COMPILER_RT_CAN_EXECUTE_TESTS)
# Run ASan tests only if we're sure we may produce working binaries.
set(ASAN_TEST_DEPS
- clang clang-headers FileCheck count not llvm-nm llvm-symbolizer
+ ${SANITIZER_COMMON_LIT_TEST_DEPS}
${ASAN_RUNTIME_LIBRARIES}
- )
+ asan_blacklist)
set(ASAN_TEST_PARAMS
asan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
)
diff --git a/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c b/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c
new file mode 100644
index 000000000000..3fca6e915324
--- /dev/null
+++ b/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c
@@ -0,0 +1,39 @@
+// Check the presense of interface symbols in the ASan runtime dylib.
+// If you're changing this file, please also change
+// ../Linux/interface_symbols.c
+
+// RUN: %clang -fsanitize=address -dead_strip -O2 %s -o %t.exe
+// RUN: rm -f %t.symbols %t.interface
+
+// RUN: nm -g `otool -L %t.exe | grep "asan_osx_dynamic.dylib" | \
+// RUN: tr -d '\011' | \
+// RUN: sed "s/.dylib.*/.dylib/"` \
+// RUN: | grep " T " | sed "s/.* T //" \
+// RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \
+// RUN: | grep -v "__asan_malloc_hook" \
+// RUN: | grep -v "__asan_free_hook" \
+// RUN: | grep -v "__asan_symbolize" \
+// RUN: | grep -v "__asan_default_options" \
+// RUN: | grep -v "__asan_on_error" > %t.symbols
+
+// RUN: cat %p/../../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: cat %t.interface | sort -u | diff %t.symbols -
+
+int main() { return 0; }
diff --git a/lib/asan/lit_tests/Darwin/lit.local.cfg b/lib/asan/lit_tests/Darwin/lit.local.cfg
new file mode 100644
index 000000000000..a85dfcd24c08
--- /dev/null
+++ b/lib/asan/lit_tests/Darwin/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Darwin']:
+ config.unsupported = True
diff --git a/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc b/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc
new file mode 100644
index 000000000000..40a459fd84db
--- /dev/null
+++ b/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc
@@ -0,0 +1,20 @@
+// Make sure ASan doesn't hang in an exec loop if DYLD_INSERT_LIBRARIES is set.
+// This is a regression test for
+// https://code.google.com/p/address-sanitizer/issues/detail?id=159
+
+// RUN: %clangxx_asan -m64 %s -o %t
+// RUN: %clangxx -m64 %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \
+// RUN: -dynamiclib -o darwin-dummy-shared-lib-so.dylib
+
+// FIXME: the following command line may hang in the case of a regression.
+// RUN: DYLD_INSERT_LIBRARIES=darwin-dummy-shared-lib-so.dylib \
+// RUN: %t 2>&1 | FileCheck %s || exit 1
+#include <stdio.h>
+#include <stdlib.h>
+
+int main() {
+ const char kEnvName[] = "DYLD_INSERT_LIBRARIES";
+ printf("%s=%s\n", kEnvName, getenv(kEnvName));
+ // CHECK: {{DYLD_INSERT_LIBRARIES=.*darwin-dummy-shared-lib-so.dylib.*}}
+ return 0;
+}
diff --git a/lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc b/lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc
new file mode 100644
index 000000000000..cf89949cf942
--- /dev/null
+++ b/lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc
@@ -0,0 +1,20 @@
+// Make sure ASan removes the runtime library from DYLD_INSERT_LIBRARIES before
+// executing other programs.
+
+// RUN: %clangxx_asan -m64 %s -o %t
+// RUN: %clangxx -m64 %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \
+// RUN: -dynamiclib -o darwin-dummy-shared-lib-so.dylib
+
+// Make sure DYLD_INSERT_LIBRARIES doesn't contain the runtime library before
+// execl().
+
+// RUN: %t >/dev/null 2>&1
+// RUN: DYLD_INSERT_LIBRARIES=darwin-dummy-shared-lib-so.dylib \
+// RUN: %t 2>&1 | FileCheck %s || exit 1
+#include <unistd.h>
+int main() {
+ execl("/bin/bash", "/bin/bash", "-c",
+ "echo DYLD_INSERT_LIBRARIES=$DYLD_INSERT_LIBRARIES", NULL);
+ // CHECK: {{DYLD_INSERT_LIBRARIES=.*darwin-dummy-shared-lib-so.dylib.*}}
+ return 0;
+}
diff --git a/lib/asan/lit_tests/Helpers/init-order-atexit-extra.cc b/lib/asan/lit_tests/Helpers/init-order-atexit-extra.cc
new file mode 100644
index 000000000000..e4189d19d099
--- /dev/null
+++ b/lib/asan/lit_tests/Helpers/init-order-atexit-extra.cc
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+class C {
+ public:
+ C() { value = 42; }
+ ~C() { }
+ int value;
+};
+
+C c;
+
+void AccessC() {
+ printf("C value: %d\n", c.value);
+}
+
+int main() { return 0; }
diff --git a/lib/asan/lit_tests/Helpers/initialization-blacklist-extra2.cc b/lib/asan/lit_tests/Helpers/initialization-blacklist-extra2.cc
new file mode 100644
index 000000000000..69455a0a6fc9
--- /dev/null
+++ b/lib/asan/lit_tests/Helpers/initialization-blacklist-extra2.cc
@@ -0,0 +1,4 @@
+int zero_init();
+int badSrcGlobal = zero_init();
+int readBadSrcGlobal() { return badSrcGlobal; }
+
diff --git a/lib/asan/lit_tests/Helpers/initialization-blacklist.txt b/lib/asan/lit_tests/Helpers/initialization-blacklist.txt
index c5f6610937f0..fa4a83667f4b 100644
--- a/lib/asan/lit_tests/Helpers/initialization-blacklist.txt
+++ b/lib/asan/lit_tests/Helpers/initialization-blacklist.txt
@@ -1,2 +1,3 @@
global-init:*badGlobal*
global-init-type:*badNamespace::BadClass*
+global-init-src:*initialization-blacklist-extra2.cc
diff --git a/lib/asan/lit_tests/Helpers/initialization-constexpr-extra.cc b/lib/asan/lit_tests/Helpers/initialization-constexpr-extra.cc
new file mode 100644
index 000000000000..b32466a981b3
--- /dev/null
+++ b/lib/asan/lit_tests/Helpers/initialization-constexpr-extra.cc
@@ -0,0 +1,3 @@
+// Constexpr:
+int getCoolestInteger();
+static int coolest_integer = getCoolestInteger();
diff --git a/lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc b/lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc
index 490b3339054a..886165affd76 100644
--- a/lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc
+++ b/lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc
@@ -4,6 +4,6 @@ static int ab = getAB();
// Function local statics:
int countCalls();
static int one = countCalls();
-// Constexpr:
-int getCoolestInteger();
-static int coolest_integer = getCoolestInteger();
+// Trivial constructor, non-trivial destructor:
+int getStructWithDtorValue();
+static int val = getStructWithDtorValue();
diff --git a/lib/asan/lit_tests/Linux/asan_prelink_test.cc b/lib/asan/lit_tests/Linux/asan_prelink_test.cc
new file mode 100644
index 000000000000..c209c39c8c42
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/asan_prelink_test.cc
@@ -0,0 +1,28 @@
+// Test if asan works with prelink.
+// It does not actually use prelink, but relies on ld's flag -Ttext-segment
+// or gold's flag -Ttext (we try the first flag first, if that fails we
+// try the second flag).
+//
+// RUN: %clangxx_asan -m64 -c %s -o %t.o
+// RUN: %clangxx_asan -m64 -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext-segment=0x3600000000 ||\
+// RUN: %clangxx_asan -m64 -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext=0x3600000000
+// RUN: %clangxx_asan -m64 %t.o %t.so -Wl,-R. -o %t
+// RUN: ASAN_OPTIONS=verbosity=1 %t 2>&1 | FileCheck %s
+
+// REQUIRES: x86_64-supported-target
+#if BUILD_SO
+int G;
+int *getG() {
+ return &G;
+}
+#else
+#include <stdio.h>
+extern int *getG();
+int main(int argc, char **argv) {
+ long p = (long)getG();
+ printf("SO mapped at %lx\n", p & ~0xffffffffUL);
+ *getG() = 0;
+}
+#endif
+// CHECK: 0x003000000000, 0x004fffffffff{{.*}} MidMem
+// CHECK: SO mapped at 3600000000
diff --git a/lib/asan/lit_tests/Linux/glob.cc b/lib/asan/lit_tests/Linux/glob.cc
new file mode 100644
index 000000000000..e05228ff39e3
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/glob.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t %p 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t %p 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t %p 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t %p 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <glob.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <string>
+
+
+int main(int argc, char *argv[]) {
+ std::string path = argv[1];
+ std::string pattern = path + "/glob_test_root/*a";
+ printf("pattern: %s\n", pattern.c_str());
+
+ glob_t globbuf;
+ int res = glob(pattern.c_str(), 0, 0, &globbuf);
+
+ printf("%d %s\n", errno, strerror(errno));
+ assert(res == 0);
+ assert(globbuf.gl_pathc == 2);
+ printf("%zu\n", strlen(globbuf.gl_pathv[0]));
+ printf("%zu\n", strlen(globbuf.gl_pathv[1]));
+ printf("PASS\n");
+ // CHECK: PASS
+ return 0;
+}
diff --git a/lib/asan/lit_tests/Linux/glob_test_root/aa b/lib/asan/lit_tests/Linux/glob_test_root/aa
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/glob_test_root/aa
diff --git a/lib/asan/lit_tests/Linux/glob_test_root/ab b/lib/asan/lit_tests/Linux/glob_test_root/ab
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/glob_test_root/ab
diff --git a/lib/asan/lit_tests/Linux/glob_test_root/ba b/lib/asan/lit_tests/Linux/glob_test_root/ba
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/glob_test_root/ba
diff --git a/lib/asan/lit_tests/Linux/heavy_uar_test.cc b/lib/asan/lit_tests/Linux/heavy_uar_test.cc
new file mode 100644
index 000000000000..c0f4560fb4e7
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/heavy_uar_test.cc
@@ -0,0 +1,55 @@
+// RUN: %clangxx_asan -fsanitize=use-after-return -m64 -O0 %s -o %t && \
+// RUN: %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -fsanitize=use-after-return -m64 -O2 %s -o %t && \
+// RUN: %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -fsanitize=use-after-return -m32 -O2 %s -o %t && \
+// RUN: %t 2>&1 | %symbolize | FileCheck %s
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+__attribute__((noinline))
+char *pretend_to_do_something(char *x) {
+ __asm__ __volatile__("" : : "r" (x) : "memory");
+ return x;
+}
+
+__attribute__((noinline))
+char *LeakStack() {
+ char x[1024];
+ memset(x, 0, sizeof(x));
+ return pretend_to_do_something(x);
+}
+
+template<size_t kFrameSize>
+__attribute__((noinline))
+void RecuriveFunctionWithStackFrame(int depth) {
+ if (depth <= 0) return;
+ char x[kFrameSize];
+ x[0] = depth;
+ pretend_to_do_something(x);
+ RecuriveFunctionWithStackFrame<kFrameSize>(depth - 1);
+}
+
+int main(int argc, char **argv) {
+ int n_iter = argc >= 2 ? atoi(argv[1]) : 1000;
+ int depth = argc >= 3 ? atoi(argv[2]) : 500;
+ for (int i = 0; i < n_iter; i++) {
+ RecuriveFunctionWithStackFrame<10>(depth);
+ RecuriveFunctionWithStackFrame<100>(depth);
+ RecuriveFunctionWithStackFrame<500>(depth);
+ RecuriveFunctionWithStackFrame<1024>(depth);
+ RecuriveFunctionWithStackFrame<2000>(depth);
+ RecuriveFunctionWithStackFrame<5000>(depth);
+ RecuriveFunctionWithStackFrame<10000>(depth);
+ }
+ char *stale_stack = LeakStack();
+ RecuriveFunctionWithStackFrame<1024>(10);
+ stale_stack[100]++;
+ // CHECK: ERROR: AddressSanitizer: stack-use-after-return on address
+ // CHECK: is located in stack of thread T0 at offset 132 in frame
+ // CHECK: in LeakStack(){{.*}}heavy_uar_test.cc:
+ // CHECK: [32, 1056) 'x'
+ return 0;
+}
diff --git a/lib/asan/lit_tests/Linux/initialization-bug-any-order.cc b/lib/asan/lit_tests/Linux/initialization-bug-any-order.cc
index 645fe1c85ed4..4f41dda18128 100644
--- a/lib/asan/lit_tests/Linux/initialization-bug-any-order.cc
+++ b/lib/asan/lit_tests/Linux/initialization-bug-any-order.cc
@@ -1,12 +1,13 @@
// Test to make sure basic initialization order errors are caught.
// Check that on Linux initialization order bugs are caught
-// independently on order in which we list source files.
+// independently on order in which we list source files (if we specify
+// strict init-order checking).
-// RUN: %clangxx_asan -m64 -O0 %s %p/../Helpers/initialization-bug-extra.cc\
-// RUN: -fsanitize=init-order -o %t && %t 2>&1 \
+// RUN: %clangxx_asan -m64 -O0 %s %p/../Helpers/initialization-bug-extra.cc -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true %t 2>&1 \
// RUN: | %symbolize | FileCheck %s
-// RUN: %clangxx_asan -m64 -O0 %p/../Helpers/initialization-bug-extra.cc %s\
-// RUN: -fsanitize=init-order -o %t && %t 2>&1 \
+// RUN: %clangxx_asan -m64 -O0 %p/../Helpers/initialization-bug-extra.cc %s -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true %t 2>&1 \
// RUN: | %symbolize | FileCheck %s
// Do not test with optimization -- the error may be optimized away.
diff --git a/lib/asan/lit_tests/interface_symbols.c b/lib/asan/lit_tests/Linux/interface_symbols_linux.c
index f3167f562922..4134c8744043 100644
--- a/lib/asan/lit_tests/interface_symbols.c
+++ b/lib/asan/lit_tests/Linux/interface_symbols_linux.c
@@ -1,14 +1,14 @@
// Check the presense of interface symbols in compiled file.
-// RUN: %clang -fsanitize=address -dead_strip -O2 %s -o %t.exe
-// RUN: nm %t.exe | grep " T " | sed "s/.* T //" \
+// RUN: %clang -fsanitize=address -O2 %s -o %t.exe
+// RUN: nm -D %t.exe | grep " T " | sed "s/.* T //" \
// RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \
// RUN: | grep -v "__asan_malloc_hook" \
// RUN: | grep -v "__asan_free_hook" \
// RUN: | grep -v "__asan_symbolize" \
// RUN: | grep -v "__asan_default_options" \
// RUN: | grep -v "__asan_on_error" > %t.symbols
-// RUN: cat %p/../../../include/sanitizer/asan_interface.h \
+// RUN: cat %p/../../asan_interface_internal.h \
// RUN: | sed "s/\/\/.*//" | sed "s/typedef.*//" \
// RUN: | grep -v "OPTIONAL" \
// RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \
@@ -23,6 +23,12 @@
// 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: cat %t.interface | sort -u | diff %t.symbols -
+// FIXME: nm -D on powerpc somewhy shows ASan interface symbols residing
+// in "initialized data section".
+// REQUIRES: x86_64-supported-target,i386-supported-target
+
int main() { return 0; }
diff --git a/lib/asan/lit_tests/Linux/malloc-in-qsort.cc b/lib/asan/lit_tests/Linux/malloc-in-qsort.cc
index a3fa255b186d..ee2e81f0d2ab 100644
--- a/lib/asan/lit_tests/Linux/malloc-in-qsort.cc
+++ b/lib/asan/lit_tests/Linux/malloc-in-qsort.cc
@@ -1,10 +1,14 @@
-// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: %clangxx_asan -m64 -O2 %s -o %t
// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=1 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-FAST
// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-SLOW
// Test how well we unwind in presence of qsort in the stack
// (i.e. if we can unwind through a function compiled w/o frame pointers).
// https://code.google.com/p/address-sanitizer/issues/detail?id=137
+
+// Fast unwinder is only avaliable on x86_64 and i386.
+// REQUIRES: x86_64-supported-target
+
#include <stdlib.h>
#include <stdio.h>
diff --git a/lib/asan/lit_tests/malloc_delete_mismatch.cc b/lib/asan/lit_tests/Linux/malloc_delete_mismatch.cc
index f34b33a38fb3..f34b33a38fb3 100644
--- a/lib/asan/lit_tests/malloc_delete_mismatch.cc
+++ b/lib/asan/lit_tests/Linux/malloc_delete_mismatch.cc
diff --git a/lib/asan/lit_tests/Linux/overflow-in-qsort.cc b/lib/asan/lit_tests/Linux/overflow-in-qsort.cc
index c298991a8348..8bc43ca0a5c3 100644
--- a/lib/asan/lit_tests/Linux/overflow-in-qsort.cc
+++ b/lib/asan/lit_tests/Linux/overflow-in-qsort.cc
@@ -1,10 +1,14 @@
-// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: %clangxx_asan -m64 -O2 %s -o %t
// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=1 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-FAST
// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=0 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-SLOW
// Test how well we unwind in presence of qsort in the stack
// (i.e. if we can unwind through a function compiled w/o frame pointers).
// https://code.google.com/p/address-sanitizer/issues/detail?id=137
+
+// Fast unwinder is only avaliable on x86_64 and i386.
+// REQUIRES: x86_64-supported-target
+
#include <stdlib.h>
#include <stdio.h>
diff --git a/lib/asan/lit_tests/Linux/preinit_test.cc b/lib/asan/lit_tests/Linux/preinit_test.cc
new file mode 100644
index 000000000000..28e509472c0c
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/preinit_test.cc
@@ -0,0 +1,27 @@
+// RUN: %clangxx -DFUNC=zzzz %s -shared -o %t.so -fPIC
+// RUN: %clangxx_asan -DFUNC=main %s -o %t -Wl,-R. %t.so
+// RUN: %t
+
+// This test ensures that we call __asan_init early enough.
+// We build a shared library w/o asan instrumentation
+// and the binary with asan instrumentation.
+// Both files include the same header (emulated by -DFUNC here)
+// with C++ template magic which runs global initializer at library load time.
+// The function get() is instrumented with asan, but called
+// before the usual constructors are run.
+// So, we must make sure that __asan_init is executed even earlier.
+//
+// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56393
+
+struct A {
+ int foo() const { return 0; }
+};
+A get () { return A(); }
+template <class> struct O {
+ static A const e;
+};
+template <class T> A const O <T>::e = get();
+int FUNC() {
+ return O<int>::e.foo();
+}
+
diff --git a/lib/asan/lit_tests/Linux/rlimit_mmap_test.cc b/lib/asan/lit_tests/Linux/rlimit_mmap_test.cc
index 5026e24e424d..86794756c76f 100644
--- a/lib/asan/lit_tests/Linux/rlimit_mmap_test.cc
+++ b/lib/asan/lit_tests/Linux/rlimit_mmap_test.cc
@@ -11,6 +11,6 @@ int main(int argc, char **argv) {
struct rlimit mmap_resource_limit = { 0, 0 };
assert(0 == setrlimit(RLIMIT_AS, &mmap_resource_limit));
x = malloc(10000000);
-// CHECK: AddressSanitizer is unable to mmap
+// CHECK: ERROR: Failed to mmap
return 0;
}
diff --git a/lib/asan/lit_tests/Linux/swapcontext_test.cc b/lib/asan/lit_tests/Linux/swapcontext_test.cc
index 0404b4f602bd..47a8d9891f51 100644
--- a/lib/asan/lit_tests/Linux/swapcontext_test.cc
+++ b/lib/asan/lit_tests/Linux/swapcontext_test.cc
@@ -8,6 +8,9 @@
// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s
+//
+// This test is too sublte to try on non-x86 arch for now.
+// REQUIRES: x86_64-supported-target,i386-supported-target
#include <stdio.h>
#include <ucontext.h>
@@ -16,9 +19,26 @@
ucontext_t orig_context;
ucontext_t child_context;
+const int kStackSize = 1 << 20;
+
+__attribute__((noinline))
+void Throw() {
+ throw 1;
+}
+
+__attribute__((noinline))
+void ThrowAndCatch() {
+ try {
+ Throw();
+ } catch(int a) {
+ printf("ThrowAndCatch: %d\n", a);
+ }
+}
+
void Child(int mode) {
char x[32] = {0}; // Stack gets poisoned.
printf("Child: %p\n", x);
+ ThrowAndCatch(); // Simulate __asan_handle_no_return().
// (a) Do nothing, just return to parent function.
// (b) Jump into the original function. Stack remains poisoned unless we do
// something.
@@ -30,9 +50,7 @@ void Child(int mode) {
}
}
-int Run(int arg, int mode) {
- const int kStackSize = 1 << 20;
- char child_stack[kStackSize + 1];
+int Run(int arg, int mode, char *child_stack) {
printf("Child stack: %p\n", child_stack);
// Setup child context.
getcontext(&child_context);
@@ -54,13 +72,23 @@ int Run(int arg, int mode) {
}
int main(int argc, char **argv) {
+ char stack[kStackSize + 1];
// CHECK: WARNING: ASan doesn't fully support makecontext/swapcontext
int ret = 0;
- ret += Run(argc - 1, 0);
+ ret += Run(argc - 1, 0, stack);
printf("Test1 passed\n");
// CHECK: Test1 passed
- ret += Run(argc - 1, 1);
+ ret += Run(argc - 1, 1, stack);
printf("Test2 passed\n");
// CHECK: Test2 passed
+ char *heap = new char[kStackSize + 1];
+ ret += Run(argc - 1, 0, heap);
+ printf("Test3 passed\n");
+ // CHECK: Test3 passed
+ ret += Run(argc - 1, 1, heap);
+ printf("Test4 passed\n");
+ // CHECK: Test4 passed
+
+ delete [] heap;
return ret;
}
diff --git a/lib/asan/lit_tests/Linux/syscalls.cc b/lib/asan/lit_tests/Linux/syscalls.cc
new file mode 100644
index 000000000000..b2edcfb92375
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/syscalls.cc
@@ -0,0 +1,22 @@
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+#include <assert.h>
+#include <errno.h>
+#include <glob.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sanitizer/linux_syscall_hooks.h>
+
+/* Test the presence of __sanitizer_syscall_ in the tool runtime, and general
+ sanity of their behaviour. */
+
+int main(int argc, char *argv[]) {
+ char buf[1000];
+ __sanitizer_syscall_pre_recvmsg(0, buf - 1, 0);
+ // CHECK: AddressSanitizer: stack-buffer-{{.*}}erflow
+ // CHECK: READ of size {{.*}} at {{.*}} thread T0
+ // CHECK: #0 {{.*}} in __sanitizer_syscall_pre_recvmsg
+ return 0;
+}
diff --git a/lib/asan/lit_tests/Linux/time_null_regtest.cc b/lib/asan/lit_tests/Linux/time_null_regtest.cc
new file mode 100644
index 000000000000..975bca3d105a
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/time_null_regtest.cc
@@ -0,0 +1,20 @@
+// RUN: %clangxx_asan -m64 -O0 %s -fsanitize-address-zero-base-shadow -pie -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+// Zero-base shadow only works on x86_64 and i386.
+// REQUIRES: x86_64-supported-target
+
+// A regression test for time(NULL), which caused ASan to crash in the
+// zero-based shadow mode on Linux.
+// FIXME: this test does not work on Darwin, because the code pages of the
+// executable interleave with the zero-based shadow.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+int main() {
+ time_t t = time(NULL);
+ fprintf(stderr, "Time: %s\n", ctime(&t)); // NOLINT
+ // CHECK: {{Time: .* .* .*}}
+ return 0;
+}
diff --git a/lib/asan/lit_tests/Linux/zero-base-shadow.cc b/lib/asan/lit_tests/Linux/zero-base-shadow.cc
new file mode 100644
index 000000000000..682e7e8d7e59
--- /dev/null
+++ b/lib/asan/lit_tests/Linux/zero-base-shadow.cc
@@ -0,0 +1,31 @@
+// RUN: %clangxx_asan -m64 -O0 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-64 < %t.out
+// RUN: %clangxx_asan -m64 -O1 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-64 < %t.out
+// RUN: %clangxx_asan -m64 -O2 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-64 < %t.out
+// RUN: %clangxx_asan -m32 -O0 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-32 < %t.out
+// RUN: %clangxx_asan -m32 -O1 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-32 < %t.out
+// RUN: %clangxx_asan -m32 -O2 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-32 < %t.out
+
+// Zero-base shadow only works on x86_64 and i386.
+// REQUIRES: x86_64-supported-target,i386-supported-target
+
+#include <string.h>
+int main(int argc, char **argv) {
+ char x[10];
+ memset(x, 0, 10);
+ int res = x[argc * 10]; // BOOOM
+ // CHECK: {{READ of size 1 at 0x.* thread T0}}
+ // CHECK: {{ #0 0x.* in _?main .*zero-base-shadow.cc:}}[[@LINE-2]]
+ // CHECK: {{Address 0x.* is .* frame}}
+ // CHECK: main
+
+ // Check that shadow for stack memory occupies lower part of address space.
+ // CHECK-64: =>0x0f
+ // CHECK-32: =>0x1
+ return res;
+}
diff --git a/lib/asan/lit_tests/SharedLibs/darwin-dummy-shared-lib-so.cc b/lib/asan/lit_tests/SharedLibs/darwin-dummy-shared-lib-so.cc
new file mode 100644
index 000000000000..5d939991476e
--- /dev/null
+++ b/lib/asan/lit_tests/SharedLibs/darwin-dummy-shared-lib-so.cc
@@ -0,0 +1,13 @@
+//===----------- darwin-dummy-shared-lib-so.cc ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+//===----------------------------------------------------------------------===//
+void foo() {}
diff --git a/lib/asan/lit_tests/SharedLibs/init-order-dlopen-so.cc b/lib/asan/lit_tests/SharedLibs/init-order-dlopen-so.cc
new file mode 100644
index 000000000000..20ef2d8a00bb
--- /dev/null
+++ b/lib/asan/lit_tests/SharedLibs/init-order-dlopen-so.cc
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <unistd.h>
+
+void inc_global();
+
+int slow_init() {
+ sleep(1);
+ inc_global();
+ return 42;
+}
+
+int slowly_init_glob = slow_init();
diff --git a/lib/asan/lit_tests/Unit/lit.cfg b/lib/asan/lit_tests/Unit/lit.cfg
index 243eb7fbeec0..e24361b014e9 100644
--- a/lib/asan/lit_tests/Unit/lit.cfg
+++ b/lib/asan/lit_tests/Unit/lit.cfg
@@ -11,9 +11,8 @@ def get_required_attr(config, attr_name):
return attr_value
# Setup attributes common for all compiler-rt projects.
-llvm_src_root = get_required_attr(config, 'llvm_src_root')
-compiler_rt_lit_unit_cfg = os.path.join(llvm_src_root, "projects",
- "compiler-rt", "lib",
+compiler_rt_src_root = get_required_attr(config, 'compiler_rt_src_root')
+compiler_rt_lit_unit_cfg = os.path.join(compiler_rt_src_root, "lib",
"lit.common.unit.cfg")
lit.load_config(config, compiler_rt_lit_unit_cfg)
diff --git a/lib/asan/lit_tests/Unit/lit.site.cfg.in b/lib/asan/lit_tests/Unit/lit.site.cfg.in
index 401c3a8cc2eb..315d24d1ed09 100644
--- a/lib/asan/lit_tests/Unit/lit.site.cfg.in
+++ b/lib/asan/lit_tests/Unit/lit.site.cfg.in
@@ -3,8 +3,15 @@
config.target_triple = "@TARGET_TRIPLE@"
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
-config.build_type = "@CMAKE_BUILD_TYPE@"
+config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@"
+config.llvm_build_mode = "@LLVM_BUILD_MODE@"
config.asan_binary_dir = "@ASAN_BINARY_DIR@"
+try:
+ config.llvm_build_mode = config.llvm_build_mode % lit.params
+except KeyError,e:
+ key, = e.args
+ lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key))
+
# Let the main config do the real work.
lit.load_config(config, "@ASAN_SOURCE_DIR@/lit_tests/Unit/lit.cfg")
diff --git a/lib/asan/lit_tests/allow_user_segv.cc b/lib/asan/lit_tests/allow_user_segv.cc
new file mode 100644
index 000000000000..f8aed0d4ca80
--- /dev/null
+++ b/lib/asan/lit_tests/allow_user_segv.cc
@@ -0,0 +1,50 @@
+// Regression test for
+// https://code.google.com/p/address-sanitizer/issues/detail?id=180
+
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m64 -O2 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m32 -O0 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m32 -O2 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s
+
+#include <signal.h>
+#include <stdio.h>
+
+struct sigaction user_sigaction;
+struct sigaction original_sigaction;
+
+void User_OnSIGSEGV(int signum, siginfo_t *siginfo, void *context) {
+ fprintf(stderr, "User sigaction called\n");
+ if (original_sigaction.sa_flags | SA_SIGINFO)
+ original_sigaction.sa_sigaction(signum, siginfo, context);
+ else
+ original_sigaction.sa_handler(signum);
+}
+
+int DoSEGV() {
+ volatile int *x = 0;
+ return *x;
+}
+
+int main() {
+ user_sigaction.sa_sigaction = User_OnSIGSEGV;
+ user_sigaction.sa_flags = SA_SIGINFO;
+#if defined(__APPLE__) && !defined(__LP64__)
+ // On 32-bit Darwin KERN_PROTECTION_FAILURE (SIGBUS) is delivered.
+ int signum = SIGBUS;
+#else
+ // On 64-bit Darwin KERN_INVALID_ADDRESS (SIGSEGV) is delivered.
+ // On Linux SIGSEGV is delivered as well.
+ int signum = SIGSEGV;
+#endif
+ if (sigaction(signum, &user_sigaction, &original_sigaction)) {
+ perror("sigaction");
+ return 1;
+ }
+ fprintf(stderr, "User sigaction installed\n");
+ return DoSEGV();
+}
+
+// CHECK: User sigaction installed
+// CHECK-NEXT: User sigaction called
+// CHECK-NEXT: ASAN:SIGSEGV
+// CHECK: AddressSanitizer: SEGV on unknown address
diff --git a/lib/asan/lit_tests/default_blacklist.cc b/lib/asan/lit_tests/default_blacklist.cc
new file mode 100644
index 000000000000..25a1ae1752b0
--- /dev/null
+++ b/lib/asan/lit_tests/default_blacklist.cc
@@ -0,0 +1,3 @@
+// Test that ASan uses the default blacklist from resource directory.
+// RUN: %clangxx_asan -### %s 2>&1 | FileCheck %s
+// CHECK: fsanitize-blacklist={{.*}}asan_blacklist.txt
diff --git a/lib/asan/lit_tests/default_options.cc b/lib/asan/lit_tests/default_options.cc
index 950a7d879194..84b80557b852 100644
--- a/lib/asan/lit_tests/default_options.cc
+++ b/lib/asan/lit_tests/default_options.cc
@@ -4,7 +4,7 @@
const char *kAsanDefaultOptions="verbosity=1 foo=bar";
extern "C"
-__attribute__((no_address_safety_analysis))
+__attribute__((no_sanitize_address))
const char *__asan_default_options() {
// CHECK: Using the defaults from __asan_default_options: {{.*}} foo=bar
return kAsanDefaultOptions;
diff --git a/lib/asan/lit_tests/dlclose-test.cc b/lib/asan/lit_tests/dlclose-test.cc
index 229f508294bf..b15895bf3579 100644
--- a/lib/asan/lit_tests/dlclose-test.cc
+++ b/lib/asan/lit_tests/dlclose-test.cc
@@ -9,6 +9,11 @@
// are globals.
// 6. BOOM
+// This sublte test assumes that after a foo.so is dlclose-d
+// we can mmap the region of memory that has been occupied by the library.
+// It works on i368/x86_64 Linux, but not necessary anywhere else.
+// REQUIRES: x86_64-supported-target,i386-supported-target
+
// RUN: %clangxx_asan -m64 -O0 %p/SharedLibs/dlclose-test-so.cc \
// RUN: -fPIC -shared -o %t-so.so
// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s
@@ -39,17 +44,17 @@
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
+#include <unistd.h>
#include <string>
using std::string;
-static const int kPageSize = 4096;
-
typedef int *(fun_t)();
int main(int argc, char *argv[]) {
string path = string(argv[0]) + "-so.so";
+ size_t PageSize = sysconf(_SC_PAGESIZE);
printf("opening %s ... \n", path.c_str());
void *lib = dlopen(path.c_str(), RTLD_NOW);
if (!lib) {
@@ -73,8 +78,8 @@ int main(int argc, char *argv[]) {
return 1;
}
// Now, the page where 'addr' is unmapped. Map it.
- size_t page_beg = ((size_t)addr) & ~(kPageSize - 1);
- void *res = mmap((void*)(page_beg), kPageSize,
+ size_t page_beg = ((size_t)addr) & ~(PageSize - 1);
+ void *res = mmap((void*)(page_beg), PageSize,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 0, 0);
if (res == (char*)-1L) {
diff --git a/lib/asan/lit_tests/double-free.cc b/lib/asan/lit_tests/double-free.cc
new file mode 100644
index 000000000000..9e201117c563
--- /dev/null
+++ b/lib/asan/lit_tests/double-free.cc
@@ -0,0 +1,18 @@
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+#include <stdlib.h>
+#include <string.h>
+int main(int argc, char **argv) {
+ char *x = (char*)malloc(10 * sizeof(char));
+ memset(x, 0, 10);
+ int res = x[argc];
+ free(x);
+ free(x + argc - 1); // BOOM
+ // CHECK: AddressSanitizer: attempting double-free{{.*}}in thread T0
+ // CHECK: double-free.cc:[[@LINE-2]]
+ // CHECK: freed by thread T0 here:
+ // CHECK: double-free.cc:[[@LINE-5]]
+ // CHECK: allocated by thread T0 here:
+ // CHECK: double-free.cc:[[@LINE-10]]
+ return res;
+}
diff --git a/lib/asan/lit_tests/global-demangle.cc b/lib/asan/lit_tests/global-demangle.cc
new file mode 100644
index 000000000000..5696a38a7705
--- /dev/null
+++ b/lib/asan/lit_tests/global-demangle.cc
@@ -0,0 +1,18 @@
+// Don't run through %symbolize to avoid c++filt demangling.
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s
+
+namespace XXX {
+class YYY {
+ public:
+ static char ZZZ[];
+};
+char YYY::ZZZ[] = "abc";
+}
+
+int main(int argc, char **argv) {
+ return (int)XXX::YYY::ZZZ[argc + 5]; // BOOM
+ // CHECK: {{READ of size 1 at 0x.*}}
+ // CHECK: {{0x.* is located 2 bytes to the right of global variable}}
+ // CHECK: 'XXX::YYY::ZZZ' {{.*}} of size 4
+ // CHECK: 'XXX::YYY::ZZZ' is ascii string 'abc'
+}
diff --git a/lib/asan/lit_tests/heap-overflow.cc b/lib/asan/lit_tests/heap-overflow.cc
index 2648ec7e5f1f..f1d719cd0b20 100644
--- a/lib/asan/lit_tests/heap-overflow.cc
+++ b/lib/asan/lit_tests/heap-overflow.cc
@@ -29,10 +29,8 @@ int main(int argc, char **argv) {
// CHECK-Linux: {{ #0 0x.* in .*malloc}}
// CHECK-Linux: {{ #1 0x.* in main .*heap-overflow.cc:21}}
- // CHECK-Darwin: {{ #0 0x.* in .*mz_malloc.*}}
- // CHECK-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}}
- // CHECK-Darwin: {{ #2 0x.* in malloc.*}}
- // CHECK-Darwin: {{ #3 0x.* in _?main .*heap-overflow.cc:21}}
+ // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}}
+ // CHECK-Darwin: {{ #1 0x.* in _?main .*heap-overflow.cc:21}}
free(x);
return res;
}
diff --git a/lib/asan/lit_tests/huge_negative_hea_oob.cc b/lib/asan/lit_tests/huge_negative_hea_oob.cc
new file mode 100644
index 000000000000..a09e3bf87d60
--- /dev/null
+++ b/lib/asan/lit_tests/huge_negative_hea_oob.cc
@@ -0,0 +1,13 @@
+// RUN: %clangxx_asan -m64 %s -o %t && %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m64 -O %s -o %t && %t 2>&1 | FileCheck %s
+// Check that we can find huge buffer overflows to the left.
+#include <stdlib.h>
+#include <string.h>
+int main(int argc, char **argv) {
+ char *x = (char*)malloc(1 << 20);
+ memset(x, 0, 10);
+ int res = x[-argc * 4000]; // BOOOM
+ // CHECK: is located 4000 bytes to the left of
+ free(x);
+ return res;
+}
diff --git a/lib/asan/lit_tests/init-order-atexit.cc b/lib/asan/lit_tests/init-order-atexit.cc
new file mode 100644
index 000000000000..45f4f17c0cb0
--- /dev/null
+++ b/lib/asan/lit_tests/init-order-atexit.cc
@@ -0,0 +1,31 @@
+// Test for the following situation:
+// (1) global A is constructed.
+// (2) exit() is called during construction of global B.
+// (3) destructor of A reads uninitialized global C from another module.
+// We do *not* want to report init-order bug in this case.
+
+// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/init-order-atexit-extra.cc -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void AccessC();
+
+class A {
+ public:
+ A() { }
+ ~A() { AccessC(); printf("PASSED\n"); }
+ // CHECK-NOT: AddressSanitizer
+ // CHECK: PASSED
+};
+
+A a;
+
+class B {
+ public:
+ B() { exit(1); }
+ ~B() { }
+};
+
+B b;
diff --git a/lib/asan/lit_tests/init-order-dlopen.cc b/lib/asan/lit_tests/init-order-dlopen.cc
new file mode 100644
index 000000000000..228f44204c99
--- /dev/null
+++ b/lib/asan/lit_tests/init-order-dlopen.cc
@@ -0,0 +1,52 @@
+// Regression test for
+// https://code.google.com/p/address-sanitizer/issues/detail?id=178
+
+// RUN: %clangxx_asan -m64 -O0 %p/SharedLibs/init-order-dlopen-so.cc \
+// RUN: -fPIC -shared -o %t-so.so
+// If the linker doesn't support --export-dynamic (which is ELF-specific),
+// try to link without that option.
+// FIXME: find a better solution.
+// RUN: %clangxx_asan -m64 -O0 %s -o %t -Wl,--export-dynamic || \
+// RUN: %clangxx_asan -m64 -O0 %s -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true %t 2>&1 | FileCheck %s
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <string>
+
+using std::string;
+
+int foo() {
+ return 42;
+}
+int global = foo();
+
+__attribute__((visibility("default")))
+void inc_global() {
+ global++;
+}
+
+void *global_poller(void *arg) {
+ while (true) {
+ if (global != 42)
+ break;
+ usleep(100);
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ pthread_t p;
+ pthread_create(&p, 0, global_poller, 0);
+ string path = string(argv[0]) + "-so.so";
+ if (0 == dlopen(path.c_str(), RTLD_NOW)) {
+ fprintf(stderr, "dlerror: %s\n", dlerror());
+ return 1;
+ }
+ pthread_join(p, 0);
+ printf("PASSED\n");
+ // CHECK: PASSED
+ return 0;
+}
diff --git a/lib/asan/lit_tests/initialization-blacklist.cc b/lib/asan/lit_tests/initialization-blacklist.cc
index f8df24c68ea6..12fbc49ed91b 100644
--- a/lib/asan/lit_tests/initialization-blacklist.cc
+++ b/lib/asan/lit_tests/initialization-blacklist.cc
@@ -1,23 +1,35 @@
// Test for blacklist functionality of initialization-order checker.
// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-blacklist-extra.cc\
+// RUN: %p/Helpers/initialization-blacklist-extra2.cc \
// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \
-// RUN: -fsanitize=init-order -o %t && %t 2>&1
+// RUN: -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
// RUN: %clangxx_asan -m64 -O1 %s %p/Helpers/initialization-blacklist-extra.cc\
+// RUN: %p/Helpers/initialization-blacklist-extra2.cc \
// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \
-// RUN: -fsanitize=init-order -o %t && %t 2>&1
+// RUN: -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
// RUN: %clangxx_asan -m64 -O2 %s %p/Helpers/initialization-blacklist-extra.cc\
+// RUN: %p/Helpers/initialization-blacklist-extra2.cc \
// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \
-// RUN: -fsanitize=init-order -o %t && %t 2>&1
+// RUN: -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-blacklist-extra.cc\
+// RUN: %p/Helpers/initialization-blacklist-extra2.cc \
// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \
-// RUN: -fsanitize=init-order -o %t && %t 2>&1
+// RUN: -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
// RUN: %clangxx_asan -m32 -O1 %s %p/Helpers/initialization-blacklist-extra.cc\
+// RUN: %p/Helpers/initialization-blacklist-extra2.cc \
// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \
-// RUN: -fsanitize=init-order -o %t && %t 2>&1
+// RUN: -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
// RUN: %clangxx_asan -m32 -O2 %s %p/Helpers/initialization-blacklist-extra.cc\
+// RUN: %p/Helpers/initialization-blacklist-extra2.cc \
// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \
-// RUN: -fsanitize=init-order -o %t && %t 2>&1
+// RUN: -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
// Function is defined in another TU.
int readBadGlobal();
@@ -27,6 +39,9 @@ int x = readBadGlobal(); // init-order bug.
int accessBadObject();
int y = accessBadObject(); // init-order bug.
+int readBadSrcGlobal();
+int z = readBadSrcGlobal(); // init-order bug.
+
int main(int argc, char **argv) {
- return argc + x + y - 1;
+ return argc + x + y + z - 1;
}
diff --git a/lib/asan/lit_tests/initialization-bug.cc b/lib/asan/lit_tests/initialization-bug.cc
index 8f4e33ef5a35..ee2c725f0b13 100644
--- a/lib/asan/lit_tests/initialization-bug.cc
+++ b/lib/asan/lit_tests/initialization-bug.cc
@@ -1,14 +1,17 @@
// Test to make sure basic initialization order errors are caught.
-// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-bug-extra2.cc\
-// RUN: -fsanitize=init-order -o %t && %t 2>&1 \
+// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \
// RUN: | %symbolize | FileCheck %s
-// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-bug-extra2.cc\
-// RUN: -fsanitize=init-order -o %t && %t 2>&1 \
+// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \
// RUN: | %symbolize | FileCheck %s
// Do not test with optimization -- the error may be optimized away.
+// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=186
+// XFAIL: darwin
+
#include <cstdio>
// The structure of the test is:
diff --git a/lib/asan/lit_tests/initialization-constexpr.cc b/lib/asan/lit_tests/initialization-constexpr.cc
new file mode 100644
index 000000000000..ba5410674f76
--- /dev/null
+++ b/lib/asan/lit_tests/initialization-constexpr.cc
@@ -0,0 +1,43 @@
+// Constexpr:
+// We need to check that a global variable initialized with a constexpr
+// constructor can be accessed during dynamic initialization (as a constexpr
+// constructor implies that it was initialized during constant initialization,
+// not dynamic initialization).
+
+// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-constexpr-extra.cc\
+// RUN: --std=c++11 -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m64 -O1 %s %p/Helpers/initialization-constexpr-extra.cc\
+// RUN: --std=c++11 -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m64 -O2 %s %p/Helpers/initialization-constexpr-extra.cc\
+// RUN: --std=c++11 -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m64 -O3 %s %p/Helpers/initialization-constexpr-extra.cc\
+// RUN: --std=c++11 -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-constexpr-extra.cc\
+// RUN: --std=c++11 -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m32 -O1 %s %p/Helpers/initialization-constexpr-extra.cc\
+// RUN: --std=c++11 -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m32 -O2 %s %p/Helpers/initialization-constexpr-extra.cc\
+// RUN: --std=c++11 -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m32 -O3 %s %p/Helpers/initialization-constexpr-extra.cc\
+// RUN: --std=c++11 -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+
+class Integer {
+ private:
+ int value;
+
+ public:
+ constexpr Integer(int x = 0) : value(x) {}
+ int getValue() {return value;}
+};
+Integer coolestInteger(42);
+int getCoolestInteger() { return coolestInteger.getValue(); }
+
+int main() { return 0; }
diff --git a/lib/asan/lit_tests/initialization-nobug.cc b/lib/asan/lit_tests/initialization-nobug.cc
index 1b8961606811..407226e29a1b 100644
--- a/lib/asan/lit_tests/initialization-nobug.cc
+++ b/lib/asan/lit_tests/initialization-nobug.cc
@@ -1,24 +1,22 @@
// A collection of various initializers which shouldn't trip up initialization
// order checking. If successful, this will just return 0.
-// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-nobug-extra.cc\
-// RUN: --std=c++11 -fsanitize=init-order -o %t && %t 2>&1
-// RUN: %clangxx_asan -m64 -O1 %s %p/Helpers/initialization-nobug-extra.cc\
-// RUN: --std=c++11 -fsanitize=init-order -o %t && %t 2>&1
-// RUN: %clangxx_asan -m64 -O2 %s %p/Helpers/initialization-nobug-extra.cc\
-// RUN: --std=c++11 -fsanitize=init-order -o %t && %t 2>&1
-// RUN: %clangxx_asan -m64 -O3 %s %p/Helpers/initialization-nobug-extra.cc\
-// RUN: --std=c++11 -fsanitize=init-order -o %t && %t 2>&1
-// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-nobug-extra.cc\
-// RUN: --std=c++11 -fsanitize=init-order -o %t && %t 2>&1
-// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-nobug-extra.cc\
-// RUN: --std=c++11 -fsanitize=init-order -o %t && %t 2>&1
-// RUN: %clangxx_asan -m32 -O1 %s %p/Helpers/initialization-nobug-extra.cc\
-// RUN: --std=c++11 -fsanitize=init-order -o %t && %t 2>&1
-// RUN: %clangxx_asan -m32 -O2 %s %p/Helpers/initialization-nobug-extra.cc\
-// RUN: --std=c++11 -fsanitize=init-order -o %t && %t 2>&1
-// RUN: %clangxx_asan -m32 -O3 %s %p/Helpers/initialization-nobug-extra.cc\
-// RUN: --std=c++11 -fsanitize=init-order -o %t && %t 2>&1
+// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m64 -O1 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m64 -O2 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m64 -O3 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m32 -O1 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m32 -O2 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
+// RUN: %clangxx_asan -m32 -O3 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t
+// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1
// Simple access:
// Make sure that accessing a global in the same TU is safe
@@ -47,21 +45,12 @@ int countCalls() {
return ++calls;
}
-// Constexpr:
-// We need to check that a global variable initialized with a constexpr
-// constructor can be accessed during dynamic initialization (as a constexpr
-// constructor implies that it was initialized during constant initialization,
-// not dynamic initialization).
-
-class Integer {
- private:
+// Trivial constructor, non-trivial destructor.
+struct StructWithDtor {
+ ~StructWithDtor() { }
int value;
-
- public:
- constexpr Integer(int x = 0) : value(x) {}
- int getValue() {return value;}
};
-Integer coolestInteger(42);
-int getCoolestInteger() { return coolestInteger.getValue(); }
+StructWithDtor struct_with_dtor;
+int getStructWithDtorValue() { return struct_with_dtor.value; }
int main() { return 0; }
diff --git a/lib/asan/lit_tests/interface_test.cc b/lib/asan/lit_tests/interface_test.cc
new file mode 100644
index 000000000000..428a109fe70d
--- /dev/null
+++ b/lib/asan/lit_tests/interface_test.cc
@@ -0,0 +1,8 @@
+// Check that user may include ASan interface header.
+// RUN: %clang -fsanitize=address -I %p/../../../include %s -o %t && %t
+// RUN: %clang -I %p/../../../include %s -o %t && %t
+#include <sanitizer/asan_interface.h>
+
+int main() {
+ return 0;
+}
diff --git a/lib/asan/lit_tests/invalid-free.cc b/lib/asan/lit_tests/invalid-free.cc
new file mode 100644
index 000000000000..0ef064056b63
--- /dev/null
+++ b/lib/asan/lit_tests/invalid-free.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+#include <stdlib.h>
+#include <string.h>
+int main(int argc, char **argv) {
+ char *x = (char*)malloc(10 * sizeof(char));
+ memset(x, 0, 10);
+ int res = x[argc];
+ free(x + 5); // BOOM
+ // CHECK: AddressSanitizer: attempting free on address{{.*}}in thread T0
+ // CHECK: invalid-free.cc:[[@LINE-2]]
+ // CHECK: is located 5 bytes inside of 10-byte region
+ // CHECK: allocated by thread T0 here:
+ // CHECK: invalid-free.cc:[[@LINE-8]]
+ return res;
+}
diff --git a/lib/asan/lit_tests/large_func_test.cc b/lib/asan/lit_tests/large_func_test.cc
index a74828811f74..ceecc29b7b0a 100644
--- a/lib/asan/lit_tests/large_func_test.cc
+++ b/lib/asan/lit_tests/large_func_test.cc
@@ -32,7 +32,7 @@ static void LargeFunction(int *x, int zero) {
// CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
// CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
// CHECK: {{READ of size 4 at 0x.* thread T0}}
- x[zero + 111]++; // we should report this exact line
+ x[zero + 103]++; // we should report this exact line
// atos incorrectly extracts the symbol name for the static functions on
// Darwin.
// CHECK-Linux: {{#0 0x.* in LargeFunction.*large_func_test.cc:}}[[@LINE-3]]
@@ -54,9 +54,10 @@ int main(int argc, char **argv) {
int *x = new int[100];
LargeFunction(x, argc - 1);
// CHECK: {{ #1 0x.* in _?main .*large_func_test.cc:}}[[@LINE-1]]
- // CHECK: {{0x.* is located 44 bytes to the right of 400-byte region}}
+ // CHECK: {{0x.* is located 12 bytes to the right of 400-byte region}}
// CHECK: {{allocated by thread T0 here:}}
- // CHECK: {{ #0 0x.* in operator new.*}}
- // CHECK: {{ #1 0x.* in _?main .*large_func_test.cc:}}[[@LINE-6]]
+ // CHECK-Linux: {{ #0 0x.* in operator new.*}}
+ // CHECK-Darwin: {{ #0 0x.* in .*_Zna.*}}
+ // CHECK: {{ #1 0x.* in _?main .*large_func_test.cc:}}[[@LINE-7]]
delete x;
}
diff --git a/lib/asan/lit_tests/lit.cfg b/lib/asan/lit_tests/lit.cfg
index 7875281b1f2f..5daecd9e557d 100644
--- a/lib/asan/lit_tests/lit.cfg
+++ b/lib/asan/lit_tests/lit.cfg
@@ -2,6 +2,14 @@
import os
+def get_required_attr(config, attr_name):
+ attr_value = getattr(config, attr_name, None)
+ if not attr_value:
+ lit.fatal("No attribute %r in test configuration! You may need to run "
+ "tests from your build directory or add this attribute "
+ "to lit.site.cfg " % attr_name)
+ return attr_value
+
# Setup config name.
config.name = 'AddressSanitizer'
@@ -30,14 +38,6 @@ if llvm_src_root is None:
if not llvm_config:
DisplayNoConfigMessage()
- # Validate that llvm-config points to the same source tree.
- llvm_src_root = lit.util.capture(["llvm-config", "--src-root"]).strip()
- asan_test_src_root = os.path.join(llvm_src_root, "projects", "compiler-rt",
- "lib", "asan", "lit_tests")
- if (os.path.realpath(asan_test_src_root) !=
- os.path.realpath(config.test_source_root)):
- DisplayNoConfigMessage()
-
# Find out the presumed location of generated site config.
llvm_obj_root = lit.util.capture(["llvm-config", "--obj-root"]).strip()
asan_site_cfg = os.path.join(llvm_obj_root, "projects", "compiler-rt",
@@ -49,8 +49,9 @@ if llvm_src_root is None:
raise SystemExit
# Setup attributes common for all compiler-rt projects.
-compiler_rt_lit_cfg = os.path.join(llvm_src_root, "projects", "compiler-rt",
- "lib", "lit.common.cfg")
+compiler_rt_src_root = get_required_attr(config, "compiler_rt_src_root")
+compiler_rt_lit_cfg = os.path.join(compiler_rt_src_root, "lib",
+ "lit.common.cfg")
if (not compiler_rt_lit_cfg) or (not os.path.exists(compiler_rt_lit_cfg)):
lit.fatal("Can't find common compiler-rt lit config at: %r"
% compiler_rt_lit_cfg)
diff --git a/lib/asan/lit_tests/lit.site.cfg.in b/lib/asan/lit_tests/lit.site.cfg.in
index cf439309c6ad..08546cdabe02 100644
--- a/lib/asan/lit_tests/lit.site.cfg.in
+++ b/lib/asan/lit_tests/lit.site.cfg.in
@@ -5,8 +5,10 @@ config.target_triple = "@TARGET_TRIPLE@"
config.host_os = "@HOST_OS@"
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
+config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.clang = "@LLVM_BINARY_DIR@/bin/clang"
+config.compiler_rt_arch = "@COMPILER_RT_SUPPORTED_ARCH@"
# LLVM tools dir can be passed in lit parameters, so try to
# apply substitution.
diff --git a/lib/asan/lit_tests/log_path_fork_test.cc b/lib/asan/lit_tests/log_path_fork_test.cc.disabled
index c6c1b49e994d..c6c1b49e994d 100644
--- a/lib/asan/lit_tests/log_path_fork_test.cc
+++ b/lib/asan/lit_tests/log_path_fork_test.cc.disabled
diff --git a/lib/asan/lit_tests/malloc_fill.cc b/lib/asan/lit_tests/malloc_fill.cc
new file mode 100644
index 000000000000..c23516b33299
--- /dev/null
+++ b/lib/asan/lit_tests/malloc_fill.cc
@@ -0,0 +1,22 @@
+// Check that we fill malloc-ed memory correctly.
+// RUN: %clangxx_asan -m64 %s -o %t
+// RUN: %t | FileCheck %s
+// RUN: ASAN_OPTIONS=max_malloc_fill_size=10:malloc_fill_byte=8 %t | FileCheck %s --check-prefix=CHECK-10-8
+// RUN: ASAN_OPTIONS=max_malloc_fill_size=20:malloc_fill_byte=171 %t | FileCheck %s --check-prefix=CHECK-20-ab
+
+#include <stdio.h>
+int main(int argc, char **argv) {
+ // With asan allocator this makes sure we get memory from mmap.
+ static const int kSize = 1 << 25;
+ unsigned char *x = new unsigned char[kSize];
+ printf("-");
+ for (int i = 0; i <= 32; i++) {
+ printf("%02x", x[i]);
+ }
+ printf("-\n");
+ delete [] x;
+}
+
+// CHECK: -bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe-
+// CHECK-10-8: -080808080808080808080000000000000000000000000000000000000000000000-
+// CHECK-20-ab: -abababababababababababababababababababab00000000000000000000000000-
diff --git a/lib/asan/lit_tests/memcmp_strict_test.cc b/lib/asan/lit_tests/memcmp_strict_test.cc
new file mode 100644
index 000000000000..00bf921c744a
--- /dev/null
+++ b/lib/asan/lit_tests/memcmp_strict_test.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && ASAN_OPTIONS=strict_memcmp=0 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-nonstrict
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && ASAN_OPTIONS=strict_memcmp=1 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-strict
+// Default to strict_memcmp=1.
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-strict
+
+#include <stdio.h>
+#include <string.h>
+int main() {
+ char kFoo[] = "foo";
+ char kFubar[] = "fubar";
+ int res = memcmp(kFoo, kFubar, strlen(kFubar));
+ printf("res: %d\n", res);
+ // CHECK-nonstrict: {{res: -1}}
+ // CHECK-strict: AddressSanitizer: stack-buffer-overflow
+ return 0;
+}
diff --git a/lib/asan/lit_tests/partial_right.cc b/lib/asan/lit_tests/partial_right.cc
new file mode 100644
index 000000000000..c579262726f9
--- /dev/null
+++ b/lib/asan/lit_tests/partial_right.cc
@@ -0,0 +1,17 @@
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+#include <stdlib.h>
+int main(int argc, char **argv) {
+ volatile int *x = (int*)malloc(2*sizeof(int) + 2);
+ int res = x[2]; // BOOOM
+ // CHECK: {{READ of size 4 at 0x.* thread T0}}
+ // CHECK: [[ADDR:0x[01-9a-fa-f]+]] is located 0 bytes to the right of {{.*}}-byte region [{{.*}},{{.*}}[[ADDR]])
+ return res;
+}
diff --git a/lib/asan/lit_tests/stack-frame-demangle.cc b/lib/asan/lit_tests/stack-frame-demangle.cc
index 7f4d59fc5838..bb8de16b2b8a 100644
--- a/lib/asan/lit_tests/stack-frame-demangle.cc
+++ b/lib/asan/lit_tests/stack-frame-demangle.cc
@@ -1,7 +1,4 @@
-// Check that ASan is able to print demangled frame name even w/o
-// symbolization.
-
-// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
#include <string.h>
@@ -11,12 +8,13 @@ struct YYY {
char array[10];
memset(array, 0, 10);
return array[x]; // BOOOM
- // CHECK: {{ERROR: AddressSanitizer: stack-buffer-overflow}}
- // CHECK: {{READ of size 1 at 0x.* thread T0}}
- // CHECK: {{Address 0x.* is .* frame <XXX::YYY::ZZZ(.*)>}}
+ // CHECK: ERROR: AddressSanitizer: stack-buffer-overflow
+ // CHECK: READ of size 1 at
+ // CHECK: is located in stack of thread T0 at offset
+ // CHECK: XXX::YYY::ZZZ
}
};
-};
+} // namespace XXX
int main(int argc, char **argv) {
int res = XXX::YYY::ZZZ(argc + 10);
diff --git a/lib/asan/lit_tests/stack-oob-frames.cc b/lib/asan/lit_tests/stack-oob-frames.cc
new file mode 100644
index 000000000000..0395522252e8
--- /dev/null
+++ b/lib/asan/lit_tests/stack-oob-frames.cc
@@ -0,0 +1,59 @@
+// RUN: %clangxx_asan -m64 -O1 %s -o %t
+// RUN: %t 0 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK0
+// RUN: %t 1 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK1
+// RUN: %t 2 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK2
+// RUN: %t 3 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK3
+
+#define NOINLINE __attribute__((noinline))
+inline void break_optimization(void *arg) {
+ __asm__ __volatile__("" : : "r" (arg) : "memory");
+}
+
+NOINLINE static void Frame0(int frame, char *a, char *b, char *c) {
+ char s[4] = {0};
+ char *d = s;
+ break_optimization(&d);
+ switch (frame) {
+ case 3: a[5]++; break;
+ case 2: b[5]++; break;
+ case 1: c[5]++; break;
+ case 0: d[5]++; break;
+ }
+}
+NOINLINE static void Frame1(int frame, char *a, char *b) {
+ char c[4] = {0}; Frame0(frame, a, b, c);
+ break_optimization(0);
+}
+NOINLINE static void Frame2(int frame, char *a) {
+ char b[4] = {0}; Frame1(frame, a, b);
+ break_optimization(0);
+}
+NOINLINE static void Frame3(int frame) {
+ char a[4] = {0}; Frame2(frame, a);
+ break_optimization(0);
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) return 1;
+ Frame3(argv[1][0] - '0');
+}
+
+// CHECK0: AddressSanitizer: stack-buffer-overflow
+// CHECK0: #0{{.*}}Frame0
+// CHECK0: #1{{.*}}Frame1
+// CHECK0: #2{{.*}}Frame2
+// CHECK0: #3{{.*}}Frame3
+// CHECK0: is located in stack of thread T0 at offset
+// CHECK0-NEXT: #0{{.*}}Frame0
+//
+// CHECK1: AddressSanitizer: stack-buffer-overflow
+// CHECK1: is located in stack of thread T0 at offset
+// CHECK1-NEXT: #0{{.*}}Frame1
+//
+// CHECK2: AddressSanitizer: stack-buffer-overflow
+// CHECK2: is located in stack of thread T0 at offset
+// CHECK2-NEXT: #0{{.*}}Frame2
+//
+// CHECK3: AddressSanitizer: stack-buffer-overflow
+// CHECK3: is located in stack of thread T0 at offset
+// CHECK3-NEXT: #0{{.*}}Frame3
diff --git a/lib/asan/lit_tests/stack-overflow.cc b/lib/asan/lit_tests/stack-overflow.cc
index 3deb1e91de6c..25ea43af48a4 100644
--- a/lib/asan/lit_tests/stack-overflow.cc
+++ b/lib/asan/lit_tests/stack-overflow.cc
@@ -14,6 +14,7 @@ int main(int argc, char **argv) {
int res = x[argc * 10]; // BOOOM
// CHECK: {{READ of size 1 at 0x.* thread T0}}
// CHECK: {{ #0 0x.* in _?main .*stack-overflow.cc:}}[[@LINE-2]]
- // CHECK: {{Address 0x.* is .* frame <main>}}
+ // CHECK: {{Address 0x.* is located in stack of thread T0 at offset}}
+ // CHECK-NEXT: in{{.*}}main{{.*}}stack-overflow.cc
return res;
}
diff --git a/lib/asan/lit_tests/strncpy-overflow.cc b/lib/asan/lit_tests/strncpy-overflow.cc
index 18711843c4c8..5133b5c1653e 100644
--- a/lib/asan/lit_tests/strncpy-overflow.cc
+++ b/lib/asan/lit_tests/strncpy-overflow.cc
@@ -22,7 +22,7 @@ int main(int argc, char **argv) {
strcpy(hello, "hello");
char *short_buffer = (char*)malloc(9);
strncpy(short_buffer, hello, 10); // BOOM
- // CHECK: {{WRITE of size 1 at 0x.* thread T0}}
+ // CHECK: {{WRITE of size 10 at 0x.* thread T0}}
// CHECK-Linux: {{ #0 0x.* in .*strncpy}}
// CHECK-Darwin: {{ #0 0x.* in _?wrap_strncpy}}
// CHECK: {{ #1 0x.* in _?main .*strncpy-overflow.cc:}}[[@LINE-4]]
@@ -32,9 +32,7 @@ int main(int argc, char **argv) {
// CHECK-Linux: {{ #0 0x.* in .*malloc}}
// CHECK-Linux: {{ #1 0x.* in main .*strncpy-overflow.cc:}}[[@LINE-10]]
- // CHECK-Darwin: {{ #0 0x.* in .*mz_malloc.*}}
- // CHECK-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}}
- // CHECK-Darwin: {{ #2 0x.* in malloc.*}}
- // CHECK-Darwin: {{ #3 0x.* in _?main .*strncpy-overflow.cc:}}[[@LINE-15]]
+ // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}}
+ // CHECK-Darwin: {{ #1 0x.* in _?main .*strncpy-overflow.cc:}}[[@LINE-13]]
return short_buffer[8];
}
diff --git a/lib/asan/lit_tests/throw_call_test.cc b/lib/asan/lit_tests/throw_call_test.cc
new file mode 100644
index 000000000000..974bc51d97c5
--- /dev/null
+++ b/lib/asan/lit_tests/throw_call_test.cc
@@ -0,0 +1,45 @@
+// RUN: %clangxx_asan %s -o %t && %t
+// http://code.google.com/p/address-sanitizer/issues/detail?id=147 (not fixed).
+// BROKEN: %clangxx_asan %s -o %t -static-libstdc++ && %t
+#include <stdio.h>
+static volatile int zero = 0;
+inline void pretend_to_do_something(void *x) {
+ __asm__ __volatile__("" : : "r" (x) : "memory");
+}
+
+__attribute__((noinline, no_sanitize_address))
+void ReallyThrow() {
+ fprintf(stderr, "ReallyThrow\n");
+ if (zero == 0)
+ throw 42;
+}
+
+__attribute__((noinline))
+void Throw() {
+ int a, b, c, d, e;
+ pretend_to_do_something(&a);
+ pretend_to_do_something(&b);
+ pretend_to_do_something(&c);
+ pretend_to_do_something(&d);
+ pretend_to_do_something(&e);
+ fprintf(stderr, "Throw stack = %p\n", &a);
+ ReallyThrow();
+}
+
+__attribute__((noinline))
+void CheckStack() {
+ int ar[100];
+ pretend_to_do_something(ar);
+ for (int i = 0; i < 100; i++)
+ ar[i] = i;
+ fprintf(stderr, "CheckStack stack = %p, %p\n", ar, ar + 100);
+}
+
+int main(int argc, char** argv) {
+ try {
+ Throw();
+ } catch(int a) {
+ fprintf(stderr, "a = %d\n", a);
+ }
+ CheckStack();
+}
diff --git a/lib/asan/lit_tests/throw_invoke_test.cc b/lib/asan/lit_tests/throw_invoke_test.cc
new file mode 100644
index 000000000000..077a940e8d19
--- /dev/null
+++ b/lib/asan/lit_tests/throw_invoke_test.cc
@@ -0,0 +1,50 @@
+// RUN: %clangxx_asan %s -o %t && %t
+// RUN: %clangxx_asan %s -o %t -static-libstdc++ && %t
+#include <stdio.h>
+static volatile int zero = 0;
+inline void pretend_to_do_something(void *x) {
+ __asm__ __volatile__("" : : "r" (x) : "memory");
+}
+
+__attribute__((noinline))
+void ReallyThrow() {
+ fprintf(stderr, "ReallyThrow\n");
+ try {
+ if (zero == 0)
+ throw 42;
+ else if (zero == 1)
+ throw 1.;
+ } catch(double x) {
+ }
+}
+
+__attribute__((noinline))
+void Throw() {
+ int a, b, c, d, e;
+ pretend_to_do_something(&a);
+ pretend_to_do_something(&b);
+ pretend_to_do_something(&c);
+ pretend_to_do_something(&d);
+ pretend_to_do_something(&e);
+ fprintf(stderr, "Throw stack = %p\n", &a);
+ ReallyThrow();
+}
+
+__attribute__((noinline))
+void CheckStack() {
+ int ar[100];
+ pretend_to_do_something(ar);
+ for (int i = 0; i < 100; i++)
+ ar[i] = i;
+ fprintf(stderr, "CheckStack stack = %p, %p\n", ar, ar + 100);
+}
+
+int main(int argc, char** argv) {
+ try {
+ Throw();
+ } catch(int a) {
+ fprintf(stderr, "a = %d\n", a);
+ }
+ CheckStack();
+}
+
diff --git a/lib/asan/lit_tests/time_interceptor.cc b/lib/asan/lit_tests/time_interceptor.cc
new file mode 100644
index 000000000000..f5f2ad62b815
--- /dev/null
+++ b/lib/asan/lit_tests/time_interceptor.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+// Test the time() interceptor.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+int main() {
+ time_t *tm = (time_t*)malloc(sizeof(time_t));
+ free(tm);
+ time_t t = time(tm);
+ printf("Time: %s\n", ctime(&t)); // NOLINT
+ // CHECK: use-after-free
+ return 0;
+}
diff --git a/lib/asan/lit_tests/unaligned_loads_and_stores.cc b/lib/asan/lit_tests/unaligned_loads_and_stores.cc
new file mode 100644
index 000000000000..bcae089b427b
--- /dev/null
+++ b/lib/asan/lit_tests/unaligned_loads_and_stores.cc
@@ -0,0 +1,52 @@
+// RUN: %clangxx_asan -O0 -I %p/../../../include %s -o %t
+// RUN: %t A 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-A %s
+// RUN: %t B 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-B %s
+// RUN: %t C 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-C %s
+// RUN: %t D 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-D %s
+// RUN: %t E 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-E %s
+
+// RUN: %t K 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-K %s
+// RUN: %t L 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-L %s
+// RUN: %t M 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-M %s
+// RUN: %t N 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-N %s
+// RUN: %t O 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-O %s
+
+#include <sanitizer/asan_interface.h>
+
+#include <stdlib.h>
+#include <string.h>
+int main(int argc, char **argv) {
+ if (argc != 2) return 1;
+ char *x = new char[16];
+ memset(x, 0xab, 16);
+ int res = 1;
+ switch (argv[1][0]) {
+ case 'A': res = __sanitizer_unaligned_load16(x + 15); break;
+// CHECK-A ERROR: AddressSanitizer: heap-buffer-overflow on address
+// CHECK-A: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-2]]
+// CHECK-A: is located 0 bytes to the right of 16-byte region
+ case 'B': res = __sanitizer_unaligned_load32(x + 14); break;
+// CHECK-B: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-1]]
+ case 'C': res = __sanitizer_unaligned_load32(x + 13); break;
+// CHECK-C: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-1]]
+ case 'D': res = __sanitizer_unaligned_load64(x + 15); break;
+// CHECK-D: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-1]]
+ case 'E': res = __sanitizer_unaligned_load64(x + 9); break;
+// CHECK-E: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-1]]
+
+ case 'K': __sanitizer_unaligned_store16(x + 15, 0); break;
+// CHECK-K ERROR: AddressSanitizer: heap-buffer-overflow on address
+// CHECK-K: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-2]]
+// CHECK-K: is located 0 bytes to the right of 16-byte region
+ case 'L': __sanitizer_unaligned_store32(x + 15, 0); break;
+// CHECK-L: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-1]]
+ case 'M': __sanitizer_unaligned_store32(x + 13, 0); break;
+// CHECK-M: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-1]]
+ case 'N': __sanitizer_unaligned_store64(x + 10, 0); break;
+// CHECK-N: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-1]]
+ case 'O': __sanitizer_unaligned_store64(x + 14, 0); break;
+// CHECK-O: main{{.*}}unaligned_loads_and_stores.cc:[[@LINE-1]]
+ }
+ delete x;
+ return res;
+}
diff --git a/lib/asan/lit_tests/use-after-free-right.cc b/lib/asan/lit_tests/use-after-free-right.cc
new file mode 100644
index 000000000000..b0de07b04a08
--- /dev/null
+++ b/lib/asan/lit_tests/use-after-free-right.cc
@@ -0,0 +1,46 @@
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out
+// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out
+// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out
+// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out
+// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out
+// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out
+// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out
+// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out
+
+// Test use-after-free report in the case when access is at the right border of
+// the allocation.
+
+#include <stdlib.h>
+int main() {
+ volatile char *x = (char*)malloc(sizeof(char));
+ free((void*)x);
+ *x = 42;
+ // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+ // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
+ // CHECK: {{WRITE of size 1 at 0x.* thread T0}}
+ // CHECK: {{ #0 0x.* in _?main .*use-after-free-right.cc:25}}
+ // CHECK: {{0x.* is located 0 bytes inside of 1-byte region .0x.*,0x.*}}
+ // CHECK: {{freed by thread T0 here:}}
+
+ // CHECK-Linux: {{ #0 0x.* in .*free}}
+ // CHECK-Linux: {{ #1 0x.* in main .*use-after-free-right.cc:24}}
+
+ // CHECK-Darwin: {{ #0 0x.* in _?wrap_free}}
+ // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free-right.cc:24}}
+
+ // CHECK: {{previously allocated by thread T0 here:}}
+
+ // CHECK-Linux: {{ #0 0x.* in .*malloc}}
+ // CHECK-Linux: {{ #1 0x.* in main .*use-after-free-right.cc:23}}
+
+ // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}}
+ // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free-right.cc:23}}
+}
diff --git a/lib/asan/lit_tests/use-after-free.cc b/lib/asan/lit_tests/use-after-free.cc
index 24d5a2a54807..aee185dc4518 100644
--- a/lib/asan/lit_tests/use-after-free.cc
+++ b/lib/asan/lit_tests/use-after-free.cc
@@ -30,19 +30,14 @@ int main() {
// CHECK-Linux: {{ #0 0x.* in .*free}}
// CHECK-Linux: {{ #1 0x.* in main .*use-after-free.cc:21}}
- // CHECK-Darwin: {{ #0 0x.* in .*free_common.*}}
- // CHECK-Darwin: {{ #1 0x.* in .*mz_free.*}}
- // We override free() on Darwin, thus no malloc_zone_free
- // CHECK-Darwin: {{ #2 0x.* in _?wrap_free}}
- // CHECK-Darwin: {{ #3 0x.* in _?main .*use-after-free.cc:21}}
+ // CHECK-Darwin: {{ #0 0x.* in _?wrap_free}}
+ // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free.cc:21}}
// CHECK: {{previously allocated by thread T0 here:}}
// CHECK-Linux: {{ #0 0x.* in .*malloc}}
// CHECK-Linux: {{ #1 0x.* in main .*use-after-free.cc:20}}
- // CHECK-Darwin: {{ #0 0x.* in .*mz_malloc.*}}
- // CHECK-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}}
- // CHECK-Darwin: {{ #2 0x.* in malloc.*}}
- // CHECK-Darwin: {{ #3 0x.* in _?main .*use-after-free.cc:20}}
+ // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}}
+ // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free.cc:20}}
}
diff --git a/lib/asan/lit_tests/use-after-poison.cc b/lib/asan/lit_tests/use-after-poison.cc
new file mode 100644
index 000000000000..d87342900245
--- /dev/null
+++ b/lib/asan/lit_tests/use-after-poison.cc
@@ -0,0 +1,20 @@
+// Check that __asan_poison_memory_region works.
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+//
+// Check that we can disable it
+// RUN: ASAN_OPTIONS=allow_user_poisoning=0 %t
+
+#include <stdlib.h>
+
+extern "C" void __asan_poison_memory_region(void *, size_t);
+
+int main(int argc, char **argv) {
+ char *x = new char[16];
+ x[10] = 0;
+ __asan_poison_memory_region(x, 16);
+ int res = x[argc * 10]; // BOOOM
+ // CHECK: ERROR: AddressSanitizer: use-after-poison
+ // CHECK: main{{.*}}use-after-poison.cc:[[@LINE-2]]
+ delete [] x;
+ return res;
+}
diff --git a/lib/asan/lit_tests/use-after-scope-inlined.cc b/lib/asan/lit_tests/use-after-scope-inlined.cc
index 3d730de6ab35..5c121ea187eb 100644
--- a/lib/asan/lit_tests/use-after-scope-inlined.cc
+++ b/lib/asan/lit_tests/use-after-scope-inlined.cc
@@ -23,7 +23,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 at offset
- // CHECK: [[OFFSET:[^ ]*]] in frame <main> of T0{{.*}}:
+ // CHECK: Address 0x{{.*}} is located in stack of thread T0 at offset
+ // CHECK: [[OFFSET:[^ ]*]] in frame
+ // CHECK: main
// CHECK: {{\[}}[[OFFSET]], {{.*}}) 'x.i'
}
diff --git a/lib/asan/lit_tests/wait.cc b/lib/asan/lit_tests/wait.cc
new file mode 100644
index 000000000000..88fbb17176fa
--- /dev/null
+++ b/lib/asan/lit_tests/wait.cc
@@ -0,0 +1,77 @@
+// RUN: %clangxx_asan -DWAIT -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+// RUN: %clangxx_asan -DWAITPID -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAITPID -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAITPID -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAITPID -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+// RUN: %clangxx_asan -DWAITID -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAITID -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAITID -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAITID -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+// RUN: %clangxx_asan -DWAIT3 -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT3 -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT3 -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT3 -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+// RUN: %clangxx_asan -DWAIT4 -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT4 -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT4 -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT4 -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+// RUN: %clangxx_asan -DWAIT3_RUSAGE -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT3_RUSAGE -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT3_RUSAGE -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT3_RUSAGE -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+// RUN: %clangxx_asan -DWAIT4_RUSAGE -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT4_RUSAGE -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT4_RUSAGE -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -DWAIT4_RUSAGE -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+
+#include <assert.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+ pid_t pid = fork();
+ if (pid) { // parent
+ int x[3];
+ int *status = x + argc * 3;
+ int res;
+#if defined(WAIT)
+ res = wait(status);
+#elif defined(WAITPID)
+ res = waitpid(pid, status, WNOHANG);
+#elif defined(WAITID)
+ siginfo_t *si = (siginfo_t*)(x + argc * 3);
+ res = waitid(P_ALL, 0, si, WEXITED | WNOHANG);
+#elif defined(WAIT3)
+ res = wait3(status, WNOHANG, NULL);
+#elif defined(WAIT4)
+ res = wait4(pid, status, WNOHANG, NULL);
+#elif defined(WAIT3_RUSAGE) || defined(WAIT4_RUSAGE)
+ struct rusage *ru = (struct rusage*)(x + argc * 3);
+ int good_status;
+# if defined(WAIT3_RUSAGE)
+ res = wait3(&good_status, WNOHANG, ru);
+# elif defined(WAIT4_RUSAGE)
+ res = wait4(pid, &good_status, WNOHANG, ru);
+# endif
+#endif
+ // CHECK: stack-buffer-overflow
+ // CHECK: {{WRITE of size .* at 0x.* thread T0}}
+ // CHECK: {{in .*wait}}
+ // CHECK: {{in _?main .*wait.cc:}}
+ // CHECK: is located in stack of thread T0 at offset
+ // CHECK: {{in _?main}}
+ return res != -1;
+ }
+ // child
+ return 0;
+}