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
12pthread_mutex_t mu1, mu2;
13pthread_barrier_t barrier;
14
15void *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
26int 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

source code of compiler-rt/test/tsan/must_deadlock.cpp