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
14const int kSigCnt = 200;
15int x = 0;
16
17__attribute__((noinline))
18int f(int a) {
19 return a;
20}
21
22__attribute__((noinline))
23void 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
30int sigcnt;
31
32void 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
40int 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

source code of compiler-rt/test/dfsan/sigaction_stress_test.c