xref: /aosp_15_r20/external/compiler-rt/test/msan/signal_stress_test.cc (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot // RUN: %clangxx_msan -std=c++11 -O0 %s -o %t && %run %t
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot // Test that va_arg shadow from a signal handler does not leak outside.
4*7c3d14c8STreehugger Robot 
5*7c3d14c8STreehugger Robot #include <signal.h>
6*7c3d14c8STreehugger Robot #include <stdarg.h>
7*7c3d14c8STreehugger Robot #include <sanitizer/msan_interface.h>
8*7c3d14c8STreehugger Robot #include <assert.h>
9*7c3d14c8STreehugger Robot #include <sys/time.h>
10*7c3d14c8STreehugger Robot #include <stdio.h>
11*7c3d14c8STreehugger Robot 
12*7c3d14c8STreehugger Robot const int kSigCnt = 200;
13*7c3d14c8STreehugger Robot 
f(bool poisoned,int n,...)14*7c3d14c8STreehugger Robot void f(bool poisoned, int n, ...) {
15*7c3d14c8STreehugger Robot   va_list vl;
16*7c3d14c8STreehugger Robot   va_start(vl, n);
17*7c3d14c8STreehugger Robot   for (int i = 0; i < n; ++i) {
18*7c3d14c8STreehugger Robot     void *p = va_arg(vl, void *);
19*7c3d14c8STreehugger Robot     if (!poisoned)
20*7c3d14c8STreehugger Robot       assert(__msan_test_shadow(&p, sizeof(p)) == -1);
21*7c3d14c8STreehugger Robot   }
22*7c3d14c8STreehugger Robot   va_end(vl);
23*7c3d14c8STreehugger Robot }
24*7c3d14c8STreehugger Robot 
25*7c3d14c8STreehugger Robot int sigcnt;
26*7c3d14c8STreehugger Robot 
SignalHandler(int signo)27*7c3d14c8STreehugger Robot void SignalHandler(int signo) {
28*7c3d14c8STreehugger Robot   assert(signo == SIGPROF);
29*7c3d14c8STreehugger Robot   void *p;
30*7c3d14c8STreehugger Robot   void **volatile q = &p;
31*7c3d14c8STreehugger Robot   f(true, 10,
32*7c3d14c8STreehugger Robot     *q, *q, *q, *q, *q,
33*7c3d14c8STreehugger Robot     *q, *q, *q, *q, *q);
34*7c3d14c8STreehugger Robot   ++sigcnt;
35*7c3d14c8STreehugger Robot }
36*7c3d14c8STreehugger Robot 
main()37*7c3d14c8STreehugger Robot int main() {
38*7c3d14c8STreehugger Robot   signal(SIGPROF, SignalHandler);
39*7c3d14c8STreehugger Robot 
40*7c3d14c8STreehugger Robot   itimerval itv;
41*7c3d14c8STreehugger Robot   itv.it_interval.tv_sec = 0;
42*7c3d14c8STreehugger Robot   itv.it_interval.tv_usec = 100;
43*7c3d14c8STreehugger Robot   itv.it_value.tv_sec = 0;
44*7c3d14c8STreehugger Robot   itv.it_value.tv_usec = 100;
45*7c3d14c8STreehugger Robot   setitimer(ITIMER_PROF, &itv, NULL);
46*7c3d14c8STreehugger Robot 
47*7c3d14c8STreehugger Robot   void *p;
48*7c3d14c8STreehugger Robot   void **volatile q = &p;
49*7c3d14c8STreehugger Robot 
50*7c3d14c8STreehugger Robot   do {
51*7c3d14c8STreehugger Robot     f(false, 20,
52*7c3d14c8STreehugger Robot       nullptr, nullptr, nullptr, nullptr, nullptr,
53*7c3d14c8STreehugger Robot       nullptr, nullptr, nullptr, nullptr, nullptr,
54*7c3d14c8STreehugger Robot       nullptr, nullptr, nullptr, nullptr, nullptr,
55*7c3d14c8STreehugger Robot       nullptr, nullptr, nullptr, nullptr, nullptr);
56*7c3d14c8STreehugger Robot     f(true, 20,
57*7c3d14c8STreehugger Robot       *q, *q, *q, *q, *q,
58*7c3d14c8STreehugger Robot       *q, *q, *q, *q, *q,
59*7c3d14c8STreehugger Robot       *q, *q, *q, *q, *q,
60*7c3d14c8STreehugger Robot       *q, *q, *q, *q, *q);
61*7c3d14c8STreehugger Robot   } while (sigcnt < kSigCnt);
62*7c3d14c8STreehugger Robot 
63*7c3d14c8STreehugger Robot   itv.it_interval.tv_sec = 0;
64*7c3d14c8STreehugger Robot   itv.it_interval.tv_usec = 0;
65*7c3d14c8STreehugger Robot   itv.it_value.tv_sec = 0;
66*7c3d14c8STreehugger Robot   itv.it_value.tv_usec = 0;
67*7c3d14c8STreehugger Robot   setitimer(ITIMER_PROF, &itv, NULL);
68*7c3d14c8STreehugger Robot 
69*7c3d14c8STreehugger Robot   signal(SIGPROF, SIG_DFL);
70*7c3d14c8STreehugger Robot   return 0;
71*7c3d14c8STreehugger Robot }
72