summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_tls_get_addr.cc
diff options
context:
space:
mode:
authorMaxim Ostapenko <chefmax7@gmail.com>2017-04-06 07:42:27 +0000
committerMaxim Ostapenko <chefmax7@gmail.com>2017-04-06 07:42:27 +0000
commit500b2fd06f162094319a95424bcbebf25cd35fd2 (patch)
tree3c2466f5607704a8d360bb656047f93a1d0b86e8 /lib/sanitizer_common/sanitizer_tls_get_addr.cc
parent7b9666449c81e5522fd8d32a0e4db368a12e0b41 (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.cc6
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