Home | History | Annotate | Download | only in TestCases
      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 
     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 
     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 
     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