From 528c47b597377681d7165aeebd5911c1df27be28 Mon Sep 17 00:00:00 2001 From: Fei Peng Date: Wed, 1 Oct 2025 15:16:36 -0700 Subject: [PATCH 1/2] [compiler-rt][TSan] fix crash caused by intercpting pthread_detach on Android --- .../lib/tsan/rtl/tsan_interceptors_posix.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index b46a81031258c..6a2af75cbaec9 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -1130,6 +1130,20 @@ TSAN_INTERCEPTOR(int, pthread_create, TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) { SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret); +#if SANITIZER_ANDROID + { + // In Bionic, pthread_detach calls pthread_join, so the thread has already + // been consumed by the pthread_detach interceptor. + Tid tid = ctx->thread_registry.FindThread( + [](ThreadContextBase* tctx, void* arg) { + return tctx->user_id == (uptr)arg; + }, + th); + if (tid == kInvalidTid) { + return REAL(pthread_join)(th, ret); + } + } +#endif Tid tid = ThreadConsumeTid(thr, pc, (uptr)th); ThreadIgnoreBegin(thr, pc); int res = BLOCK_REAL(pthread_join)(th, ret); From 46e63ea5792cb87a683fe51f30e0800fddc692eb Mon Sep 17 00:00:00 2001 From: Fei Peng Date: Sun, 5 Oct 2025 14:41:11 -0700 Subject: [PATCH 2/2] update comment --- compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 6a2af75cbaec9..eda3600b9de9e 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -1132,8 +1132,10 @@ TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) { SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret); #if SANITIZER_ANDROID { - // In Bionic, pthread_detach calls pthread_join, so the thread has already - // been consumed by the pthread_detach interceptor. + // In Bionic, if the target thread has already exited when pthread_detach is + // called, pthread_detach will call pthread_join internally to clean it up. + // In that case, the thread has already been consumed by the pthread_detach + // interceptor. Tid tid = ctx->thread_registry.FindThread( [](ThreadContextBase* tctx, void* arg) { return tctx->user_id == (uptr)arg;