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 // RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread -fsanitize-address-use-after-return=never && %run %t
5 // RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread -fsanitize-address-use-after-return=always && %run %t
6 // REQUIRES: stable-runtime
12 #include <initializer_list>
17 typedef void (*Sigaction
)(int, siginfo_t
*, void *);
19 void SignalHandler(int, siginfo_t
*, void*) {
25 static void EnableSigprof(Sigaction SignalHandler
) {
27 sa
.sa_sigaction
= SignalHandler
;
28 sa
.sa_flags
= SA_RESTART
| SA_SIGINFO
;
29 sigemptyset(&sa
.sa_mask
);
30 if (sigaction(SIGPROF
, &sa
, NULL
) != 0) {
34 struct itimerval timer
;
35 timer
.it_interval
.tv_sec
= 0;
36 timer
.it_interval
.tv_usec
= 1;
37 timer
.it_value
= timer
.it_interval
;
38 if (setitimer(ITIMER_PROF
, &timer
, 0) != 0) {
44 void RecursiveFunction(int depth
) {
45 if (depth
== 0) return;
48 // printf("r: %p\n", &local);
49 // printf("[%2d] n_signals: %d\n", depth, n_signals);
50 RecursiveFunction(depth
- 1);
51 RecursiveFunction(depth
- 1);
54 void *FastThread(void *) {
59 void *SlowThread(void *) {
64 int main(int argc
, char **argv
) {
65 EnableSigprof(SignalHandler
);
67 for (auto Thread
: {&FastThread
, &SlowThread
}) {
68 for (int i
= 0; i
< 100; i
++) {
70 const int kNumThread
= 8;
71 pthread_t t
[kNumThread
];
72 for (int i
= 0; i
< kNumThread
; i
++)
73 pthread_create(&t
[i
], 0, Thread
, 0);
74 for (int i
= 0; i
< kNumThread
; i
++)
75 pthread_join(t
[i
], 0);
77 fprintf(stderr
, "\n");