1 | // Test that the deadlock detector can find a deadlock that actually happened. |
2 | // Currently we will fail to report such a deadlock because we check for |
3 | // cycles in lock-order graph after pthread_mutex_lock. |
4 | |
5 | // RUN: %clangxx_tsan %s -o %t |
6 | // RUN: not %run %t 2>&1 | FileCheck %s |
7 | // XFAIL: * |
8 | #include <pthread.h> |
9 | #include <stdio.h> |
10 | #include <unistd.h> |
11 | |
12 | pthread_mutex_t mu1, mu2; |
13 | pthread_barrier_t barrier; |
14 | |
15 | void *Thread(void *p) { |
16 | // mu2 => mu1 |
17 | pthread_mutex_lock(mutex: &mu2); |
18 | pthread_barrier_wait(barrier: &barrier); |
19 | pthread_mutex_lock(mutex: &mu1); |
20 | // CHECK: ThreadSanitizer: lock-order-inversion (potential deadlock) |
21 | pthread_mutex_unlock(mutex: &mu1); |
22 | pthread_mutex_unlock(mutex: &mu2); |
23 | return p; |
24 | } |
25 | |
26 | int main() { |
27 | pthread_mutex_init(mutex: &mu1, NULL); |
28 | pthread_mutex_init(mutex: &mu2, NULL); |
29 | pthread_barrier_init(barrier: &barrier, attr: 0, count: 2); |
30 | |
31 | fprintf(stderr, format: "This test is going to deadlock and die in 3 seconds\n" ); |
32 | alarm(seconds: 3); |
33 | |
34 | pthread_t t; |
35 | pthread_create(newthread: &t, attr: 0, start_routine: Thread, arg: 0); |
36 | |
37 | // mu1 => mu2 |
38 | pthread_mutex_lock(mutex: &mu1); |
39 | pthread_barrier_wait(barrier: &barrier); |
40 | pthread_mutex_lock(mutex: &mu2); |
41 | pthread_mutex_unlock(mutex: &mu2); |
42 | pthread_mutex_unlock(mutex: &mu1); |
43 | |
44 | pthread_join(th: t, thread_return: 0); |
45 | |
46 | pthread_mutex_destroy(mutex: &mu1); |
47 | pthread_mutex_destroy(mutex: &mu2); |
48 | pthread_barrier_destroy(barrier: &barrier); |
49 | fprintf(stderr, format: "FAILED\n" ); |
50 | } |
51 | |