diff options
author | Maxim Ostapenko <chefmax7@gmail.com> | 2017-04-06 07:42:27 +0000 |
---|---|---|
committer | Maxim Ostapenko <chefmax7@gmail.com> | 2017-04-06 07:42:27 +0000 |
commit | 500b2fd06f162094319a95424bcbebf25cd35fd2 (patch) | |
tree | 3c2466f5607704a8d360bb656047f93a1d0b86e8 /lib/sanitizer_common/sanitizer_tls_get_addr.cc | |
parent | 7b9666449c81e5522fd8d32a0e4db368a12e0b41 (diff) |
[lsan] Avoid segfaults during threads destruction under high load
This patch addresses two issues:
* It turned out that suspended thread may have dtls->dtv_size == kDestroyedThread (-1)
and LSan wrongly assumes that DTV is available. This leads to SEGV when LSan tries to
iterate through DTV that is invalid.
* In some rare cases GetRegistersAndSP can fail with errno 3 (ESRCH). In this case LSan
assumes that the whole stack of a given thread is available. This is wrong because ESRCH
can indicate that suspended thread was destroyed and its stack was unmapped. This patch
properly handles ESRCH from GetRegistersAndSP in order to avoid invalid accesses to already
unpapped threads stack.
Differential Revision: https://reviews.llvm.org/D30818
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@299630 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_tls_get_addr.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_tls_get_addr.cc | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/lib/sanitizer_common/sanitizer_tls_get_addr.cc b/lib/sanitizer_common/sanitizer_tls_get_addr.cc index 77c1947d5..aa146d01f 100644 --- a/lib/sanitizer_common/sanitizer_tls_get_addr.cc +++ b/lib/sanitizer_common/sanitizer_tls_get_addr.cc @@ -136,11 +136,17 @@ void DTLS_on_libc_memalign(void *ptr, uptr size) { DTLS *DTLS_Get() { return &dtls; } +bool DTLSInDestruction(DTLS *dtls) { + return dtls->dtv_size == kDestroyedThread; +} + #else void DTLS_on_libc_memalign(void *ptr, uptr size) {} DTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res) { return 0; } DTLS *DTLS_Get() { return 0; } void DTLS_Destroy() {} +bool DTLSInDestruction(DTLS *dtls) { UNREACHABLE(); } + #endif // SANITIZER_INTERCEPT_TLS_GET_ADDR } // namespace __sanitizer |