tsan: intercept mlock() because of the kernel bug
authorDmitry Vyukov <dvyukov@google.com>
Fri, 30 Nov 2012 06:50:15 +0000 (06:50 +0000)
committerDmitry Vyukov <dvyukov@google.com>
Fri, 30 Nov 2012 06:50:15 +0000 (06:50 +0000)
llvm-svn: 168987

compiler-rt/lib/tsan/rtl/tsan_flags.h
compiler-rt/lib/tsan/rtl/tsan_interceptors.cc

index 86c2af5..ea4cb43 100644 (file)
@@ -52,7 +52,7 @@ struct Flags {
   // Write logs to "log_path.pid".
   // The special values are "stdout" and "stderr".
   // The default is "stderr".
-  const char *log_path;  
+  const char *log_path;
   // Sleep in main thread before exiting for that many ms
   // (useful to catch "at exit" races).
   int atexit_sleep_ms;
index 4149c76..3cdad7d 100644 (file)
@@ -1349,6 +1349,35 @@ TSAN_INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
   return REAL(gettimeofday)(tv, tz);
 }
 
+// Linux kernel has a bug that leads to kernel deadlock if a process
+// maps TBs of memory and then calls mlock().
+static void MlockIsUnsupported() {
+  static atomic_uint8_t printed;
+  if (atomic_exchange(&printed, 1, memory_order_relaxed))
+    return;
+  Printf("INFO: ThreadSanitizer ignores mlock/mlockall/munlock/munlockall\n");
+}
+
+TSAN_INTERCEPTOR(int, mlock, const void *addr, uptr len) {
+  MlockIsUnsupported();
+  return 0;
+}
+
+TSAN_INTERCEPTOR(int, munlock, const void *addr, uptr len) {
+  MlockIsUnsupported();
+  return 0;
+}
+
+TSAN_INTERCEPTOR(int, mlockall, int flags) {
+  MlockIsUnsupported();
+  return 0;
+}
+
+TSAN_INTERCEPTOR(int, munlockall, void) {
+  MlockIsUnsupported();
+  return 0;
+}
+
 namespace __tsan {
 
 void ProcessPendingSignals(ThreadState *thr) {
@@ -1526,6 +1555,11 @@ void InitializeInterceptors() {
   TSAN_INTERCEPT(nanosleep);
   TSAN_INTERCEPT(gettimeofday);
 
+  TSAN_INTERCEPT(mlock);
+  TSAN_INTERCEPT(munlock);
+  TSAN_INTERCEPT(mlockall);
+  TSAN_INTERCEPT(munlockall);
+
   atexit_ctx = new(internal_alloc(MBlockAtExit, sizeof(AtExitContext)))
       AtExitContext();