blob: 45e24626cbfab4f66d50a38e2cb3f205e9f6bc1c [file] [log] [blame]
Stephen Hines6d186232014-11-26 17:56:19 -08001// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2
3// Test case for longjumping out of signal handler:
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -08004// https://github.com/google/sanitizers/issues/482
Stephen Hines6d186232014-11-26 17:56:19 -08005
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -07006// Longjmp assembly has not been implemented for mips64 yet
7// XFAIL: mips64
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -08008// 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
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070012
Stephen Hines6d186232014-11-26 17:56:19 -080013#include <setjmp.h>
14#include <signal.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <sys/mman.h>
18
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080019#ifdef __APPLE__
20#define SIGNAL_TO_HANDLE SIGBUS
21#else
22#define SIGNAL_TO_HANDLE SIGSEGV
23#endif
24
Stephen Hines6d186232014-11-26 17:56:19 -080025sigjmp_buf fault_jmp;
26volatile int fault_expected;
27
28void 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
48int 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
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080057 if (sigaction(SIGNAL_TO_HANDLE, &act, NULL)) {
Stephen Hines6d186232014-11-26 17:56:19 -080058 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