diff options
| author | Kostya Serebryany <kcc@google.com> | 2013-09-04 14:39:43 +0000 |
|---|---|---|
| committer | Kostya Serebryany <kcc@google.com> | 2013-09-04 14:39:43 +0000 |
| commit | 2e57127cf74c36fe5149a00865b7b8404daa1509 (patch) | |
| tree | 17967775a6f0e18a6b60d20bbb2188b7d880ed2d /compiler-rt/lib | |
| parent | 3a3563d4be1ba20791fe882f8297612ac1354ea2 (diff) | |
| download | bcm5719-llvm-2e57127cf74c36fe5149a00865b7b8404daa1509.tar.gz bcm5719-llvm-2e57127cf74c36fe5149a00865b7b8404daa1509.zip | |
[asan] add a test that demonstrates why the current use-after-return is not signal-safe
llvm-svn: 189943
Diffstat (limited to 'compiler-rt/lib')
| -rw-r--r-- | compiler-rt/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/compiler-rt/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc b/compiler-rt/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc new file mode 100644 index 00000000000..59a2814876f --- /dev/null +++ b/compiler-rt/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc @@ -0,0 +1,66 @@ +// This test shows that the current implementation of use-after-return is +// not signal-safe. +// RUN: %clangxx_asan -O1 %s -o %t -lpthread && %t +// FAILS: %clangxx_asan -fsanitize=use-after-return -O1 %s -o %t -lpthread&& %t +#include <signal.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/time.h> +#include <pthread.h> + +int *g; +int n_signals; + +typedef void (*Sigaction)(int, siginfo_t *, void *); + +void SignalHandler(int, siginfo_t*, void*) { + int local; + g = &local; + n_signals++; + // printf("s: %p\n", &local); +} + +static void EnableSigprof(Sigaction SignalHandler) { + struct sigaction sa; + sa.sa_sigaction = SignalHandler; + sa.sa_flags = SA_RESTART | SA_SIGINFO; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGPROF, &sa, NULL) != 0) { + perror("sigaction"); + abort(); + } + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 1; + timer.it_value = timer.it_interval; + if (setitimer(ITIMER_PROF, &timer, 0) != 0) { + perror("setitimer"); + abort(); + } +} + +void RecursiveFunction(int depth) { + if (depth == 0) return; + int local; + g = &local; + // printf("r: %p\n", &local); + // printf("[%2d] n_signals: %d\n", depth, n_signals); + RecursiveFunction(depth - 1); + RecursiveFunction(depth - 1); +} + +void *Thread(void *) { + RecursiveFunction(18); + return NULL; +} + +int main(int argc, char **argv) { + EnableSigprof(SignalHandler); + + const int kNumThread = 32; + pthread_t t[kNumThread]; + for (int i = 0; i < kNumThread; i++) + pthread_create(&t[i], 0, Thread, 0); + for (int i = 0; i < kNumThread; i++) + pthread_join(t[i], 0); +} |

