diff options
Diffstat (limited to 'compiler-rt/lib/tsan/rtl')
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interface.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interface_inl.h | 16 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_report.cc | 2 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_report.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc | 7 |
6 files changed, 25 insertions, 3 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface.h b/compiler-rt/lib/tsan/rtl/tsan_interface.h index 28eea14210d..24526615db8 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface.h +++ b/compiler-rt/lib/tsan/rtl/tsan_interface.h @@ -41,6 +41,7 @@ void __tsan_write4(void *addr) SANITIZER_INTERFACE_ATTRIBUTE; 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; diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_inl.h b/compiler-rt/lib/tsan/rtl/tsan_interface_inl.h index 29e2b21ea9c..0187e49d96e 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface_inl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_interface_inl.h @@ -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) { diff --git a/compiler-rt/lib/tsan/rtl/tsan_report.cc b/compiler-rt/lib/tsan/rtl/tsan_report.cc index b394c406dcc..30e5488c02d 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_report.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_report.cc @@ -46,6 +46,8 @@ const char *thread_name(char *buf, int tid) { 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) diff --git a/compiler-rt/lib/tsan/rtl/tsan_report.h b/compiler-rt/lib/tsan/rtl/tsan_report.h index b2b7b53306d..eacb10c819d 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_report.h +++ b/compiler-rt/lib/tsan/rtl/tsan_report.h @@ -20,6 +20,7 @@ namespace __tsan { enum ReportType { ReportTypeRace, + ReportTypeVptrRace, ReportTypeUseAfterFree, ReportTypeThreadLeak, ReportTypeMutexDestroyLocked, diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index e57fcc735d1..c216a80f1da 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -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; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc index 18ab18e0cbf..50c531177dc 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc @@ -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); |