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