]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // This test checks that the implementation of use-after-return |
2 | // is async-signal-safe. | |
92a42be0 SL |
3 | // RUN: %clangxx_asan -O1 %s -o %t -pthread && %run %t |
4 | // REQUIRES: stable-runtime | |
1a4d82fc JJ |
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 | } |