Home | History | Annotate | Download | only in Posix
      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 
     11 struct sigaction original_sigaction_sigbus;
     12 struct sigaction original_sigaction_sigsegv;
     13 
     14 void 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 
     31 int DoSEGV() {
     32   volatile int *x = 0;
     33   return *x;
     34 }
     35 
     36 int 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 
     47 int 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