xref: /aosp_15_r20/external/compiler-rt/test/esan/TestCases/workingset-signal-posix.cpp (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot // RUN: %clang_esan_wset -O0 %s -o %t 2>&1
2*7c3d14c8STreehugger Robot // RUN: %run %t 2>&1 | FileCheck %s
3*7c3d14c8STreehugger Robot 
4*7c3d14c8STreehugger Robot #include <assert.h>
5*7c3d14c8STreehugger Robot #include <setjmp.h>
6*7c3d14c8STreehugger Robot #include <signal.h>
7*7c3d14c8STreehugger Robot #include <stdio.h>
8*7c3d14c8STreehugger Robot #include <stdlib.h>
9*7c3d14c8STreehugger Robot #include <sys/mman.h>
10*7c3d14c8STreehugger Robot 
11*7c3d14c8STreehugger Robot sigjmp_buf mark;
12*7c3d14c8STreehugger Robot 
SignalHandler(int Sig)13*7c3d14c8STreehugger Robot static void SignalHandler(int Sig) {
14*7c3d14c8STreehugger Robot   if (Sig == SIGSEGV) {
15*7c3d14c8STreehugger Robot     fprintf(stderr, "Handling SIGSEGV for signal\n");
16*7c3d14c8STreehugger Robot     siglongjmp(mark, 1);
17*7c3d14c8STreehugger Robot   }
18*7c3d14c8STreehugger Robot   exit(1);
19*7c3d14c8STreehugger Robot }
20*7c3d14c8STreehugger Robot 
SigactionHandler(int Sig,siginfo_t * Info,void * Ctx)21*7c3d14c8STreehugger Robot static void SigactionHandler(int Sig, siginfo_t *Info, void *Ctx) {
22*7c3d14c8STreehugger Robot   if (Sig == SIGSEGV) {
23*7c3d14c8STreehugger Robot     fprintf(stderr, "Handling SIGSEGV for sigaction\n");
24*7c3d14c8STreehugger Robot     siglongjmp(mark, 1);
25*7c3d14c8STreehugger Robot   }
26*7c3d14c8STreehugger Robot   exit(1);
27*7c3d14c8STreehugger Robot }
28*7c3d14c8STreehugger Robot 
main(int argc,char ** argv)29*7c3d14c8STreehugger Robot int main(int argc, char **argv) {
30*7c3d14c8STreehugger Robot   __sighandler_t Prior = signal(SIGSEGV, SignalHandler);
31*7c3d14c8STreehugger Robot   assert(Prior == SIG_DFL);
32*7c3d14c8STreehugger Robot   if (sigsetjmp(mark, 1) == 0)
33*7c3d14c8STreehugger Robot     *((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV
34*7c3d14c8STreehugger Robot   fprintf(stderr, "Past longjmp for signal\n");
35*7c3d14c8STreehugger Robot 
36*7c3d14c8STreehugger Robot   Prior = signal(SIGSEGV, SIG_DFL);
37*7c3d14c8STreehugger Robot   assert(Prior == SignalHandler);
38*7c3d14c8STreehugger Robot 
39*7c3d14c8STreehugger Robot   struct sigaction SigAct;
40*7c3d14c8STreehugger Robot   SigAct.sa_sigaction = SigactionHandler;
41*7c3d14c8STreehugger Robot   int Res = sigfillset(&SigAct.sa_mask);
42*7c3d14c8STreehugger Robot   assert(Res == 0);
43*7c3d14c8STreehugger Robot   SigAct.sa_flags = SA_SIGINFO;
44*7c3d14c8STreehugger Robot   Res = sigaction(SIGSEGV, &SigAct, NULL);
45*7c3d14c8STreehugger Robot   assert(Res == 0);
46*7c3d14c8STreehugger Robot 
47*7c3d14c8STreehugger Robot   if (sigsetjmp(mark, 1) == 0)
48*7c3d14c8STreehugger Robot     *((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV
49*7c3d14c8STreehugger Robot   fprintf(stderr, "Past longjmp for sigaction\n");
50*7c3d14c8STreehugger Robot 
51*7c3d14c8STreehugger Robot   Res = sigaction(SIGSEGV, NULL, &SigAct);
52*7c3d14c8STreehugger Robot   assert(Res == 0);
53*7c3d14c8STreehugger Robot   assert(SigAct.sa_sigaction == SigactionHandler);
54*7c3d14c8STreehugger Robot 
55*7c3d14c8STreehugger Robot   // Test blocking SIGSEGV and raising a shadow fault.
56*7c3d14c8STreehugger Robot   sigset_t Set;
57*7c3d14c8STreehugger Robot   sigemptyset(&Set);
58*7c3d14c8STreehugger Robot   sigaddset(&Set, SIGSEGV);
59*7c3d14c8STreehugger Robot   Res = sigprocmask(SIG_BLOCK, &Set, NULL);
60*7c3d14c8STreehugger Robot   // Make a large enough mapping that its start point will be before any
61*7c3d14c8STreehugger Robot   // prior library-region shadow access.
62*7c3d14c8STreehugger Robot   char *buf = (char *)mmap(0, 640*1024, PROT_READ | PROT_WRITE,
63*7c3d14c8STreehugger Robot                            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
64*7c3d14c8STreehugger Robot   buf[0] = 4;
65*7c3d14c8STreehugger Robot   munmap(buf, 640*1024);
66*7c3d14c8STreehugger Robot   fprintf(stderr, "Past blocked-SIGSEGV shadow fault\n");
67*7c3d14c8STreehugger Robot 
68*7c3d14c8STreehugger Robot   return 0;
69*7c3d14c8STreehugger Robot }
70*7c3d14c8STreehugger Robot // CHECK:      Handling SIGSEGV for signal
71*7c3d14c8STreehugger Robot // CHECK-NEXT: Past longjmp for signal
72*7c3d14c8STreehugger Robot // CHECK-NEXT: Handling SIGSEGV for sigaction
73*7c3d14c8STreehugger Robot // CHECK-NEXT: Past longjmp for sigaction
74*7c3d14c8STreehugger Robot // CHECK-NEXT: Past blocked-SIGSEGV shadow fault
75*7c3d14c8STreehugger Robot // CHECK:      {{.*}} EfficiencySanitizer: the total working set size: {{[0-9]+}} Bytes ({{[0-9][0-9]}} cache lines)
76