Home | History | Annotate | Download | only in Linux
      1 // This test checks that the implementation of use-after-return
      2 // is async-signal-safe.
      3 // RUN: %clangxx_asan -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 
     11 int *g;
     12 int n_signals;
     13 
     14 typedef void (*Sigaction)(int, siginfo_t *, void *);
     15 
     16 void SignalHandler(int, siginfo_t*, void*) {
     17   int local;
     18   g = &local;
     19   n_signals++;
     20   // printf("s: %p\n", &local);
     21 }
     22 
     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 
     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 
     52 void *Thread(void *) {
     53   RecursiveFunction(18);
     54   return NULL;
     55 }
     56 
     57 int main(int argc, char **argv) {
     58   EnableSigprof(SignalHandler);
     59 
     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);
     68   }
     69   fprintf(stderr, "\n");
     70 }
     71