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