tsan: ignore destruction of global mutexes (causes a lot of non-interesting reports)


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@163400 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/tsan/rtl/tsan_platform.h b/lib/tsan/rtl/tsan_platform.h
index 888daf6..b80b268 100644
--- a/lib/tsan/rtl/tsan_platform.h
+++ b/lib/tsan/rtl/tsan_platform.h
@@ -86,6 +86,9 @@
 
 void internal_start_thread(void(*func)(void*), void *arg);
 
+// Says whether the addr relates to a global var.
+// Guesses with high probability, may yield both false positives and negatives.
+bool IsGlobalVar(uptr addr);
 uptr GetTlsSize();
 void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
                           uptr *tls_addr, uptr *tls_size);
diff --git a/lib/tsan/rtl/tsan_platform_linux.cc b/lib/tsan/rtl/tsan_platform_linux.cc
index f6b5598..9d4c248 100644
--- a/lib/tsan/rtl/tsan_platform_linux.cc
+++ b/lib/tsan/rtl/tsan_platform_linux.cc
@@ -132,6 +132,10 @@
   DPrintf("stack        %zx\n", (uptr)&shadow);
 }
 
+static uptr g_tls_size;
+static uptr g_data_start;
+static uptr g_data_end;
+
 #ifndef TSAN_GO
 static void CheckPIE() {
   // Ensure that the binary is indeed compiled with -pie.
@@ -150,7 +154,26 @@
   }
 }
 
-static uptr g_tls_size;
+static void InitDataSeg() {
+  MemoryMappingLayout proc_maps;
+  uptr start, end, offset;
+  char name[128];
+  bool prev_is_data = false;
+  while (proc_maps.Next(&start, &end, &offset, name, ARRAY_SIZE(name))) {
+    DPrintf("%p-%p %p %s\n", start, end, offset, name);
+    bool is_data = offset != 0 && name[0] != 0;
+    bool is_bss = offset == 0 && name[0] == 0 && prev_is_data;
+    if (g_data_start == 0 && is_data)
+      g_data_start = start;
+    if (is_bss)
+      g_data_end = end;
+    prev_is_data = is_data;
+  }
+  DPrintf("guessed data_start=%p data_end=%p\n",  g_data_start, g_data_end);
+  CHECK_LT(g_data_start, g_data_end);
+  CHECK_GE((uptr)&g_data_start, g_data_start);
+  CHECK_LT((uptr)&g_data_start, g_data_end);
+}
 
 #ifdef __i386__
 # define INTERNAL_FUNCTION __attribute__((regparm(3), stdcall))
@@ -187,6 +210,7 @@
 #ifndef TSAN_GO
   CheckPIE();
   g_tls_size = (uptr)InitTlsSize();
+  InitDataSeg();
 #endif
   return getenv("TSAN_OPTIONS");
 }
@@ -232,6 +256,9 @@
 #endif
 }
 
+bool IsGlobalVar(uptr addr) {
+  return g_data_start && addr >= g_data_start && addr < g_data_end;
+}
 
 }  // namespace __tsan
 
diff --git a/lib/tsan/rtl/tsan_rtl_mutex.cc b/lib/tsan/rtl/tsan_rtl_mutex.cc
index 45dc559..3175f91 100644
--- a/lib/tsan/rtl/tsan_rtl_mutex.cc
+++ b/lib/tsan/rtl/tsan_rtl_mutex.cc
@@ -40,6 +40,12 @@
   CHECK_GT(thr->in_rtl, 0);
   DPrintf("#%d: MutexDestroy %zx\n", thr->tid, addr);
   StatInc(thr, StatMutexDestroy);
+#ifndef TSAN_GO
+  // Global mutexes not marked as LINKER_INITIALIZED
+  // cause tons of not interesting reports, so just ignore it.
+  if (IsGlobalVar(addr))
+    return;
+#endif
   SyncVar *s = ctx->synctab.GetAndRemove(thr, pc, addr);
   if (s == 0)
     return;