summaryrefslogtreecommitdiff
path: root/lib/lsan
diff options
context:
space:
mode:
authorMaxim Ostapenko <m.ostapenko@partner.samsung.com>2016-10-28 06:49:53 +0000
committerMaxim Ostapenko <m.ostapenko@partner.samsung.com>2016-10-28 06:49:53 +0000
commit6fdba17a20fd7c5f31f39556dc511abe3a537204 (patch)
treece1470338990b84fa57a112bf27a98080cda6954 /lib/lsan
parentf977078a729400bcd96a206b77e261621dc0bba5 (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.cc1
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++; }