[compiler-rt] [TSan] Add interceptors for flockfile, ftrylockfile, funlockfile (PR #203470)
James Lim via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 11 23:59:35 PDT 2026
https://github.com/lim-james created https://github.com/llvm/llvm-project/pull/203470
This patch adds TSan interceptors for `flockfile`, `ftrylockfile`, and `funlockfile`.
`flockfile`/`funlockfile` are POSIX stdio locking primitives for mutual exclusion on FILE streams. However, TSan does not have interceptors to account for them, so happens-before relations are not tracked, thus causing false positive data race reports.
This fixes false positives for `std::println` on Glibc platforms as libstdc++'s _File_sink acquires `flockfile`, which was invisible to TSan.
Verified by:
- Confirming TSan reports a race on flockfile-protected code without the fix
- Confirming silence with the fix applied
- Confirming real unprotected races are still caught
Resolves #203451
>From 3fe88eaf48005dd03acd583d1d4f287fa45963f0 Mon Sep 17 00:00:00 2001
From: james <jameslimbj at gmail.com>
Date: Fri, 12 Jun 2026 14:47:39 +0800
Subject: [PATCH] [tsan] Add interceptors for flockfile, ftrylockfile,
funlockfile
flockfile/funlockfile are POSIX stdio locking primitives for mutual exclusion on FILE
streams. However, TSan does not have interceptors to account for them, so
happens-before relations are not tracked, thus causing false positive data race
reports.
Signed-off-by: james <jameslimbj at gmail.com>
---
.../lib/tsan/rtl/tsan_interceptors_posix.cpp | 27 +++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index e00853bd1b426..ed123cae3b8a9 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -1762,6 +1762,30 @@ TSAN_INTERCEPTOR(int, fstat64, int fd, void *buf) {
# define TSAN_MAYBE_INTERCEPT_FSTAT64
#endif
+TSAN_INTERCEPTOR(void, flockfile, void *file) {
+ SCOPED_TSAN_INTERCEPTOR(flockfile, file);
+ MutexPreLock(thr, pc, (uptr)file,
+ MutexFlagWriteReentrant | MutexFlagNotStatic);
+ BLOCK_REAL(flockfile)(file);
+ MutexPostLock(thr, pc, (uptr)file,
+ MutexFlagWriteReentrant | MutexFlagNotStatic);
+}
+
+TSAN_INTERCEPTOR(int, ftrylockfile, void *file) {
+ SCOPED_TSAN_INTERCEPTOR(ftrylockfile, file);
+ int res = REAL(ftrylockfile)(file);
+ if (res == 0)
+ MutexPostLock(thr, pc, (uptr)file,
+ MutexFlagWriteReentrant | MutexFlagNotStatic | MutexFlagTryLock);
+ return res;
+}
+
+TSAN_INTERCEPTOR(void, funlockfile, void *file) {
+ SCOPED_TSAN_INTERCEPTOR(funlockfile, file);
+ MutexUnlock(thr, pc, (uptr)file);
+ REAL(funlockfile)(file);
+}
+
TSAN_INTERCEPTOR(int, open, const char *name, int oflag, ...) {
mode_t mode = 0;
if (OpenReadsVaArgs(oflag)) {
@@ -3142,6 +3166,9 @@ void InitializeInterceptors() {
TSAN_MAYBE_INTERCEPT___FXSTAT;
TSAN_MAYBE_INTERCEPT_FSTAT;
TSAN_MAYBE_INTERCEPT_FSTAT64;
+ TSAN_INTERCEPT(flockfile);
+ TSAN_INTERCEPT(ftrylockfile);
+ TSAN_INTERCEPT(funlockfile);
TSAN_INTERCEPT(open);
TSAN_MAYBE_INTERCEPT_OPEN64;
TSAN_INTERCEPT(creat);
More information about the llvm-commits
mailing list