Move ASan lit-tests under test/asan
[blocksruntime.git] / test / asan / TestCases / Linux / uar_signals.cc
blob9663859dfefdde2bacaeedb7404dfa227f321d37
1 // This test shows that the current implementation of use-after-return is
2 // not signal-safe.
3 // RUN: %clangxx_asan -O1 %s -o %t -lpthread && %t
4 // RUN: %clangxx_asan -O1 %s -o %t -lpthread && %t
5 #include <signal.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <sys/time.h>
9 #include <pthread.h>
11 int *g;
12 int n_signals;
14 typedef void (*Sigaction)(int, siginfo_t *, void *);
16 void SignalHandler(int, siginfo_t*, void*) {
17 int local;
18 g = &local;
19 n_signals++;
20 // printf("s: %p\n", &local);
23 static void EnableSigprof(Sigaction SignalHandler) {
24 struct sigaction sa;
25 sa.sa_sigaction = SignalHandler;
26 sa.sa_flags = SA_RESTART | SA_SIGINFO;
27 sigemptyset(&sa.sa_mask);
28 if (sigaction(SIGPROF, &sa, NULL) != 0) {
29 perror("sigaction");
30 abort();
32 struct itimerval timer;
33 timer.it_interval.tv_sec = 0;
34 timer.it_interval.tv_usec = 1;
35 timer.it_value = timer.it_interval;
36 if (setitimer(ITIMER_PROF, &timer, 0) != 0) {
37 perror("setitimer");
38 abort();
42 void RecursiveFunction(int depth) {
43 if (depth == 0) return;
44 int local;
45 g = &local;
46 // printf("r: %p\n", &local);
47 // printf("[%2d] n_signals: %d\n", depth, n_signals);
48 RecursiveFunction(depth - 1);
49 RecursiveFunction(depth - 1);
52 void *Thread(void *) {
53 RecursiveFunction(18);
54 return NULL;
57 int main(int argc, char **argv) {
58 EnableSigprof(SignalHandler);
60 for (int i = 0; i < 4; i++) {
61 fprintf(stderr, ".");
62 const int kNumThread = sizeof(void*) == 8 ? 16 : 8;
63 pthread_t t[kNumThread];
64 for (int i = 0; i < kNumThread; i++)
65 pthread_create(&t[i], 0, Thread, 0);
66 for (int i = 0; i < kNumThread; i++)
67 pthread_join(t[i], 0);
69 fprintf(stderr, "\n");