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