Skip to content

Commit e54ae4e

Browse files
vitalybukaAlexisPerry
authored andcommitted
[tsan] Fix dead lock when starting StackDepot thread (llvm#96456)
Sometime tsan runtimes calls, like `__tsan_mutex_create ()`, need to store a stack in the StackDepot, and the Depot may need to start and maintenance thread. Example: ``` __sanitizer::FutexWait () __sanitizer::Semaphore::Wait () __sanitizer::Mutex::Lock () __tsan::SlotLock () __tsan::SlotLocker::SlotLocker () __tsan::Acquire () __tsan::CallUserSignalHandler () __tsan::ProcessPendingSignalsImpl () __tsan::ProcessPendingSignals () __tsan::ScopedInterceptor::~ScopedInterceptor () ___interceptor_mmap () pthread_create () __sanitizer::internal_start_thread () __sanitizer::(anonymous namespace)::CompressThread::NewWorkNotify () __sanitizer::StackDepotNode::store () __sanitizer::StackDepotBase<__sanitizer::StackDepotNode, 1, 20>::Put () __tsan::CurrentStackId () __tsan::MutexCreate () __tsan_mutex_create () ``` pthread_create() implementation may hit other interceptors recursively, which may invoke ProcessPendingSignals, which deadlocks. Alternative solution could be block interceptors closer to TSAN runtime API function, like `__tsan_mutex_create`, or just before `StackDepotPut``, but it's not needed for most calls, only when new thread is created using `real_pthread_create`. I don't see a reasonable way to create a regression test.
1 parent 442deb1 commit e54ae4e

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,18 @@ TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
10881088
return res;
10891089
}
10901090

1091-
DEFINE_REAL_PTHREAD_FUNCTIONS
1091+
// DEFINE_REAL_PTHREAD_FUNCTIONS
1092+
namespace __sanitizer {
1093+
int real_pthread_create(void *th, void *attr, void *(*callback)(void *),
1094+
void *param) {
1095+
ScopedIgnoreInterceptors ignore;
1096+
return REAL(pthread_create)(th, attr, callback, param);
1097+
}
1098+
int real_pthread_join(void *th, void **ret) {
1099+
ScopedIgnoreInterceptors ignore;
1100+
return REAL(pthread_join(th, ret));
1101+
}
1102+
} // namespace __sanitizer
10921103

10931104
TSAN_INTERCEPTOR(int, pthread_detach, void *th) {
10941105
SCOPED_INTERCEPTOR_RAW(pthread_detach, th);

0 commit comments

Comments
 (0)