-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[rtsan] Add versioned pthread_cond interceptors #155970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Chris Apple (cjappl) ChangesThis fixes #146120, confirmed by the original reporter Previously reviewed as #155181, but re-submitting for better book-keeping. Adds versioned pthread_cond interceptors, and the pthread_cond_init/_destroy interceptors Full diff: https://github.com/llvm/llvm-project/pull/155970.diff 2 Files Affected:
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index a9d864e9fe926..eaf2da745f047 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -15,6 +15,7 @@
#include "interception/interception.h"
#include "sanitizer_common/sanitizer_allocator_dlsym.h"
+#include "sanitizer_common/sanitizer_glibc_version.h"
#include "sanitizer_common/sanitizer_platform_interceptors.h"
#include "interception/interception.h"
@@ -766,6 +767,12 @@ INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) {
return REAL(pthread_join)(thread, value_ptr);
}
+INTERCEPTOR(int, pthread_cond_init, pthread_cond_t *cond,
+ const pthread_condattr_t *a) {
+ __rtsan_notify_intercepted_call("pthread_cond_init");
+ return REAL(pthread_cond_init)(cond, a);
+}
+
INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) {
__rtsan_notify_intercepted_call("pthread_cond_signal");
return REAL(pthread_cond_signal)(cond);
@@ -788,6 +795,12 @@ INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond,
return REAL(pthread_cond_timedwait)(cond, mutex, ts);
}
+INTERCEPTOR(int, pthread_cond_destroy, pthread_cond_t *cond) {
+ __rtsan_notify_intercepted_call("pthread_cond_destroy");
+ int res = REAL(pthread_cond_destroy)(cond);
+ return res;
+}
+
INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) {
__rtsan_notify_intercepted_call("pthread_rwlock_rdlock");
return REAL(pthread_rwlock_rdlock)(lock);
@@ -1641,10 +1654,26 @@ void __rtsan::InitializeInterceptors() {
INTERCEPT_FUNCTION(pthread_mutex_lock);
INTERCEPT_FUNCTION(pthread_mutex_unlock);
INTERCEPT_FUNCTION(pthread_join);
+
+ // See the comment in tsan_interceptors_posix.cpp.
+#if SANITIZER_GLIBC && !__GLIBC_PREREQ(2, 36) && \
+ (defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \
+ defined(__s390x__))
+ INTERCEPT_FUNCTION_VER(pthread_cond_init, "GLIBC_2.3.2");
+ INTERCEPT_FUNCTION_VER(pthread_cond_signal, "GLIBC_2.3.2");
+ INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, "GLIBC_2.3.2");
+ INTERCEPT_FUNCTION_VER(pthread_cond_wait, "GLIBC_2.3.2");
+ INTERCEPT_FUNCTION_VER(pthread_cond_timedwait, "GLIBC_2.3.2");
+ INTERCEPT_FUNCTION_VER(pthread_cond_destroy, "GLIBC_2.3.2");
+#else
+ INTERCEPT_FUNCTION(pthread_cond_init);
INTERCEPT_FUNCTION(pthread_cond_signal);
INTERCEPT_FUNCTION(pthread_cond_broadcast);
INTERCEPT_FUNCTION(pthread_cond_wait);
INTERCEPT_FUNCTION(pthread_cond_timedwait);
+ INTERCEPT_FUNCTION(pthread_cond_destroy);
+#endif
+
INTERCEPT_FUNCTION(pthread_rwlock_rdlock);
INTERCEPT_FUNCTION(pthread_rwlock_unlock);
INTERCEPT_FUNCTION(pthread_rwlock_wrlock);
diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
index d69a4e74825f0..20e3b485f3be0 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
@@ -1241,6 +1241,24 @@ TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) {
}
#endif
+TEST(TestRtsanInterceptors, PthreadCondInitDiesWhenRealtime) {
+ pthread_cond_t cond{};
+ auto Func = [&cond]() { pthread_cond_init(&cond, nullptr); };
+ ExpectRealtimeDeath(Func, "pthread_cond_init");
+ ExpectNonRealtimeSurvival(Func);
+}
+
+TEST(TestRtsanInterceptors, PthreadCondDestroyDiesWhenRealtime) {
+ pthread_cond_t cond{};
+ ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
+
+ auto Func = [&cond]() { pthread_cond_destroy(&cond); };
+ ExpectRealtimeDeath(Func, "pthread_cond_destroy");
+ ExpectNonRealtimeSurvival(Func);
+
+ pthread_cond_destroy(&cond);
+}
+
TEST(TestRtsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
pthread_cond_t cond{};
ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
|
CC for visibility @adrew0809 Once the PR bot is green, I am going to submit this and cherry pick it to LLVM 21 |
@@ -788,6 +795,12 @@ INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond, | |||
return REAL(pthread_cond_timedwait)(cond, mutex, ts); | |||
} | |||
|
|||
INTERCEPTOR(int, pthread_cond_destroy, pthread_cond_t *cond) { | |||
__rtsan_notify_intercepted_call("pthread_cond_destroy"); | |||
int res = REAL(pthread_cond_destroy)(cond); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return REAL(...)...
This fixes #146120, confirmed by the original reporter
Previously reviewed as #155181, but re-submitting for better book-keeping.
Adds versioned pthread_cond interceptors, and the pthread_cond_init/_destroy interceptors