1 | // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-DIE |
2 | // RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=die_after_fork=0 %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-NODIE |
3 | #include "test.h" |
4 | #include <errno.h> |
5 | #include <sys/types.h> |
6 | #include <sys/wait.h> |
7 | |
8 | static void *sleeper(void *p) { |
9 | sleep(1000); // not intended to exit during test |
10 | return 0; |
11 | } |
12 | |
13 | static void *nop(void *p) { |
14 | return 0; |
15 | } |
16 | |
17 | int main() { |
18 | barrier_init(&barrier, 2); |
19 | pthread_t th; |
20 | pthread_create(&th, 0, sleeper, 0); |
21 | switch (fork()) { |
22 | default: // parent |
23 | while (wait(0) < 0) {} |
24 | break; |
25 | case 0: // child |
26 | { |
27 | pthread_t th2; |
28 | pthread_create(&th2, 0, nop, 0); |
29 | exit(0); |
30 | break; |
31 | } |
32 | case -1: // error |
33 | fprintf(stderr, "failed to fork (%d)\n" , errno); |
34 | exit(1); |
35 | } |
36 | fprintf(stderr, "OK\n" ); |
37 | } |
38 | |
39 | // CHECK-DIE: ThreadSanitizer: starting new threads after multi-threaded fork is not supported |
40 | // CHECK-DIE: OK |
41 | |
42 | // CHECK-NODIE-NOT: ThreadSanitizer: starting new threads after multi-threaded fork is not supported |
43 | // CHECK-NODIE: OK |
44 | |
45 | |