Skip to content

Commit c940c24

Browse files
authored
tsan: Refine conditions to intercept pthread_cond_t functions
On glibc x86-64, functions like pthread_cond_init exist in two versions: 2.2 (older pthread_cond_t) and 2.3.2 (newer pthread_cond_t). In glibc versions prior to 2.36, using an unversioned interceptor (`dlsym(RTLD_NEXT, "pthread_cond_init")`) retrieves the older 2.2 symbol, which is not desired (https://sourceware.org/bugzilla/show_bug.cgi?id=14932). For newer architectures, such as aarch64 (introduced in glibc 2.17) and riscv64 (introduced in glibc 2.27), a versioned interceptor is unnecessary. Pull Request: #154268
1 parent 1fb2331 commit c940c24

File tree

2 files changed

+32
-22
lines changed

2 files changed

+32
-22
lines changed

compiler-rt/lib/tsan/dd/dd_interceptors.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,12 +312,24 @@ void InitializeInterceptors() {
312312
INTERCEPT_FUNCTION(pthread_rwlock_timedwrlock);
313313
INTERCEPT_FUNCTION(pthread_rwlock_unlock);
314314

315+
// See the comment in tsan_interceptors_posix.cpp.
316+
#if SANITIZER_GLIBC && !__GLIBC_PREREQ(2, 36) && \
317+
(defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \
318+
defined(__s390x__))
315319
INTERCEPT_FUNCTION_VER(pthread_cond_init, "GLIBC_2.3.2");
316320
INTERCEPT_FUNCTION_VER(pthread_cond_signal, "GLIBC_2.3.2");
317321
INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, "GLIBC_2.3.2");
318322
INTERCEPT_FUNCTION_VER(pthread_cond_wait, "GLIBC_2.3.2");
319323
INTERCEPT_FUNCTION_VER(pthread_cond_timedwait, "GLIBC_2.3.2");
320324
INTERCEPT_FUNCTION_VER(pthread_cond_destroy, "GLIBC_2.3.2");
325+
#else
326+
INTERCEPT_FUNCTION(pthread_cond_init);
327+
INTERCEPT_FUNCTION(pthread_cond_signal);
328+
INTERCEPT_FUNCTION(pthread_cond_broadcast);
329+
INTERCEPT_FUNCTION(pthread_cond_wait);
330+
INTERCEPT_FUNCTION(pthread_cond_timedwait);
331+
INTERCEPT_FUNCTION(pthread_cond_destroy);
332+
#endif
321333

322334
// for symbolizer
323335
INTERCEPT_FUNCTION(realpath);

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

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,6 @@ struct ucontext_t {
7979
};
8080
#endif
8181

82-
#if defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \
83-
defined(__s390x__)
84-
#define PTHREAD_ABI_BASE "GLIBC_2.3.2"
85-
#elif defined(__aarch64__) || SANITIZER_PPC64V2
86-
#define PTHREAD_ABI_BASE "GLIBC_2.17"
87-
#elif SANITIZER_LOONGARCH64
88-
#define PTHREAD_ABI_BASE "GLIBC_2.36"
89-
#elif SANITIZER_RISCV64
90-
# define PTHREAD_ABI_BASE "GLIBC_2.27"
91-
#endif
92-
9382
extern "C" int pthread_attr_init(void *attr);
9483
extern "C" int pthread_attr_destroy(void *attr);
9584
DECLARE_REAL(int, pthread_attr_getdetachstate, void *, void *)
@@ -341,11 +330,6 @@ void ScopedInterceptor::DisableIgnoresImpl() {
341330
}
342331

343332
#define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)
344-
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
345-
# define TSAN_INTERCEPT_VER(func, ver) INTERCEPT_FUNCTION(func)
346-
#else
347-
# define TSAN_INTERCEPT_VER(func, ver) INTERCEPT_FUNCTION_VER(func, ver)
348-
#endif
349333
#if SANITIZER_FREEBSD
350334
# define TSAN_MAYBE_INTERCEPT_FREEBSD_ALIAS(func) \
351335
INTERCEPT_FUNCTION(_pthread_##func)
@@ -3041,12 +3025,26 @@ void InitializeInterceptors() {
30413025
TSAN_INTERCEPT(pthread_timedjoin_np);
30423026
#endif
30433027

3044-
TSAN_INTERCEPT_VER(pthread_cond_init, PTHREAD_ABI_BASE);
3045-
TSAN_INTERCEPT_VER(pthread_cond_signal, PTHREAD_ABI_BASE);
3046-
TSAN_INTERCEPT_VER(pthread_cond_broadcast, PTHREAD_ABI_BASE);
3047-
TSAN_INTERCEPT_VER(pthread_cond_wait, PTHREAD_ABI_BASE);
3048-
TSAN_INTERCEPT_VER(pthread_cond_timedwait, PTHREAD_ABI_BASE);
3049-
TSAN_INTERCEPT_VER(pthread_cond_destroy, PTHREAD_ABI_BASE);
3028+
// In glibc versions older than 2.36, dlsym(RTLD_NEXT, "pthread_cond_init")
3029+
// may return an outdated symbol (max(2.2,base_version)) if the port was
3030+
// introduced before 2.3.2 (when the new pthread_cond_t was introduced).
3031+
#if SANITIZER_GLIBC && !__GLIBC_PREREQ(2, 36) && \
3032+
(defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \
3033+
defined(__s390x__))
3034+
INTERCEPT_FUNCTION_VER(pthread_cond_init, "GLIBC_2.3.2");
3035+
INTERCEPT_FUNCTION_VER(pthread_cond_signal, "GLIBC_2.3.2");
3036+
INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, "GLIBC_2.3.2");
3037+
INTERCEPT_FUNCTION_VER(pthread_cond_wait, "GLIBC_2.3.2");
3038+
INTERCEPT_FUNCTION_VER(pthread_cond_timedwait, "GLIBC_2.3.2");
3039+
INTERCEPT_FUNCTION_VER(pthread_cond_destroy, "GLIBC_2.3.2");
3040+
#else
3041+
INTERCEPT_FUNCTION(pthread_cond_init);
3042+
INTERCEPT_FUNCTION(pthread_cond_signal);
3043+
INTERCEPT_FUNCTION(pthread_cond_broadcast);
3044+
INTERCEPT_FUNCTION(pthread_cond_wait);
3045+
INTERCEPT_FUNCTION(pthread_cond_timedwait);
3046+
INTERCEPT_FUNCTION(pthread_cond_destroy);
3047+
#endif
30503048

30513049
TSAN_MAYBE_PTHREAD_COND_CLOCKWAIT;
30523050

0 commit comments

Comments
 (0)