Skip to content

Commit 5ccad1b

Browse files
authored
[TSAN] add instrumentation for pthread_mutex_clocklock (#75713)
The function `pthread_mutex_clocklock` is not supported by TSAN yet, which is mentioned by[ /issues/62623](#62623 (comment)). This patch is to handle this function.
1 parent 33d5f43 commit 5ccad1b

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,20 @@ TSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
13801380
return res;
13811381
}
13821382

1383+
TSAN_INTERCEPTOR(int, pthread_mutex_clocklock, void *m,
1384+
__sanitizer_clockid_t clock, void *abstime) {
1385+
SCOPED_TSAN_INTERCEPTOR(pthread_mutex_clocklock, m, clock, abstime);
1386+
MutexPreLock(thr, pc, (uptr)m);
1387+
int res = REAL(pthread_mutex_clocklock)(m, clock, abstime);
1388+
if (res == errno_EOWNERDEAD)
1389+
MutexRepair(thr, pc, (uptr)m);
1390+
if (res == 0 || res == errno_EOWNERDEAD)
1391+
MutexPostLock(thr, pc, (uptr)m);
1392+
if (res == errno_EINVAL)
1393+
MutexInvalidAccess(thr, pc, (uptr)m);
1394+
return res;
1395+
}
1396+
13831397
#if SANITIZER_GLIBC
13841398
# if !__GLIBC_PREREQ(2, 34)
13851399
// glibc 2.34 applies a non-default version for the two functions. They are no
@@ -2902,6 +2916,7 @@ void InitializeInterceptors() {
29022916
TSAN_INTERCEPT(pthread_mutex_trylock);
29032917
TSAN_INTERCEPT(pthread_mutex_timedlock);
29042918
TSAN_INTERCEPT(pthread_mutex_unlock);
2919+
TSAN_INTERCEPT(pthread_mutex_clocklock);
29052920
#if SANITIZER_GLIBC
29062921
# if !__GLIBC_PREREQ(2, 34)
29072922
TSAN_INTERCEPT(__pthread_mutex_lock);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2+
// UNSUPPORTED: darwin
3+
#include <pthread.h>
4+
#include <stdio.h>
5+
6+
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
7+
struct timespec ts = {0};
8+
9+
void *tfunc(void *p) {
10+
if (!pthread_mutex_trylock(&m)) {
11+
puts("Second thread could not lock mutex");
12+
pthread_mutex_unlock(&m);
13+
}
14+
return p;
15+
}
16+
17+
int main() {
18+
if (!pthread_mutex_clocklock(&m, CLOCK_REALTIME, &ts)) {
19+
pthread_t thr;
20+
pthread_create(&thr, 0, tfunc, 0);
21+
pthread_join(thr, 0);
22+
pthread_mutex_unlock(&m);
23+
} else
24+
puts("Failed to lock mutex");
25+
fprintf(stderr, "PASS\n");
26+
}
27+
28+
// CHECK-NOT: WARNING: ThreadSanitizer: unlock of an unlocked mutex
29+
// CHECK: PASS

0 commit comments

Comments
 (0)