diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index b46a81031258c..eda3600b9de9e 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -1130,6 +1130,22 @@ 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, 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; + }, + 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);