Index: lib/lsan/lsan_common.cc =================================================================== --- lib/lsan/lsan_common.cc +++ lib/lsan/lsan_common.cc @@ -253,7 +253,7 @@ if (tls_end > cache_end) ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", kReachable); } - if (dtls) { + if (dtls && !DTLSInDestruction(dtls)) { for (uptr j = 0; j < dtls->dtv_size; ++j) { uptr dtls_beg = dtls->dtv[j].beg; uptr dtls_end = dtls_beg + dtls->dtv[j].size; @@ -263,6 +263,10 @@ kReachable); } } + } else { + // We are handling a thread with DTLS under distruction. Log about + // this and continue. + LOG_THREADS("Thread %d has DTLS under distruction.\n", os_id); } } } Index: lib/sanitizer_common/sanitizer_tls_get_addr.h =================================================================== --- lib/sanitizer_common/sanitizer_tls_get_addr.h +++ lib/sanitizer_common/sanitizer_tls_get_addr.h @@ -55,6 +55,8 @@ void DTLS_on_libc_memalign(void *ptr, uptr size); DTLS *DTLS_Get(); void DTLS_Destroy(); // Make sure to call this before the thread is destroyed. +// Returns true if DTLS of suspended thread is in distruction process. +bool DTLSInDestruction(DTLS *dtls); } // namespace __sanitizer Index: lib/sanitizer_common/sanitizer_tls_get_addr.cc =================================================================== --- lib/sanitizer_common/sanitizer_tls_get_addr.cc +++ lib/sanitizer_common/sanitizer_tls_get_addr.cc @@ -136,11 +136,17 @@ DTLS *DTLS_Get() { return &dtls; } +bool DTLSInDestruction(DTLS *dtls) { + return dtls && 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) { return false; } + #endif // SANITIZER_INTERCEPT_TLS_GET_ADDR } // namespace __sanitizer