[compiler-rt] r177640 - tsan: better reporting for races on vptr

Dmitry Vyukov dvyukov at google.com
Thu Mar 21 08:37:39 PDT 2013


Author: dvyukov
Date: Thu Mar 21 10:37:39 2013
New Revision: 177640

URL: http://llvm.org/viewvc/llvm-project?rev=177640&view=rev
Log:
tsan: better reporting for races on vptr
explicitly say "ctor/dtor vs virtual call"


Added:
    compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race2.cc
Modified:
    compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interface.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_interface_inl.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc

Modified: compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race.cc?rev=177640&r1=177639&r2=177640&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race.cc (original)
+++ compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race.cc Thu Mar 21 10:37:39 2013
@@ -2,6 +2,7 @@
 #include <pthread.h>
 #include <semaphore.h>
 #include <stdio.h>
+#include <unistd.h>
 
 struct A {
   A() {
@@ -34,6 +35,7 @@ void *Thread1(void *x) {
 }
 
 void *Thread2(void *x) {
+  sleep(1);
   delete obj;
   return NULL;
 }
@@ -46,4 +48,4 @@ int main() {
   pthread_join(t[1], NULL);
 }
 
-// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: WARNING: ThreadSanitizer: data race on vptr

Added: compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race2.cc?rev=177640&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race2.cc (added)
+++ compiler-rt/trunk/lib/tsan/lit_tests/vptr_harmful_race2.cc Thu Mar 21 10:37:39 2013
@@ -0,0 +1,51 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <unistd.h>
+
+struct A {
+  A() {
+    sem_init(&sem_, 0, 0);
+  }
+  virtual void F() {
+  }
+  void Done() {
+    sem_post(&sem_);
+  }
+  virtual ~A() {
+    sem_wait(&sem_);
+    sem_destroy(&sem_);
+  }
+  sem_t sem_;
+};
+
+struct B : A {
+  virtual void F() {
+  }
+  virtual ~B() { }
+};
+
+static A *obj = new B;
+
+void *Thread1(void *x) {
+  sleep(1);
+  obj->F();
+  obj->Done();
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  delete obj;
+  return NULL;
+}
+
+int main() {
+  pthread_t t[2];
+  pthread_create(&t[0], NULL, Thread1, NULL);
+  pthread_create(&t[1], NULL, Thread2, NULL);
+  pthread_join(t[0], NULL);
+  pthread_join(t[1], NULL);
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interface.h?rev=177640&r1=177639&r2=177640&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interface.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interface.h Thu Mar 21 10:37:39 2013
@@ -41,6 +41,7 @@ void __tsan_write4(void *addr) SANITIZER
 void __tsan_write8(void *addr) SANITIZER_INTERFACE_ATTRIBUTE;
 void __tsan_write16(void *addr) SANITIZER_INTERFACE_ATTRIBUTE;
 
+void __tsan_vptr_read(void **vptr_p) SANITIZER_INTERFACE_ATTRIBUTE;
 void __tsan_vptr_update(void **vptr_p, void *new_val)
     SANITIZER_INTERFACE_ATTRIBUTE;
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interface_inl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interface_inl.h?rev=177640&r1=177639&r2=177640&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interface_inl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interface_inl.h Thu Mar 21 10:37:39 2013
@@ -52,8 +52,20 @@ void __tsan_write8(void *addr) {
 
 void __tsan_vptr_update(void **vptr_p, void *new_val) {
   CHECK_EQ(sizeof(vptr_p), 8);
-  if (*vptr_p != new_val)
-    MemoryWrite(cur_thread(), CALLERPC, (uptr)vptr_p, kSizeLog8);
+  if (*vptr_p != new_val) {
+    ThreadState *thr = cur_thread();
+    thr->is_vptr_access = true;
+    MemoryWrite(thr, CALLERPC, (uptr)vptr_p, kSizeLog8);
+    thr->is_vptr_access = false;
+  }
+}
+
+void __tsan_vptr_read(void **vptr_p) {
+  CHECK_EQ(sizeof(vptr_p), 8);
+  ThreadState *thr = cur_thread();
+  thr->is_vptr_access = true;
+  MemoryRead(thr, CALLERPC, (uptr)vptr_p, kSizeLog8);
+  thr->is_vptr_access = false;
 }
 
 void __tsan_func_entry(void *pc) {

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=177640&r1=177639&r2=177640&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Thu Mar 21 10:37:39 2013
@@ -46,6 +46,8 @@ const char *thread_name(char *buf, int t
 static const char *ReportTypeString(ReportType typ) {
   if (typ == ReportTypeRace)
     return "data race";
+  if (typ == ReportTypeVptrRace)
+    return "data race on vptr (ctor/dtor vs virtual call)";
   if (typ == ReportTypeUseAfterFree)
     return "heap-use-after-free";
   if (typ == ReportTypeThreadLeak)

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.h?rev=177640&r1=177639&r2=177640&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.h Thu Mar 21 10:37:39 2013
@@ -20,6 +20,7 @@ namespace __tsan {
 
 enum ReportType {
   ReportTypeRace,
+  ReportTypeVptrRace,
   ReportTypeUseAfterFree,
   ReportTypeThreadLeak,
   ReportTypeMutexDestroyLocked,

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=177640&r1=177639&r2=177640&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Thu Mar 21 10:37:39 2013
@@ -426,6 +426,7 @@ struct ThreadState {
   bool in_symbolizer;
   bool is_alive;
   bool is_freeing;
+  bool is_vptr_access;
   const uptr stk_addr;
   const uptr stk_size;
   const uptr tls_addr;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=177640&r1=177639&r2=177640&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Thu Mar 21 10:37:39 2013
@@ -616,7 +616,12 @@ void ReportRace(ThreadState *thr) {
   Context *ctx = CTX();
   ThreadRegistryLock l0(ctx->thread_registry);
 
-  ScopedReport rep(freed ? ReportTypeUseAfterFree : ReportTypeRace);
+  ReportType typ = ReportTypeRace;
+  if (thr->is_vptr_access)
+    typ = ReportTypeVptrRace;
+  else if (freed)
+    typ = ReportTypeUseAfterFree;
+  ScopedReport rep(typ);
   const uptr kMop = 2;
   StackTrace traces[kMop];
   const uptr toppc = TraceTopPC(thr);





More information about the llvm-commits mailing list