diff options
Diffstat (limited to 'test/sanitizer_common/TestCases')
-rw-r--r-- | test/sanitizer_common/TestCases/Linux/assert.cc | 24 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc | 3 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/Linux/open_memstream.cc | 1 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc | 48 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc | 60 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/Posix/lit.local.cfg | 9 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/strcasestr.c | 16 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/strcspn.c | 13 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/strpbrk.c | 14 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/strspn.c | 13 | ||||
-rw-r--r-- | test/sanitizer_common/TestCases/strstr.c | 12 |
11 files changed, 212 insertions, 1 deletions
diff --git a/test/sanitizer_common/TestCases/Linux/assert.cc b/test/sanitizer_common/TestCases/Linux/assert.cc new file mode 100644 index 0000000000000..7f9b0a061da04 --- /dev/null +++ b/test/sanitizer_common/TestCases/Linux/assert.cc @@ -0,0 +1,24 @@ +// Test the handle_abort option. +// RUN: %clang %s -o %t +// RUN: not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s +// RUN: %tool_options=handle_abort=0 not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s +// RUN: %tool_options=handle_abort=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s +// FIXME: implement in other sanitizers, not just asan. +// XFAIL: msan +// XFAIL: lsan +// XFAIL: tsan +#include <assert.h> +#include <stdio.h> +#include <sanitizer/asan_interface.h> + +void death() { + fprintf(stderr, "DEATH CALLBACK\n"); +} + +int main(int argc, char **argv) { + __sanitizer_set_death_callback(death); + assert(argc == 100); +} +// CHECK1: ERROR: {{.*}}Sanitizer: +// CHECK1: DEATH CALLBACK +// CHECK0-NOT: Sanitizer diff --git a/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc b/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc index a8b51d7a99c07..c0d6cfea1fbef 100644 --- a/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc +++ b/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc @@ -2,6 +2,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t #include <assert.h> +#include <errno.h> #include <pwd.h> #include <signal.h> #include <stdio.h> @@ -13,7 +14,7 @@ int main(void) { struct passwd *pwdres; char buf[10000]; int res = getpwnam_r("no-such-user", &pwd, buf, sizeof(buf), &pwdres); - assert(res == 0); + assert(res == 0 || res == ENOENT); assert(pwdres == 0); return 0; } diff --git a/test/sanitizer_common/TestCases/Linux/open_memstream.cc b/test/sanitizer_common/TestCases/Linux/open_memstream.cc index 6abe0bfb14831..69097c094a93b 100644 --- a/test/sanitizer_common/TestCases/Linux/open_memstream.cc +++ b/test/sanitizer_common/TestCases/Linux/open_memstream.cc @@ -1,5 +1,6 @@ // RUN: %clangxx -m64 -O0 -g -xc++ %s -o %t && %run %t // RUN: %clangxx -m64 -O3 -g -xc++ %s -o %t && %run %t +// REQUIRES: x86_64-supported-target #include <assert.h> #include <stdio.h> diff --git a/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc b/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc new file mode 100644 index 0000000000000..643fb48ae7734 --- /dev/null +++ b/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc @@ -0,0 +1,48 @@ +// RUN: %clangxx -O1 %s -o %t && TSAN_OPTIONS="flush_memory_ms=1 memory_limit_mb=1" ASAN_OPTIONS="handle_segv=0 allow_user_segv_handler=1" %run %t 2>&1 | FileCheck %s + +// JVM uses SEGV to preempt threads. All threads do a load from a known address +// periodically. When runtime needs to preempt threads, it unmaps the page. +// Threads start triggering SEGV one by one. The signal handler blocks +// threads while runtime does its thing. Then runtime maps the page again +// and resumes the threads. +// Previously this pattern conflicted with stop-the-world machinery, +// because it briefly reset SEGV handler to SIG_DFL. +// As the consequence JVM just silently died. + +// This test sets memory flushing rate to maximum, then does series of +// "benign" SEGVs that are handled by signal handler, and ensures that +// the process survive. + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <sys/mman.h> +#include <string.h> +#include <unistd.h> + +unsigned long page_size; +void *guard; + +void handler(int signo, siginfo_t *info, void *uctx) { + mprotect(guard, page_size, PROT_READ | PROT_WRITE); +} + +int main() { + page_size = sysconf(_SC_PAGESIZE); + struct sigaction a, old; + memset(&a, 0, sizeof(a)); + memset(&old, 0, sizeof(old)); + a.sa_sigaction = handler; + a.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &a, &old); + guard = mmap(0, 3 * page_size, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0); + guard = (char*)guard + page_size; // work around a kernel bug + for (int i = 0; i < 1000000; i++) { + mprotect(guard, page_size, PROT_NONE); + *(int*)guard = 1; + } + sigaction(SIGSEGV, &old, 0); + fprintf(stderr, "DONE\n"); +} + +// CHECK: DONE diff --git a/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc b/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc new file mode 100644 index 0000000000000..6224717676551 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc @@ -0,0 +1,60 @@ +// RUN: %clangxx -g %s -o %t +// RUN: %tool_options=decorate_proc_maps=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%tool_name +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +bool CopyFdToFd(int in_fd, int out_fd) { + const size_t kBufSize = 0x10000; + static char buf[kBufSize]; + while (true) { + ssize_t got = read(in_fd, buf, kBufSize); + if (got > 0) { + write(out_fd, buf, got); + } else if (got == 0) { + break; + } else if (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR) { + fprintf(stderr, "error reading file, errno %d\n", errno); + return false; + } + } + return true; +} + +void *ThreadFn(void *arg) { + (void)arg; + int fd = open("/proc/self/maps", O_RDONLY); + bool res = CopyFdToFd(fd, 2); + close(fd); + return (void *)!res; +} + +int main(void) { + pthread_t t; + void *res; + pthread_create(&t, 0, ThreadFn, 0); + pthread_join(t, &res); + return (int)(size_t)res; +} + +// CHECK-asan: rw-p {{.*}} [low shadow] +// CHECK-asan: ---p {{.*}} [shadow gap] +// CHECK-asan: rw-p {{.*}} [high shadow] + +// CHECK-msan: ---p {{.*}} [invalid] +// CHECK-msan: rw-p {{.*}} [shadow] +// CHECK-msan: ---p {{.*}} [origin] + +// CHECK-tsan: rw-p {{.*}} [shadow] +// CHECK-tsan: rw-p {{.*}} [meta shadow] +// CHECK-tsan: rw-p {{.*}} [trace 0] +// CHECK-tsan: rw-p {{.*}} [trace header 0] +// CHECK-tsan: rw-p {{.*}} [trace 1] +// CHECK-tsan: rw-p {{.*}} [trace header 1] + +// Nothing interesting with standalone LSan. +// CHECK-lsan: decorate_proc_maps diff --git a/test/sanitizer_common/TestCases/Posix/lit.local.cfg b/test/sanitizer_common/TestCases/Posix/lit.local.cfg new file mode 100644 index 0000000000000..a6d96d3054cf6 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/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 in ['Windows', 'Darwin']: + config.unsupported = True diff --git a/test/sanitizer_common/TestCases/strcasestr.c b/test/sanitizer_common/TestCases/strcasestr.c new file mode 100644 index 0000000000000..4de3cac7e2537 --- /dev/null +++ b/test/sanitizer_common/TestCases/strcasestr.c @@ -0,0 +1,16 @@ +// RUN: %clang %s -o %t && %run %t 2>&1 + +// There's no interceptor for strcasestr on Windows +// XFAIL: win32 + +#define _GNU_SOURCE +#include <assert.h> +#include <string.h> +int main(int argc, char **argv) { + char *r = 0; + char s1[] = "aB"; + char s2[] = "b"; + r = strcasestr(s1, s2); + assert(r == s1 + 1); + return 0; +} diff --git a/test/sanitizer_common/TestCases/strcspn.c b/test/sanitizer_common/TestCases/strcspn.c new file mode 100644 index 0000000000000..066a27bbdf2cf --- /dev/null +++ b/test/sanitizer_common/TestCases/strcspn.c @@ -0,0 +1,13 @@ +// RUN: %clang %s -o %t && %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t r; + char s1[] = "ad"; + char s2[] = "cd"; + r = strcspn(s1, s2); + assert(r == 1); + return 0; +} diff --git a/test/sanitizer_common/TestCases/strpbrk.c b/test/sanitizer_common/TestCases/strpbrk.c new file mode 100644 index 0000000000000..318e3a4977f22 --- /dev/null +++ b/test/sanitizer_common/TestCases/strpbrk.c @@ -0,0 +1,14 @@ +// RUN: %clang %s -o %t && %run %t 2>&1 + +#include <assert.h> +#include <string.h> + + +int main(int argc, char **argv) { + char *r = 0; + char s1[] = "ad"; + char s2[] = "cd"; + r = strpbrk(s1, s2); + assert(r == s1 + 1); + return 0; +} diff --git a/test/sanitizer_common/TestCases/strspn.c b/test/sanitizer_common/TestCases/strspn.c new file mode 100644 index 0000000000000..a9a24305c6f1d --- /dev/null +++ b/test/sanitizer_common/TestCases/strspn.c @@ -0,0 +1,13 @@ +// RUN: %clang %s -o %t && %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t r; + char s1[] = "ab"; + char s2[] = "ac"; + r = strspn(s1, s2); + assert(r == 1); + return 0; +} diff --git a/test/sanitizer_common/TestCases/strstr.c b/test/sanitizer_common/TestCases/strstr.c new file mode 100644 index 0000000000000..2089ac7b5fcbd --- /dev/null +++ b/test/sanitizer_common/TestCases/strstr.c @@ -0,0 +1,12 @@ +// RUN: %clang %s -o %t && %run %t 2>&1 + +#include <assert.h> +#include <string.h> +int main(int argc, char **argv) { + char *r = 0; + char s1[] = "ab"; + char s2[] = "b"; + r = strstr(s1, s2); + assert(r == s1 + 1); + return 0; +} |