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