1// Regression test for 2// https://code.google.com/p/address-sanitizer/issues/detail?id=180 3 4// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s 5// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s 6 7#include <signal.h> 8#include <stdio.h> 9#include <stdlib.h> 10 11struct sigaction original_sigaction_sigbus; 12struct sigaction original_sigaction_sigsegv; 13 14void User_OnSIGSEGV(int signum, siginfo_t *siginfo, void *context) { 15 fprintf(stderr, "User sigaction called\n"); 16 struct sigaction original_sigaction; 17 if (signum == SIGBUS) 18 original_sigaction = original_sigaction_sigbus; 19 else if (signum == SIGSEGV) 20 original_sigaction = original_sigaction_sigsegv; 21 else { 22 printf("Invalid signum"); 23 exit(1); 24 } 25 if (original_sigaction.sa_flags | SA_SIGINFO) 26 original_sigaction.sa_sigaction(signum, siginfo, context); 27 else 28 original_sigaction.sa_handler(signum); 29} 30 31int DoSEGV() { 32 volatile int *x = 0; 33 return *x; 34} 35 36int InstallHandler(int signum, struct sigaction *original_sigaction) { 37 struct sigaction user_sigaction; 38 user_sigaction.sa_sigaction = User_OnSIGSEGV; 39 user_sigaction.sa_flags = SA_SIGINFO; 40 if (sigaction(signum, &user_sigaction, original_sigaction)) { 41 perror("sigaction"); 42 return 1; 43 } 44 return 0; 45} 46 47int main() { 48 // Let's install handlers for both SIGSEGV and SIGBUS, since pre-Yosemite 49 // 32-bit Darwin triggers SIGBUS instead. 50 if (InstallHandler(SIGSEGV, &original_sigaction_sigsegv)) return 1; 51 if (InstallHandler(SIGBUS, &original_sigaction_sigbus)) return 1; 52 fprintf(stderr, "User sigaction installed\n"); 53 return DoSEGV(); 54} 55 56// CHECK: User sigaction installed 57// CHECK-NEXT: User sigaction called 58// CHECK-NEXT: ASAN:DEADLYSIGNAL 59// CHECK: AddressSanitizer: SEGV on unknown address 60