diff options
author | Maxim Ostapenko <m.ostapenko@partner.samsung.com> | 2016-10-28 06:49:53 +0000 |
---|---|---|
committer | Maxim Ostapenko <m.ostapenko@partner.samsung.com> | 2016-10-28 06:49:53 +0000 |
commit | 6fdba17a20fd7c5f31f39556dc511abe3a537204 (patch) | |
tree | ce1470338990b84fa57a112bf27a98080cda6954 /lib/lsan | |
parent | f977078a729400bcd96a206b77e261621dc0bba5 (diff) |
[asan/lsan] Avoid possible deadlock in dynamic ASan runtime thread initialization.
There is possible deadlock in dynamic ASan runtime when we dlopen() shared lib
which creates a thread at the global initialization stage. The scenario:
1) dlopen grabs a GI_pthread_mutex_lock in main thread.
2) main thread calls pthread_create, ASan intercepts it, calls real pthread_create
and waits for the second thread to be "fully initialized".
3) Newly created thread tries to access a thread local disable_counter in LSan
(to complete its "full initialization") and hangs in tls_get_addr_tail, because
it also tries to acquire GI_pthread_mutex_lock.
The issue is reproducible on relative recent Glibc versions e.g. 2.23.
Differential Revision: https://reviews.llvm.org/D26028
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@285385 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/lsan')
-rw-r--r-- | lib/lsan/lsan_common.cc | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc index f1ab2e629..b20941ef2 100644 --- a/lib/lsan/lsan_common.cc +++ b/lib/lsan/lsan_common.cc @@ -32,6 +32,7 @@ namespace __lsan { // also to protect the global list of root regions. BlockingMutex global_mutex(LINKER_INITIALIZED); +__attribute__((tls_model("initial-exec"))) THREADLOCAL int disable_counter; bool DisabledInThisThread() { return disable_counter > 0; } void DisableInThisThread() { disable_counter++; } |