[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"