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