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