diff options
author | Yvan <yvan.dong@cs.au.dk> | 2023-12-18 22:39:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-18 13:39:01 -0800 |
commit | 5ccad1b9c39744dbef7a4d476c69b07e51117a15 (patch) | |
tree | 6d0c7afd64e31c40b75f7603c8cdd7390add6bbb | |
parent | 33d5f4314f4fd83be21e22054e662220a62fe40b (diff) | |
download | llvm-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.cpp | 15 | ||||
-rw-r--r-- | compiler-rt/test/tsan/pthread_mutex_clocklock.cpp | 29 |
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 |