[compiler-rt] r232032 - tsan: fix a bug in MetaMap::ResetRange

Dmitry Vyukov dvyukov at google.com
Thu Mar 12 05:48:19 PDT 2015


Author: dvyukov
Date: Thu Mar 12 07:48:19 2015
New Revision: 232032

URL: http://llvm.org/viewvc/llvm-project?rev=232032&view=rev
Log:
tsan: fix a bug in MetaMap::ResetRange

The bug was uncovered by NegativeTests.MmapTest from
data-race-test suite, so port it as well.


Added:
    compiler-rt/trunk/test/tsan/mmap_stress.cc
Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc?rev=232032&r1=232031&r2=232032&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc Thu Mar 12 07:48:19 2015
@@ -162,8 +162,10 @@ void MetaMap::ResetRange(ThreadState *th
   // freed). Note: we can't simply madvise, because we need to leave a zeroed
   // range (otherwise __tsan_java_move can crash if it encounters a left-over
   // meta objects in java heap).
-  UnmapOrDie((void*)p0, sz0);
-  MmapFixedNoReserve(p0, sz0);
+  uptr metap = (uptr)MemToMeta(p0);
+  uptr metasz = sz0 / kMetaRatio;
+  UnmapOrDie((void*)metap, metasz);
+  MmapFixedNoReserve(metap, metasz);
 }
 
 MBlock* MetaMap::GetBlock(uptr p) {

Added: compiler-rt/trunk/test/tsan/mmap_stress.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/mmap_stress.cc?rev=232032&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/mmap_stress.cc (added)
+++ compiler-rt/trunk/test/tsan/mmap_stress.cc Thu Mar 12 07:48:19 2015
@@ -0,0 +1,47 @@
+// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include "test.h"
+#include <errno.h>
+#include <sys/mman.h>
+
+void *SubWorker(void *arg) {
+  (void)arg;
+  const int kMmapSize =  65536;
+  for (int i = 0; i < 500; i++) {
+    int *ptr = (int*)mmap(0, kMmapSize, PROT_READ | PROT_WRITE,
+                          MAP_PRIVATE | MAP_ANON, -1, 0);
+    *ptr = 42;
+    munmap(ptr, kMmapSize);
+  }
+  return 0;
+}
+
+void *Worker1(void *arg) {
+  (void)arg;
+  pthread_t th[4];
+  for (int i = 0; i < 4; i++)
+    pthread_create(&th[i], 0, SubWorker, 0);
+  for (int i = 0; i < 4; i++)
+    pthread_join(th[i], 0);
+  return 0;
+}
+
+void *Worker(void *arg) {
+  (void)arg;
+  pthread_t th[4];
+  for (int i = 0; i < 4; i++)
+    pthread_create(&th[i], 0, Worker1, 0);
+  for (int i = 0; i < 4; i++)
+    pthread_join(th[i], 0);
+  return 0;
+}
+
+int main() {
+  pthread_t th[4];
+  for (int i = 0; i < 4; i++)
+    pthread_create(&th[i], 0, Worker, 0);
+  for (int i = 0; i < 4; i++)
+    pthread_join(th[i], 0);
+  fprintf(stderr, "DONE\n");
+}
+
+// CHECK: DONE





More information about the llvm-commits mailing list