1 | // RUN: %clangxx_dfsan %s -o %t && %run %t |
2 | // RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 %s -o %t && %run %t |
3 | // RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && %run %t |
4 | // |
5 | // Test that the state of shadows from a sigaction handler are consistent. |
6 | |
7 | #include <signal.h> |
8 | #include <stdarg.h> |
9 | #include <sanitizer/dfsan_interface.h> |
10 | #include <assert.h> |
11 | #include <sys/time.h> |
12 | #include <stdio.h> |
13 | |
14 | const int kSigCnt = 200; |
15 | int x = 0; |
16 | |
17 | __attribute__((noinline)) |
18 | int f(int a) { |
19 | return a; |
20 | } |
21 | |
22 | __attribute__((noinline)) |
23 | void g() { |
24 | int r = f(a: x); |
25 | const dfsan_label r_label = dfsan_get_label(data: r); |
26 | assert(r_label == 8 || r_label == 0); |
27 | return; |
28 | } |
29 | |
30 | int sigcnt; |
31 | |
32 | void SignalHandler(int signo) { |
33 | assert(signo == SIGPROF); |
34 | int a = 0; |
35 | dfsan_set_label(label: 4, addr: &a, size: sizeof(a)); |
36 | (void)f(a); |
37 | ++sigcnt; |
38 | } |
39 | |
40 | int main() { |
41 | struct sigaction psa = {}; |
42 | psa.sa_handler = SignalHandler; |
43 | int r = sigaction(SIGPROF, act: &psa, NULL); |
44 | |
45 | itimerval itv; |
46 | itv.it_interval.tv_sec = 0; |
47 | itv.it_interval.tv_usec = 100; |
48 | itv.it_value.tv_sec = 0; |
49 | itv.it_value.tv_usec = 100; |
50 | setitimer(ITIMER_PROF, new: &itv, NULL); |
51 | |
52 | dfsan_set_label(label: 8, addr: &x, size: sizeof(x)); |
53 | do { |
54 | g(); |
55 | } while (sigcnt < kSigCnt); |
56 | |
57 | itv.it_interval.tv_sec = 0; |
58 | itv.it_interval.tv_usec = 0; |
59 | itv.it_value.tv_sec = 0; |
60 | itv.it_value.tv_usec = 0; |
61 | setitimer(ITIMER_PROF, new: &itv, NULL); |
62 | |
63 | signal(SIGPROF, SIG_DFL); |
64 | return 0; |
65 | } |
66 | |