[asan] Move lsan_disabled out of thread context.

Fix for the case where disabler is used in pthread key destructor.

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@184553 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index e0e2ab9..97f1e26 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -26,6 +26,9 @@
 // This mutex is used to prevent races between DoLeakCheck and SuppressObject.
 BlockingMutex global_mutex(LINKER_INITIALIZED);
 
+THREADLOCAL int disable_counter;
+bool DisabledInThisThread() { return disable_counter > 0; }
+
 Flags lsan_flags;
 
 static void InitializeFlags() {
@@ -83,7 +86,7 @@
 
 // Scan the memory range, looking for byte patterns that point into allocator
 // chunks. Mark those chunks with tag and add them to the frontier.
-// There are two usage modes for this function: finding reachable or suppressed
+// There are two usage modes for this function: finding reachable or ignored 
 // chunks (tag = kReachable or kIgnored) and finding indirectly leaked chunks
 // (tag = kIndirectlyLeaked). In the second case, there's no flood fill,
 // so frontier = 0.
@@ -102,7 +105,7 @@
     void *chunk = PointsIntoChunk(p);
     if (!chunk) continue;
     LsanMetadata m(chunk);
-    // Reachable beats suppressed beats leaked.
+    // Reachable beats ignored beats leaked.
     if (m.tag() == kReachable) continue;
     if (m.tag() == kIgnored && tag != kReachable) continue;
     m.set_tag(tag);
@@ -205,7 +208,7 @@
   }
 }
 
-void CollectSuppressedCb::operator()(void *p) const {
+void CollectIgnoredCb::operator()(void *p) const {
   p = GetUserBegin(p);
   LsanMetadata m(p);
   if (m.allocated() && m.tag() == kIgnored)
@@ -230,7 +233,7 @@
   if (flags()->log_pointers)
     Report("Scanning ignored chunks.\n");
   CHECK_EQ(0, frontier.size());
-  ForEachChunk(CollectSuppressedCb(&frontier));
+  ForEachChunk(CollectIgnoredCb(&frontier));
   FloodFillTag(&frontier, kIgnored);
 
   // Iterate over leaked chunks and mark those that are reachable from other
@@ -394,8 +397,9 @@
       bytes += leaks_[i].total_size;
       allocations += leaks_[i].hit_count;
   }
-  Printf("SUMMARY: LeakSanitizer: %llu byte(s) leaked in %llu allocation(s).\n\n",
-         bytes, allocations);
+  Printf(
+      "SUMMARY: LeakSanitizer: %llu byte(s) leaked in %llu allocation(s).\n\n",
+      bytes, allocations);
 }
 
 }  // namespace __lsan
@@ -420,4 +424,22 @@
     Report("__lsan_ignore_object(): ignoring heap object at %p\n", p);
 #endif  // CAN_SANITIZE_LEAKS
 }
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __lsan_disable() {
+#if CAN_SANITIZE_LEAKS
+  __lsan::disable_counter++;
+#endif
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __lsan_enable() {
+#if CAN_SANITIZE_LEAKS
+  if (!__lsan::disable_counter) {
+    Report("Unmatched call to __lsan_enable().\n");
+    Die();
+  }
+  __lsan::disable_counter--;
+#endif
+}
 }  // extern "C"