add debug code to chase down a rare crash in asan/lsan https://github.com/google...
authorKostya Serebryany <kcc@google.com>
Tue, 2 Jun 2020 00:33:49 +0000 (17:33 -0700)
committerKostya Serebryany <kcc@google.com>
Tue, 2 Jun 2020 02:14:56 +0000 (19:14 -0700)
Summary: add debug code to chase down a rare crash in asan/lsan https://github.com/google/sanitizers/issues/1193

Reviewers: vitalybuka

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D80967

compiler-rt/lib/asan/asan_allocator.cpp
compiler-rt/lib/lsan/lsan_common.cpp

index 65c51fb..c00c354 100644 (file)
@@ -1037,8 +1037,19 @@ uptr PointsIntoChunk(void* p) {
   return 0;
 }
 
+// Debug code. Delete once issue #1193 is chased down.
+extern "C" SANITIZER_WEAK_ATTRIBUTE const char *__lsan_current_stage;
+
 uptr GetUserBegin(uptr chunk) {
   __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(chunk);
+  if (!m)
+    Printf(
+        "ASAN is about to crash with a CHECK failure.\n"
+        "The ASAN developers are trying to chaise down this bug,\n"
+        "so if you've encountered this bug please let us know.\n"
+        "See also: https://github.com/google/sanitizers/issues/1193\n"
+        "chunk: %p caller %p __lsan_current_stage %s\n",
+        chunk, GET_CALLER_PC(), __lsan_current_stage);
   CHECK(m);
   return m->Beg();
 }
index 32ea4e8..67f85f2 100644 (file)
@@ -25,6 +25,8 @@
 #include "sanitizer_common/sanitizer_thread_registry.h"
 #include "sanitizer_common/sanitizer_tls_get_addr.h"
 
+extern "C" const char *__lsan_current_stage = "unknown";
+
 #if CAN_SANITIZE_LEAKS
 namespace __lsan {
 
@@ -34,6 +36,7 @@ BlockingMutex global_mutex(LINKER_INITIALIZED);
 
 Flags lsan_flags;
 
+
 void DisableCounterUnderflow() {
   if (common_flags()->detect_leaks) {
     Report("Unmatched call to __lsan_enable().\n");
@@ -363,6 +366,7 @@ static void FloodFillTag(Frontier *frontier, ChunkTag tag) {
 // ForEachChunk callback. If the chunk is marked as leaked, marks all chunks
 // which are reachable from it as indirectly leaked.
 static void MarkIndirectlyLeakedCb(uptr chunk, void *arg) {
+  __lsan_current_stage = "MarkIndirectlyLeakedCb";
   chunk = GetUserBegin(chunk);
   LsanMetadata m(chunk);
   if (m.allocated() && m.tag() != kReachable) {
@@ -375,6 +379,7 @@ static void MarkIndirectlyLeakedCb(uptr chunk, void *arg) {
 // frontier.
 static void CollectIgnoredCb(uptr chunk, void *arg) {
   CHECK(arg);
+  __lsan_current_stage = "CollectIgnoredCb";
   chunk = GetUserBegin(chunk);
   LsanMetadata m(chunk);
   if (m.allocated() && m.tag() == kIgnored) {
@@ -404,6 +409,7 @@ struct InvalidPCParam {
 static void MarkInvalidPCCb(uptr chunk, void *arg) {
   CHECK(arg);
   InvalidPCParam *param = reinterpret_cast<InvalidPCParam *>(arg);
+  __lsan_current_stage = "MarkInvalidPCCb";
   chunk = GetUserBegin(chunk);
   LsanMetadata m(chunk);
   if (m.allocated() && m.tag() != kReachable && m.tag() != kIgnored) {
@@ -479,6 +485,7 @@ static void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads,
 // ForEachChunk callback. Resets the tags to pre-leak-check state.
 static void ResetTagsCb(uptr chunk, void *arg) {
   (void)arg;
+  __lsan_current_stage = "ResetTagsCb";
   chunk = GetUserBegin(chunk);
   LsanMetadata m(chunk);
   if (m.allocated() && m.tag() != kIgnored)
@@ -495,6 +502,7 @@ static void PrintStackTraceById(u32 stack_trace_id) {
 static void CollectLeaksCb(uptr chunk, void *arg) {
   CHECK(arg);
   LeakReport *leak_report = reinterpret_cast<LeakReport *>(arg);
+  __lsan_current_stage = "CollectLeaksCb";
   chunk = GetUserBegin(chunk);
   LsanMetadata m(chunk);
   if (!m.allocated()) return;