[compiler-rt] r236008 - tsan: fix a bug memory access handling

Dmitry Vyukov dvyukov at google.com
Tue Apr 28 11:08:42 PDT 2015


Author: dvyukov
Date: Tue Apr 28 13:08:42 2015
New Revision: 236008

URL: http://llvm.org/viewvc/llvm-project?rev=236008&view=rev
Log:
tsan: fix a bug memory access handling

We incorrectly replaced shadow slots
when the new value is not stronger than the old one.
The bug can lead to false negatives.
The bug was detected by Go race test suite:
https://github.com/golang/go/issues/10589


Added:
    compiler-rt/trunk/test/tsan/mop1.c
Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_update_shadow_word_inl.h

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_update_shadow_word_inl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_update_shadow_word_inl.h?rev=236008&r1=236007&r2=236008&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_update_shadow_word_inl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_update_shadow_word_inl.h Tue Apr 28 13:08:42 2015
@@ -38,7 +38,8 @@ do {
     }
     StatInc(thr, StatShadowAnotherThread);
     if (HappensBefore(old, thr)) {
-      StoreIfNotYetStored(sp, &store_word);
+      if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))
+        StoreIfNotYetStored(sp, &store_word);
       break;
     }
     if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))

Added: compiler-rt/trunk/test/tsan/mop1.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/mop1.c?rev=236008&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/mop1.c (added)
+++ compiler-rt/trunk/test/tsan/mop1.c Tue Apr 28 13:08:42 2015
@@ -0,0 +1,40 @@
+// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "test.h"
+
+// We want to establish the following sequence of accesses to X:
+// - main thread writes X
+// - thread2 reads X, this read happens-before the write in main thread
+// - thread1 reads X, this read is concurrent with the write in main thread
+// Write in main thread and read in thread1 should be detected as a race.
+// Previously tsan replaced write by main thread with read by thread1,
+// as the result the race was not detected.
+
+volatile long X, Y, Z;
+
+void *Thread1(void *x) {
+  barrier_wait(&barrier);
+  barrier_wait(&barrier);
+  Y = X;
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  Z = X;
+  barrier_wait(&barrier);
+  return NULL;
+}
+
+int main() {
+  barrier_init(&barrier, 2);
+  pthread_t t[2];
+  pthread_create(&t[0], 0, Thread1, 0);
+  X = 42;
+  barrier_wait(&barrier);
+  pthread_create(&t[1], 0, Thread2, 0);
+  pthread_join(t[0], 0);
+  pthread_join(t[1], 0);
+  return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+





More information about the llvm-commits mailing list