1 | // Test that Thread objects are reused. |
2 | // RUN: %clangxx_hwasan -mllvm -hwasan-globals=0 -mllvm -hwasan-instrument-stack=0 %s -o %t && %env_hwasan_opts=verbose_threads=1 %run %t 2>&1 | FileCheck %s |
3 | |
4 | #include <assert.h> |
5 | #include <fcntl.h> |
6 | #include <pthread.h> |
7 | #include <stdio.h> |
8 | #include <stdlib.h> |
9 | #include <unistd.h> |
10 | |
11 | #include <sanitizer/hwasan_interface.h> |
12 | |
13 | pthread_barrier_t bar; |
14 | |
15 | void *threadfn(void *) { |
16 | pthread_barrier_wait(barrier: &bar); |
17 | return nullptr; |
18 | } |
19 | |
20 | void start_stop_threads() { |
21 | constexpr int N = 2; |
22 | pthread_t threads[N]; |
23 | |
24 | pthread_barrier_init(barrier: &bar, attr: nullptr, count: N + 1); |
25 | for (auto &t : threads) |
26 | pthread_create(newthread: &t, attr: nullptr, start_routine: threadfn, arg: nullptr); |
27 | |
28 | pthread_barrier_wait(barrier: &bar); |
29 | |
30 | for (auto &t : threads) |
31 | pthread_join(th: t, thread_return: nullptr); |
32 | pthread_barrier_destroy(barrier: &bar); |
33 | } |
34 | |
35 | int main() { |
36 | // Cut off initial threads. |
37 | // CHECK: === test start === |
38 | fprintf(stderr, format: "=== test start ===\n" ); |
39 | |
40 | // CHECK: Creating : T{{[0-9]+}} [[A:0x[0-9a-f]+]] stack: |
41 | // CHECK: Creating : T{{[0-9]+}} [[B:0x[0-9a-f]+]] stack: |
42 | start_stop_threads(); |
43 | |
44 | // CHECK-DAG: Creating : T{{[0-9]+}} [[A]] stack: |
45 | // CHECK-DAG: Creating : T{{[0-9]+}} [[B]] stack: |
46 | start_stop_threads(); |
47 | |
48 | // CHECK-DAG: Creating : T{{[0-9]+}} [[A]] stack: |
49 | // CHECK-DAG: Creating : T{{[0-9]+}} [[B]] stack: |
50 | start_stop_threads(); |
51 | |
52 | return 0; |
53 | } |
54 | |