[compiler-rt] r219784 - tsan: fix false positive related to signals

Dmitry Vyukov dvyukov at google.com
Wed Oct 15 01:56:43 PDT 2014


Author: dvyukov
Date: Wed Oct 15 03:56:43 2014
New Revision: 219784

URL: http://llvm.org/viewvc/llvm-project?rev=219784&view=rev
Log:
tsan: fix false positive related to signals
Write interceptor calls malloc, which causes a false
unsafe-call-in-signal-handler report. See the test.


Added:
    compiler-rt/trunk/test/tsan/signal_write.cc
Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h
    compiler-rt/trunk/test/tsan/sigsuspend.cc

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc?rev=219784&r1=219783&r2=219784&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc Wed Oct 15 03:56:43 2014
@@ -48,7 +48,8 @@ static bool bogusfd(int fd) {
 }
 
 static FdSync *allocsync(ThreadState *thr, uptr pc) {
-  FdSync *s = (FdSync*)user_alloc(thr, pc, sizeof(FdSync));
+  FdSync *s = (FdSync*)user_alloc(thr, pc, sizeof(FdSync), kDefaultAlignment,
+      false);
   atomic_store(&s->rc, 1, memory_order_relaxed);
   return s;
 }
@@ -65,7 +66,7 @@ static void unref(ThreadState *thr, uptr
       CHECK_NE(s, &fdctx.globsync);
       CHECK_NE(s, &fdctx.filesync);
       CHECK_NE(s, &fdctx.socksync);
-      user_free(thr, pc, s);
+      user_free(thr, pc, s, false);
     }
   }
 }
@@ -78,13 +79,13 @@ static FdDesc *fddesc(ThreadState *thr,
   if (l1 == 0) {
     uptr size = kTableSizeL2 * sizeof(FdDesc);
     // We need this to reside in user memory to properly catch races on it.
-    void *p = user_alloc(thr, pc, size);
+    void *p = user_alloc(thr, pc, size, kDefaultAlignment, false);
     internal_memset(p, 0, size);
     MemoryResetRange(thr, (uptr)&fddesc, (uptr)p, size);
     if (atomic_compare_exchange_strong(pl1, &l1, (uptr)p, memory_order_acq_rel))
       l1 = (uptr)p;
     else
-      user_free(thr, pc, p);
+      user_free(thr, pc, p, false);
   }
   return &((FdDesc*)l1)[fd % kTableSizeL2];  // NOLINT
 }

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc?rev=219784&r1=219783&r2=219784&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc Wed Oct 15 03:56:43 2014
@@ -76,7 +76,7 @@ static void SignalUnsafeCall(ThreadState
   }
 }
 
-void *user_alloc(ThreadState *thr, uptr pc, uptr sz, uptr align) {
+void *user_alloc(ThreadState *thr, uptr pc, uptr sz, uptr align, bool signal) {
   if ((sz >= (1ull << 40)) || (align >= (1ull << 40)))
     return AllocatorReturnNull();
   void *p = allocator()->Allocate(&thr->alloc_cache, sz, align);
@@ -84,15 +84,17 @@ void *user_alloc(ThreadState *thr, uptr
     return 0;
   if (ctx && ctx->initialized)
     OnUserAlloc(thr, pc, (uptr)p, sz, true);
-  SignalUnsafeCall(thr, pc);
+  if (signal)
+    SignalUnsafeCall(thr, pc);
   return p;
 }
 
-void user_free(ThreadState *thr, uptr pc, void *p) {
+void user_free(ThreadState *thr, uptr pc, void *p, bool signal) {
   if (ctx && ctx->initialized)
     OnUserFree(thr, pc, (uptr)p, true);
   allocator()->Deallocate(&thr->alloc_cache, p);
-  SignalUnsafeCall(thr, pc);
+  if (signal)
+    SignalUnsafeCall(thr, pc);
 }
 
 void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write) {

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h?rev=219784&r1=219783&r2=219784&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h Wed Oct 15 03:56:43 2014
@@ -26,9 +26,9 @@ void AllocatorPrintStats();
 
 // For user allocations.
 void *user_alloc(ThreadState *thr, uptr pc, uptr sz,
-                 uptr align = kDefaultAlignment);
+                 uptr align = kDefaultAlignment, bool signal = true);
 // Does not accept NULL.
-void user_free(ThreadState *thr, uptr pc, void *p);
+void user_free(ThreadState *thr, uptr pc, void *p, bool signal = true);
 void *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz);
 void *user_alloc_aligned(ThreadState *thr, uptr pc, uptr sz, uptr align);
 uptr user_alloc_usable_size(const void *p);

Added: compiler-rt/trunk/test/tsan/signal_write.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/signal_write.cc?rev=219784&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/signal_write.cc (added)
+++ compiler-rt/trunk/test/tsan/signal_write.cc Wed Oct 15 03:56:43 2014
@@ -0,0 +1,27 @@
+// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+static void handler(int, siginfo_t*, void*) {
+  const char *str = "HELLO FROM SIGNAL\n";
+  write(2, str, strlen(str));
+}
+
+int main() {
+  struct sigaction act = {};
+  act.sa_sigaction = &handler;
+  sigaction(SIGPROF, &act, 0);
+  kill(getpid(), SIGPROF);
+  sleep(1);
+  fprintf(stderr, "DONE\n");
+  return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer
+// CHECK: HELLO FROM SIGNAL
+// CHECK: DONE
+

Modified: compiler-rt/trunk/test/tsan/sigsuspend.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/sigsuspend.cc?rev=219784&r1=219783&r2=219784&view=diff
==============================================================================
--- compiler-rt/trunk/test/tsan/sigsuspend.cc (original)
+++ compiler-rt/trunk/test/tsan/sigsuspend.cc Wed Oct 15 03:56:43 2014
@@ -1,4 +1,4 @@
-// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
 
 // Always enable asserts.
 #ifdef NDEBUG
@@ -37,7 +37,7 @@ int main() {
 
   // Restore the original set.
   assert(0 == sigprocmask(SIG_SETMASK, &old_set, NULL));
-  printf("DONE");
+  printf("DONE\n");
 }
 
 // CHECK: HANDLER





More information about the llvm-commits mailing list