blob: 69c1df9a1d3fe3a8c42033efbe6ad372516f5087 [file] [log] [blame]
Stephen Hines2d1fdb22014-05-28 23:58:16 -07001// Regression test for
2// https://code.google.com/p/address-sanitizer/issues/detail?id=180
3
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -08004// 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
Stephen Hines2d1fdb22014-05-28 23:58:16 -07006
7#include <signal.h>
8#include <stdio.h>
Stephen Hines6d186232014-11-26 17:56:19 -08009#include <stdlib.h>
Stephen Hines2d1fdb22014-05-28 23:58:16 -070010
Stephen Hines6d186232014-11-26 17:56:19 -080011struct sigaction original_sigaction_sigbus;
12struct sigaction original_sigaction_sigsegv;
Stephen Hines2d1fdb22014-05-28 23:58:16 -070013
14void User_OnSIGSEGV(int signum, siginfo_t *siginfo, void *context) {
15 fprintf(stderr, "User sigaction called\n");
Stephen Hines6d186232014-11-26 17:56:19 -080016 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 }
Stephen Hines2d1fdb22014-05-28 23:58:16 -070025 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
Stephen Hines6d186232014-11-26 17:56:19 -080036int InstallHandler(int signum, struct sigaction *original_sigaction) {
37 struct sigaction user_sigaction;
Stephen Hines2d1fdb22014-05-28 23:58:16 -070038 user_sigaction.sa_sigaction = User_OnSIGSEGV;
39 user_sigaction.sa_flags = SA_SIGINFO;
Stephen Hines6d186232014-11-26 17:56:19 -080040 if (sigaction(signum, &user_sigaction, original_sigaction)) {
Stephen Hines2d1fdb22014-05-28 23:58:16 -070041 perror("sigaction");
42 return 1;
43 }
Stephen Hines6d186232014-11-26 17:56:19 -080044 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;
Stephen Hines2d1fdb22014-05-28 23:58:16 -070052 fprintf(stderr, "User sigaction installed\n");
53 return DoSEGV();
54}
55
56// CHECK: User sigaction installed
57// CHECK-NEXT: User sigaction called
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080058// CHECK-NEXT: ASAN:DEADLYSIGNAL
Stephen Hines2d1fdb22014-05-28 23:58:16 -070059// CHECK: AddressSanitizer: SEGV on unknown address