xref: /llvm-project/compiler-rt/test/dfsan/sigaction_stress_test.c (revision 975327a609e55ad9c53bfeee63443128ce20006c)
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))
f(int a)18 int f(int a) {
19   return a;
20 }
21 
22 __attribute__((noinline))
g()23 void g() {
24   int r = f(x);
25   const dfsan_label r_label = dfsan_get_label(r);
26   assert(r_label == 8 || r_label == 0);
27   return;
28 }
29 
30 int sigcnt;
31 
SignalHandler(int signo)32 void SignalHandler(int signo) {
33   assert(signo == SIGPROF);
34   int a = 0;
35   dfsan_set_label(4, &a, sizeof(a));
36   (void)f(a);
37   ++sigcnt;
38 }
39 
main()40 int main() {
41   struct sigaction psa = {};
42   psa.sa_handler = SignalHandler;
43   int r = sigaction(SIGPROF, &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, &itv, NULL);
51 
52   dfsan_set_label(8, &x, 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, &itv, NULL);
62 
63   signal(SIGPROF, SIG_DFL);
64   return 0;
65 }
66