• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // REQUIRES: stable-runtime
5 #include <signal.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <sys/time.h>
9 #include <pthread.h>
10 #include <initializer_list>
11 
12 int *g;
13 int n_signals;
14 
15 typedef void (*Sigaction)(int, siginfo_t *, void *);
16 
SignalHandler(int,siginfo_t *,void *)17 void SignalHandler(int, siginfo_t*, void*) {
18   int local;
19   g = &local;
20   n_signals++;
21 }
22 
EnableSigprof(Sigaction SignalHandler)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();
31   }
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();
39   }
40 }
41 
RecursiveFunction(int depth)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);
50 }
51 
FastThread(void *)52 void *FastThread(void *) {
53   RecursiveFunction(1);
54   return NULL;
55 }
56 
SlowThread(void *)57 void *SlowThread(void *) {
58   RecursiveFunction(1);
59   return NULL;
60 }
61 
main(int argc,char ** argv)62 int main(int argc, char **argv) {
63   EnableSigprof(SignalHandler);
64 
65   for (auto Thread : {&FastThread, &SlowThread}) {
66     for (int i = 0; i < 1000; i++) {
67       fprintf(stderr, ".");
68       const int kNumThread = sizeof(void*) == 8 ? 32 : 8;
69       pthread_t t[kNumThread];
70       for (int i = 0; i < kNumThread; i++)
71         pthread_create(&t[i], 0, Thread, 0);
72       for (int i = 0; i < kNumThread; i++)
73         pthread_join(t[i], 0);
74     }
75     fprintf(stderr, "\n");
76   }
77 }
78