aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYvan <yvan.dong@cs.au.dk>2023-12-18 22:39:01 +0100
committerGitHub <noreply@github.com>2023-12-18 13:39:01 -0800
commit5ccad1b9c39744dbef7a4d476c69b07e51117a15 (patch)
tree6d0c7afd64e31c40b75f7603c8cdd7390add6bbb
parent33d5f4314f4fd83be21e22054e662220a62fe40b (diff)
downloadllvm-5ccad1b9c39744dbef7a4d476c69b07e51117a15.zip
llvm-5ccad1b9c39744dbef7a4d476c69b07e51117a15.tar.gz
llvm-5ccad1b9c39744dbef7a4d476c69b07e51117a15.tar.bz2
[TSAN] add instrumentation for pthread_mutex_clocklock (#75713)
The function `pthread_mutex_clocklock` is not supported by TSAN yet, which is mentioned by[ llvm/llvm-project/issues/62623](https://github.com/llvm/llvm-project/issues/62623#issue-1701600538). This patch is to handle this function.
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp15
-rw-r--r--compiler-rt/test/tsan/pthread_mutex_clocklock.cpp29
2 files changed, 44 insertions, 0 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 80f86ca..da0ad8e 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -1380,6 +1380,20 @@ TSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
return res;
}
+TSAN_INTERCEPTOR(int, pthread_mutex_clocklock, void *m,
+ __sanitizer_clockid_t clock, void *abstime) {
+ SCOPED_TSAN_INTERCEPTOR(pthread_mutex_clocklock, m, clock, abstime);
+ MutexPreLock(thr, pc, (uptr)m);
+ int res = REAL(pthread_mutex_clocklock)(m, clock, abstime);
+ if (res == errno_EOWNERDEAD)
+ MutexRepair(thr, pc, (uptr)m);
+ if (res == 0 || res == errno_EOWNERDEAD)
+ MutexPostLock(thr, pc, (uptr)m);
+ if (res == errno_EINVAL)
+ MutexInvalidAccess(thr, pc, (uptr)m);
+ return res;
+}
+
#if SANITIZER_GLIBC
# if !__GLIBC_PREREQ(2, 34)
// glibc 2.34 applies a non-default version for the two functions. They are no
@@ -2902,6 +2916,7 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(pthread_mutex_trylock);
TSAN_INTERCEPT(pthread_mutex_timedlock);
TSAN_INTERCEPT(pthread_mutex_unlock);
+ TSAN_INTERCEPT(pthread_mutex_clocklock);
#if SANITIZER_GLIBC
# if !__GLIBC_PREREQ(2, 34)
TSAN_INTERCEPT(__pthread_mutex_lock);
diff --git a/compiler-rt/test/tsan/pthread_mutex_clocklock.cpp b/compiler-rt/test/tsan/pthread_mutex_clocklock.cpp
new file mode 100644
index 0000000..dbca0b4
--- /dev/null
+++ b/compiler-rt/test/tsan/pthread_mutex_clocklock.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: darwin
+#include <pthread.h>
+#include <stdio.h>
+
+pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+struct timespec ts = {0};
+
+void *tfunc(void *p) {
+ if (!pthread_mutex_trylock(&m)) {
+ puts("Second thread could not lock mutex");
+ pthread_mutex_unlock(&m);
+ }
+ return p;
+}
+
+int main() {
+ if (!pthread_mutex_clocklock(&m, CLOCK_REALTIME, &ts)) {
+ pthread_t thr;
+ pthread_create(&thr, 0, tfunc, 0);
+ pthread_join(thr, 0);
+ pthread_mutex_unlock(&m);
+ } else
+ puts("Failed to lock mutex");
+ fprintf(stderr, "PASS\n");
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: unlock of an unlocked mutex
+// CHECK: PASS \ No newline at end of file