[PATCH] D30818: [lsan] Don't handle DTLS of thread under distruction

Maxim Ostapenko via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 10 04:52:28 PST 2017


m.ostapenko created this revision.
m.ostapenko added a project: Sanitizers.
Herald added a subscriber: kubamracek.

When debugging a testcase from https://github.com/google/sanitizers/issues/757 I've noticed that LSan segfaults with NULL dereference after ~10 seconds of execution.
It turned out that suspended thread may have **dtls->dtv_size == kDestroyedThread (-1)** and LSan wrongly assumes that DTV is available.
This patch doesn't resolve original issue from GitHub but allows avoid rare segfaults in thread intrusive cases.


Repository:
  rL LLVM

https://reviews.llvm.org/D30818

Files:
  lib/lsan/lsan_common.cc
  lib/sanitizer_common/sanitizer_tls_get_addr.cc
  lib/sanitizer_common/sanitizer_tls_get_addr.h


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
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);
       }
     }
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30818.91312.patch
Type: text/x-patch
Size: 2061 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170310/59c9a92a/attachment.bin>


More information about the llvm-commits mailing list