1 // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s 2 3 // Test case for longjumping out of signal handler: 4 // https://github.com/google/sanitizers/issues/482 5 6 // Longjmp assembly has not been implemented for mips64 yet 7 // XFAIL: mips64 8 // This test fails on powerpc64 BE (VMA=44), a segmentation fault 9 // error happens at the second assignment 10 // "((volatile int *volatile)mem)[1] = 1". 11 // XFAIL: powerpc64-unknown-linux-gnu 12 13 #include <setjmp.h> 14 #include <signal.h> 15 #include <stdlib.h> 16 #include <stdio.h> 17 #include <sys/mman.h> 18 19 #ifdef __APPLE__ 20 #define SIGNAL_TO_HANDLE SIGBUS 21 #else 22 #define SIGNAL_TO_HANDLE SIGSEGV 23 #endif 24 25 sigjmp_buf fault_jmp; 26 volatile int fault_expected; 27 28 void sigfault_handler(int sig) { 29 if (!fault_expected) 30 abort(); 31 32 /* just return from sighandler to proper place */ 33 fault_expected = 0; 34 siglongjmp(fault_jmp, 1); 35 } 36 37 #define MUST_FAULT(code) do { \ 38 fault_expected = 1; \ 39 if (!sigsetjmp(fault_jmp, 1)) { \ 40 code; /* should pagefault -> sihandler does longjmp */ \ 41 fprintf(stderr, "%s not faulted\n", #code); \ 42 abort(); \ 43 } else { \ 44 fprintf(stderr, "%s faulted ok\n", #code); \ 45 } \ 46 } while (0) 47 48 int main() { 49 struct sigaction act; 50 act.sa_handler = sigfault_handler; 51 act.sa_flags = 0; 52 if (sigemptyset(&act.sa_mask)) { 53 perror("sigemptyset"); 54 exit(1); 55 } 56 57 if (sigaction(SIGNAL_TO_HANDLE, &act, NULL)) { 58 perror("sigaction"); 59 exit(1); 60 } 61 62 void *mem = mmap(0, 4096, PROT_NONE, MAP_PRIVATE | MAP_ANON, 63 -1, 0); 64 65 MUST_FAULT(((volatile int *volatile)mem)[0] = 0); 66 MUST_FAULT(((volatile int *volatile)mem)[1] = 1); 67 MUST_FAULT(((volatile int *volatile)mem)[3] = 1); 68 69 // Ensure that tsan does not think that we are 70 // in a signal handler. 71 void *volatile p = malloc(10); 72 ((volatile int*)p)[1] = 1; 73 free((void*)p); 74 75 munmap(p, 4096); 76 77 fprintf(stderr, "DONE\n"); 78 return 0; 79 } 80 81 // CHECK-NOT: WARNING: ThreadSanitizer 82 // CHECK: DONE 83