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
sigfault_handler(int sig)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
main()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