diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -698,7 +698,8 @@ kAccessWrite = 0, kAccessRead = 1 << 0, kAccessAtomic = 1 << 1, - kAccessVptr = 1 << 2, + kAccessVptr = 1 << 2, // read or write of an object virtual table pointer + kAccessFree = 1 << 3, // synthetic memory access during memory freeing }; void MemoryAccess(ThreadState *thr, uptr pc, uptr addr, @@ -741,9 +742,13 @@ bool is_atomic = typ & kAccessAtomic; if (typ & kAccessVptr) thr->is_vptr_access = true; + if (typ & kAccessFree) + thr->is_freeing = true; MemoryAccess(thr, pc, addr, size_log, is_write, is_atomic); if (typ & kAccessVptr) thr->is_vptr_access = false; + if (typ & kAccessFree) + thr->is_freeing = false; } void MemoryResetRange(ThreadState *thr, uptr pc, uptr addr, uptr size); diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp @@ -132,12 +132,8 @@ // Imitate a memory write to catch unlock-destroy races. // Do this outside of sync mutex, because it can report a race which locks // sync mutexes. - if (IsAppMem(addr)) { - CHECK(!thr->is_freeing); - thr->is_freeing = true; - MemoryAccess(thr, pc, addr, 1, kAccessWrite); - thr->is_freeing = false; - } + if (IsAppMem(addr)) + MemoryAccess(thr, pc, addr, 1, kAccessWrite | kAccessFree); // s will be destroyed and freed in MetaMap::FreeBlock. }