]> git.proxmox.com Git - rustc.git/blob - src/compiler-rt/test/tsan/signal_longjmp.cc
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / compiler-rt / test / tsan / signal_longjmp.cc
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://code.google.com/p/thread-sanitizer/issues/detail?id=75
5
6 // Longjmp assembly has not been implemented for mips64 or aarch64 yet
7 // XFAIL: mips64
8 // XFAIL: aarch64
9
10 #include <setjmp.h>
11 #include <signal.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <sys/mman.h>
15
16 sigjmp_buf fault_jmp;
17 volatile int fault_expected;
18
19 void sigfault_handler(int sig) {
20 if (!fault_expected)
21 abort();
22
23 /* just return from sighandler to proper place */
24 fault_expected = 0;
25 siglongjmp(fault_jmp, 1);
26 }
27
28 #define MUST_FAULT(code) do { \
29 fault_expected = 1; \
30 if (!sigsetjmp(fault_jmp, 1)) { \
31 code; /* should pagefault -> sihandler does longjmp */ \
32 fprintf(stderr, "%s not faulted\n", #code); \
33 abort(); \
34 } else { \
35 fprintf(stderr, "%s faulted ok\n", #code); \
36 } \
37 } while (0)
38
39 int main() {
40 struct sigaction act;
41 act.sa_handler = sigfault_handler;
42 act.sa_flags = 0;
43 if (sigemptyset(&act.sa_mask)) {
44 perror("sigemptyset");
45 exit(1);
46 }
47
48 if (sigaction(SIGSEGV, &act, NULL)) {
49 perror("sigaction");
50 exit(1);
51 }
52
53 void *mem = mmap(0, 4096, PROT_NONE, MAP_PRIVATE | MAP_ANON,
54 -1, 0);
55
56 MUST_FAULT(((volatile int *volatile)mem)[0] = 0);
57 MUST_FAULT(((volatile int *volatile)mem)[1] = 1);
58 MUST_FAULT(((volatile int *volatile)mem)[3] = 1);
59
60 // Ensure that tsan does not think that we are
61 // in a signal handler.
62 void *volatile p = malloc(10);
63 ((volatile int*)p)[1] = 1;
64 free((void*)p);
65
66 munmap(p, 4096);
67
68 fprintf(stderr, "DONE\n");
69 return 0;
70 }
71
72 // CHECK-NOT: WARNING: ThreadSanitizer
73 // CHECK: DONE