// Regression test for // https://code.google.com/p/address-sanitizer/issues/detail?id=180 // FIXME: Implement. // XFAIL: hwasan // RUN: %clangxx -O0 %s -o %t // RUN: %env_tool_opts=handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 // RUN: %env_tool_opts=handle_segv=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 // RUN: %env_tool_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 // RUN: %env_tool_opts=handle_segv=0:allow_user_segv_handler=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 // RUN: %env_tool_opts=handle_segv=1:allow_user_segv_handler=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 // RUN: %env_tool_opts=handle_segv=2:allow_user_segv_handler=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 // RUN: %env_tool_opts=handle_segv=0:allow_user_segv_handler=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 // RUN: %env_tool_opts=handle_segv=1:allow_user_segv_handler=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 // RUN: %env_tool_opts=handle_segv=2:allow_user_segv_handler=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 // Flaky errors in debuggerd with "waitpid returned unexpected pid (0)" in logcat. // UNSUPPORTED: android && i386-target-arch // Note: this test case is unusual because it retrieves the original // (ASan-installed) signal handler; thus, it is incompatible with the // cloak_sanitizer_signal_handlers runtime option. #include #include #include struct sigaction original_sigaction_sigsegv; void User_OnSIGSEGV(int signum, siginfo_t *siginfo, void *context) { fprintf(stderr, "User sigaction called\n"); struct sigaction original_sigaction = {}; if (signum == SIGSEGV) original_sigaction = original_sigaction_sigsegv; else { printf("Invalid signum"); exit(1); } if (original_sigaction.sa_flags | SA_SIGINFO) { if (original_sigaction.sa_sigaction) original_sigaction.sa_sigaction(signum, siginfo, context); } else { if (original_sigaction.sa_handler) original_sigaction.sa_handler(signum); } exit(1); } bool InstallHandler(int signum, struct sigaction *original_sigaction) { struct sigaction user_sigaction = {}; user_sigaction.sa_sigaction = User_OnSIGSEGV; user_sigaction.sa_flags = SA_SIGINFO; if (sigaction(signum, &user_sigaction, original_sigaction)) { perror("sigaction"); return false; } return true; } int main() { if (InstallHandler(SIGSEGV, &original_sigaction_sigsegv)) fprintf(stderr, "User sigaction installed\n"); // Trying to organically segfault by dereferencing a pointer can be tricky // when the sanitizer runtime is built with assertions. Additionally, some // older platforms may SIGBUS instead. raise(SIGSEGV); return 0; } // CHECK0-NOT: Sanitizer:DEADLYSIGNAL // CHECK0-NOT: Sanitizer: SEGV on unknown address // CHECK0: User sigaction installed // CHECK0-NEXT: User sigaction called // CHECK1: User sigaction installed // CHECK1-NEXT: User sigaction called // CHECK1-NEXT: Sanitizer:DEADLYSIGNAL // CHECK1: Sanitizer: SEGV on unknown address // CHECK2-NOT: User sigaction called // CHECK2: User sigaction installed // CHECK2-NEXT: Sanitizer:DEADLYSIGNAL // CHECK2: Sanitizer: SEGV on unknown address