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