xref: /llvm-project/compiler-rt/test/asan/TestCases/Linux/uar_signals.cpp (revision a1e78aee66038dbc3ce35b72a52c511490cd3e06)
1 // This test checks that the implementation of use-after-return
2 // is async-signal-safe.
3 // RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread && %run %t
4 // RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread -fsanitize-address-use-after-return=never && %run %t
5 // RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread -fsanitize-address-use-after-return=always && %run %t
6 // REQUIRES: stable-runtime
7 #include <signal.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <sys/time.h>
11 #include <pthread.h>
12 #include <initializer_list>
13 
14 int *g;
15 int n_signals;
16 
17 typedef void (*Sigaction)(int, siginfo_t *, void *);
18 
SignalHandler(int,siginfo_t *,void *)19 void SignalHandler(int, siginfo_t*, void*) {
20   int local;
21   g = &local;
22   n_signals++;
23 }
24 
EnableSigprof(Sigaction SignalHandler)25 static void EnableSigprof(Sigaction SignalHandler) {
26   struct sigaction sa;
27   sa.sa_sigaction = SignalHandler;
28   sa.sa_flags = SA_RESTART | SA_SIGINFO;
29   sigemptyset(&sa.sa_mask);
30   if (sigaction(SIGPROF, &sa, NULL) != 0) {
31     perror("sigaction");
32     abort();
33   }
34   struct itimerval timer;
35   timer.it_interval.tv_sec = 0;
36   timer.it_interval.tv_usec = 1;
37   timer.it_value = timer.it_interval;
38   if (setitimer(ITIMER_PROF, &timer, 0) != 0) {
39     perror("setitimer");
40     abort();
41   }
42 }
43 
RecursiveFunction(int depth)44 void RecursiveFunction(int depth) {
45   if (depth == 0) return;
46   int local;
47   g = &local;
48   // printf("r: %p\n", &local);
49   // printf("[%2d] n_signals: %d\n", depth, n_signals);
50   RecursiveFunction(depth - 1);
51   RecursiveFunction(depth - 1);
52 }
53 
FastThread(void *)54 void *FastThread(void *) {
55   RecursiveFunction(1);
56   return NULL;
57 }
58 
SlowThread(void *)59 void *SlowThread(void *) {
60   RecursiveFunction(1);
61   return NULL;
62 }
63 
main(int argc,char ** argv)64 int main(int argc, char **argv) {
65   EnableSigprof(SignalHandler);
66 
67   for (auto Thread : {&FastThread, &SlowThread}) {
68     for (int i = 0; i < 100; i++) {
69       fprintf(stderr, ".");
70       const int kNumThread = 8;
71       pthread_t t[kNumThread];
72       for (int i = 0; i < kNumThread; i++)
73         pthread_create(&t[i], 0, Thread, 0);
74       for (int i = 0; i < kNumThread; i++)
75         pthread_join(t[i], 0);
76     }
77     fprintf(stderr, "\n");
78   }
79 }
80