Index: lib/tsan/rtl/tsan_fd.cc =================================================================== --- lib/tsan/rtl/tsan_fd.cc +++ lib/tsan/rtl/tsan_fd.cc @@ -115,7 +115,7 @@ MemoryRangeImitateWrite(thr, pc, (uptr)d, 8); } else { // See the dup-related comment in FdClose. - MemoryRead(thr, pc, (uptr)d, kSizeLog8); + MemoryRead(thr, pc, (uptr)d, kSizeLog8, true); } } @@ -163,7 +163,7 @@ FdDesc *d = fddesc(thr, pc, fd); FdSync *s = d->sync; DPrintf("#%d: FdAcquire(%d) -> %p\n", thr->tid, fd, s); - MemoryRead(thr, pc, (uptr)d, kSizeLog8); + MemoryRead(thr, pc, (uptr)d, kSizeLog8, true); if (s) Acquire(thr, pc, (uptr)s); } @@ -174,7 +174,7 @@ FdDesc *d = fddesc(thr, pc, fd); FdSync *s = d->sync; DPrintf("#%d: FdRelease(%d) -> %p\n", thr->tid, fd, s); - MemoryRead(thr, pc, (uptr)d, kSizeLog8); + MemoryRead(thr, pc, (uptr)d, kSizeLog8, true); if (s) Release(thr, pc, (uptr)s); } @@ -184,7 +184,7 @@ if (bogusfd(fd)) return; FdDesc *d = fddesc(thr, pc, fd); - MemoryRead(thr, pc, (uptr)d, kSizeLog8); + MemoryRead(thr, pc, (uptr)d, kSizeLog8, true); } void FdClose(ThreadState *thr, uptr pc, int fd, bool write) { @@ -194,7 +194,7 @@ FdDesc *d = fddesc(thr, pc, fd); if (write) { // To catch races between fd usage and close. - MemoryWrite(thr, pc, (uptr)d, kSizeLog8); + MemoryWrite(thr, pc, (uptr)d, kSizeLog8, true); } else { // This path is used only by dup2/dup3 calls. // We do read instead of write because there is a number of legitimate @@ -204,7 +204,7 @@ // 2. Some daemons dup /dev/null in place of stdin/stdout. // On the other hand we have not seen cases when write here catches real // bugs. - MemoryRead(thr, pc, (uptr)d, kSizeLog8); + MemoryRead(thr, pc, (uptr)d, kSizeLog8, true); } // We need to clear it, because if we do not intercept any call out there // that creates fd, we will hit false postives. @@ -228,7 +228,7 @@ return; // Ignore the case when user dups not yet connected socket. FdDesc *od = fddesc(thr, pc, oldfd); - MemoryRead(thr, pc, (uptr)od, kSizeLog8); + MemoryRead(thr, pc, (uptr)od, kSizeLog8, true); FdClose(thr, pc, newfd, write); init(thr, pc, newfd, ref(od->sync), write); } Index: lib/tsan/rtl/tsan_flags.inc =================================================================== --- lib/tsan/rtl/tsan_flags.inc +++ lib/tsan/rtl/tsan_flags.inc @@ -76,3 +76,5 @@ TSAN_FLAG(bool, die_after_fork, true, "Die after multi-threaded fork if the child creates new threads.") TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.") +TSAN_FLAG(bool, ignore_interceptors_accesses, false, + "Ignore reads and writes from all interceptors.") Index: lib/tsan/rtl/tsan_interceptors.cc =================================================================== --- lib/tsan/rtl/tsan_interceptors.cc +++ lib/tsan/rtl/tsan_interceptors.cc @@ -278,7 +278,7 @@ #define READ_STRING_OF_LEN(thr, pc, s, len, n) \ MemoryAccessRange((thr), (pc), (uptr)(s), \ - common_flags()->strict_string_checks ? (len) + 1 : (n), false) + common_flags()->strict_string_checks ? (len) + 1 : (n), false, true) #define READ_STRING(thr, pc, s, n) \ READ_STRING_OF_LEN((thr), (pc), (s), internal_strlen(s), (n)) @@ -614,7 +614,7 @@ TSAN_INTERCEPTOR(uptr, strlen, const char *s) { SCOPED_TSAN_INTERCEPTOR(strlen, s); uptr len = internal_strlen(s); - MemoryAccessRange(thr, pc, (uptr)s, len + 1, false); + MemoryAccessRange(thr, pc, (uptr)s, len + 1, false, true); return len; } @@ -622,7 +622,7 @@ // On FreeBSD we get here from libthr internals on thread initialization. if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { SCOPED_TSAN_INTERCEPTOR(memset, dst, v, size); - MemoryAccessRange(thr, pc, (uptr)dst, size, true); + MemoryAccessRange(thr, pc, (uptr)dst, size, true, true); } return internal_memset(dst, v, size); } @@ -631,8 +631,8 @@ // On FreeBSD we get here from libthr internals on thread initialization. if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { SCOPED_TSAN_INTERCEPTOR(memcpy, dst, src, size); - MemoryAccessRange(thr, pc, (uptr)dst, size, true); - MemoryAccessRange(thr, pc, (uptr)src, size, false); + MemoryAccessRange(thr, pc, (uptr)dst, size, true, true); + MemoryAccessRange(thr, pc, (uptr)src, size, false, true); } // On OS X, calling internal_memcpy here will cause memory corruptions, // because memcpy and memmove are actually aliases of the same implementation. @@ -643,8 +643,8 @@ TSAN_INTERCEPTOR(void*, memmove, void *dst, void *src, uptr n) { if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { SCOPED_TSAN_INTERCEPTOR(memmove, dst, src, n); - MemoryAccessRange(thr, pc, (uptr)dst, n, true); - MemoryAccessRange(thr, pc, (uptr)src, n, false); + MemoryAccessRange(thr, pc, (uptr)dst, n, true, true); + MemoryAccessRange(thr, pc, (uptr)src, n, false, true); } return REAL(memmove)(dst, src, n); } @@ -670,23 +670,23 @@ TSAN_INTERCEPTOR(char*, strrchr, char *s, int c) { SCOPED_TSAN_INTERCEPTOR(strrchr, s, c); - MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s) + 1, false); + MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s) + 1, false, true); return REAL(strrchr)(s, c); } TSAN_INTERCEPTOR(char*, strcpy, char *dst, const char *src) { // NOLINT SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src); // NOLINT uptr srclen = internal_strlen(src); - MemoryAccessRange(thr, pc, (uptr)dst, srclen + 1, true); - MemoryAccessRange(thr, pc, (uptr)src, srclen + 1, false); + MemoryAccessRange(thr, pc, (uptr)dst, srclen + 1, true, true); + MemoryAccessRange(thr, pc, (uptr)src, srclen + 1, false, true); return REAL(strcpy)(dst, src); // NOLINT } TSAN_INTERCEPTOR(char*, strncpy, char *dst, char *src, uptr n) { SCOPED_TSAN_INTERCEPTOR(strncpy, dst, src, n); uptr srclen = internal_strnlen(src, n); - MemoryAccessRange(thr, pc, (uptr)dst, n, true); - MemoryAccessRange(thr, pc, (uptr)src, min(srclen + 1, n), false); + MemoryAccessRange(thr, pc, (uptr)dst, n, true, true); + MemoryAccessRange(thr, pc, (uptr)src, min(srclen + 1, n), false, true); return REAL(strncpy)(dst, src, n); } @@ -1047,14 +1047,14 @@ INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { void *cond = init_cond(c, true); SCOPED_TSAN_INTERCEPTOR(pthread_cond_init, cond, a); - MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), true); + MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), true, true); return REAL(pthread_cond_init)(cond, a); } INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { void *cond = init_cond(c); SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait, cond, m); - MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false); + MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false, true); MutexUnlock(thr, pc, (uptr)m); CondMutexUnlockCtx arg = {&si, thr, pc, m}; int res = 0; @@ -1076,7 +1076,7 @@ INTERCEPTOR(int, pthread_cond_timedwait, void *c, void *m, void *abstime) { void *cond = init_cond(c); SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait, cond, m, abstime); - MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false); + MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false, true); MutexUnlock(thr, pc, (uptr)m); CondMutexUnlockCtx arg = {&si, thr, pc, m}; int res = 0; @@ -1097,21 +1097,21 @@ INTERCEPTOR(int, pthread_cond_signal, void *c) { void *cond = init_cond(c); SCOPED_TSAN_INTERCEPTOR(pthread_cond_signal, cond); - MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false); + MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false, true); return REAL(pthread_cond_signal)(cond); } INTERCEPTOR(int, pthread_cond_broadcast, void *c) { void *cond = init_cond(c); SCOPED_TSAN_INTERCEPTOR(pthread_cond_broadcast, cond); - MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false); + MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), false, true); return REAL(pthread_cond_broadcast)(cond); } INTERCEPTOR(int, pthread_cond_destroy, void *c) { void *cond = init_cond(c); SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy, cond); - MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), true); + MemoryAccessRange(thr, pc, (uptr)c, sizeof(uptr), true, true); int res = REAL(pthread_cond_destroy)(cond); if (common_flags()->legacy_pthread_cond) { // Free our aux cond and zero the pointer to not leave dangling pointers. @@ -1806,7 +1806,7 @@ // libc file streams can call user-supplied functions, see fopencookie. { SCOPED_TSAN_INTERCEPTOR(fread, ptr, size, nmemb, f); - MemoryAccessRange(thr, pc, (uptr)ptr, size * nmemb, true); + MemoryAccessRange(thr, pc, (uptr)ptr, size * nmemb, true, true); } return REAL(fread)(ptr, size, nmemb, f); } @@ -1815,7 +1815,7 @@ // libc file streams can call user-supplied functions, see fopencookie. { SCOPED_TSAN_INTERCEPTOR(fwrite, p, size, nmemb, f); - MemoryAccessRange(thr, pc, (uptr)p, size * nmemb, false); + MemoryAccessRange(thr, pc, (uptr)p, size * nmemb, false, true); } return REAL(fwrite)(p, size, nmemb, f); } @@ -1835,7 +1835,7 @@ TSAN_INTERCEPTOR(int, puts, const char *s) { SCOPED_TSAN_INTERCEPTOR(puts, s); - MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s), false); + MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s), false, true); return REAL(puts)(s); } @@ -2268,12 +2268,12 @@ #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr, \ ((TsanInterceptorContext *)ctx)->pc, (uptr)ptr, size, \ - true) + true, true) #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr, \ ((TsanInterceptorContext *) ctx)->pc, (uptr) ptr, size, \ - false) + false, true) #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__); \ Index: lib/tsan/rtl/tsan_interface.cc =================================================================== --- lib/tsan/rtl/tsan_interface.cc +++ lib/tsan/rtl/tsan_interface.cc @@ -29,23 +29,23 @@ } void __tsan_read16(void *addr) { - MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); - MemoryRead(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8); + MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8, false); + MemoryRead(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8, false); } void __tsan_write16(void *addr) { - MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); - MemoryWrite(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8); + MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8, false); + MemoryWrite(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8, false); } void __tsan_read16_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8); - MemoryRead(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8); + MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8, false); + MemoryRead(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8, false); } void __tsan_write16_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8); - MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8); + MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8, false); + MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8, false); } // __tsan_unaligned_read/write calls are emitted by compiler. Index: lib/tsan/rtl/tsan_interface_atomic.cc =================================================================== --- lib/tsan/rtl/tsan_interface_atomic.cc +++ lib/tsan/rtl/tsan_interface_atomic.cc @@ -249,14 +249,14 @@ // This fast-path is critical for performance. // Assume the access is atomic. if (!IsAcquireOrder(mo)) { - MemoryReadAtomic(thr, pc, (uptr)a, SizeLog()); + MemoryReadAtomic(thr, pc, (uptr)a, SizeLog(), false); return NoTsanAtomicLoad(a, mo); } SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, (uptr)a, false); AcquireImpl(thr, pc, &s->clock); T v = NoTsanAtomicLoad(a, mo); s->mtx.ReadUnlock(); - MemoryReadAtomic(thr, pc, (uptr)a, SizeLog()); + MemoryReadAtomic(thr, pc, (uptr)a, SizeLog(), false); return v; } @@ -276,7 +276,7 @@ static void AtomicStore(ThreadState *thr, uptr pc, volatile T *a, T v, morder mo) { CHECK(IsStoreOrder(mo)); - MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog()); + MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog(), false); // This fast-path is critical for performance. // Assume the access is atomic. // Strictly saying even relaxed store cuts off release sequence, @@ -297,7 +297,7 @@ template static T AtomicRMW(ThreadState *thr, uptr pc, volatile T *a, T v, morder mo) { - MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog()); + MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog(), false); SyncVar *s = 0; if (mo != mo_relaxed) { s = ctx->metamap.GetOrCreateAndLock(thr, pc, (uptr)a, true); @@ -421,7 +421,7 @@ static bool AtomicCAS(ThreadState *thr, uptr pc, volatile T *a, T *c, T v, morder mo, morder fmo) { (void)fmo; // Unused because llvm does not pass it yet. - MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog()); + MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog(), false); SyncVar *s = 0; bool write_lock = mo != mo_acquire && mo != mo_consume; if (mo != mo_relaxed) { Index: lib/tsan/rtl/tsan_interface_inl.h =================================================================== --- lib/tsan/rtl/tsan_interface_inl.h +++ lib/tsan/rtl/tsan_interface_inl.h @@ -19,67 +19,67 @@ using namespace __tsan; // NOLINT void __tsan_read1(void *addr) { - MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1); + MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1, false); } void __tsan_read2(void *addr) { - MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2); + MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2, false); } void __tsan_read4(void *addr) { - MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4); + MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4, false); } void __tsan_read8(void *addr) { - MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); + MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8, false); } void __tsan_write1(void *addr) { - MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1); + MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1, false); } void __tsan_write2(void *addr) { - MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2); + MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2, false); } void __tsan_write4(void *addr) { - MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4); + MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4, false); } void __tsan_write8(void *addr) { - MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); + MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8, false); } void __tsan_read1_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1); + MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1, false); } void __tsan_read2_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2); + MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2, false); } void __tsan_read4_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4); + MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4, false); } void __tsan_read8_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8); + MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8, false); } void __tsan_write1_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1); + MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1, false); } void __tsan_write2_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2); + MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2, false); } void __tsan_write4_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4); + MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4, false); } void __tsan_write8_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8); + MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8, false); } void __tsan_vptr_update(void **vptr_p, void *new_val) { @@ -87,7 +87,7 @@ if (*vptr_p != new_val) { ThreadState *thr = cur_thread(); thr->is_vptr_access = true; - MemoryWrite(thr, CALLERPC, (uptr)vptr_p, kSizeLog8); + MemoryWrite(thr, CALLERPC, (uptr)vptr_p, kSizeLog8, false); thr->is_vptr_access = false; } } @@ -96,7 +96,7 @@ CHECK_EQ(sizeof(vptr_p), 8); ThreadState *thr = cur_thread(); thr->is_vptr_access = true; - MemoryRead(thr, CALLERPC, (uptr)vptr_p, kSizeLog8); + MemoryRead(thr, CALLERPC, (uptr)vptr_p, kSizeLog8, false); thr->is_vptr_access = false; } @@ -109,9 +109,9 @@ } void __tsan_read_range(void *addr, uptr size) { - MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, false); + MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, false, false); } void __tsan_write_range(void *addr, uptr size) { - MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true); + MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true, false); } Index: lib/tsan/rtl/tsan_rtl.h =================================================================== --- lib/tsan/rtl/tsan_rtl.h +++ lib/tsan/rtl/tsan_rtl.h @@ -629,9 +629,7 @@ int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic, u64 *shadow_mem, Shadow cur); void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr, - uptr size, bool is_write); -void MemoryAccessRangeStep(ThreadState *thr, uptr pc, uptr addr, - uptr size, uptr step, bool is_write); + uptr size, bool is_write, bool from_interceptor); void UnalignedMemoryAccess(ThreadState *thr, uptr pc, uptr addr, int size, bool kAccessIsWrite, bool kIsAtomic); @@ -640,23 +638,28 @@ const int kSizeLog4 = 2; const int kSizeLog8 = 3; -void ALWAYS_INLINE MemoryRead(ThreadState *thr, uptr pc, - uptr addr, int kAccessSizeLog) { +void ALWAYS_INLINE MemoryRead(ThreadState *thr, uptr pc, uptr addr, + int kAccessSizeLog, bool from_interceptor) { + if (from_interceptor && flags()->ignore_interceptors_accesses) return; MemoryAccess(thr, pc, addr, kAccessSizeLog, false, false); } -void ALWAYS_INLINE MemoryWrite(ThreadState *thr, uptr pc, - uptr addr, int kAccessSizeLog) { +void ALWAYS_INLINE MemoryWrite(ThreadState *thr, uptr pc, uptr addr, + int kAccessSizeLog, bool from_interceptor) { + if (from_interceptor && flags()->ignore_interceptors_accesses) return; MemoryAccess(thr, pc, addr, kAccessSizeLog, true, false); } -void ALWAYS_INLINE MemoryReadAtomic(ThreadState *thr, uptr pc, - uptr addr, int kAccessSizeLog) { +void ALWAYS_INLINE MemoryReadAtomic(ThreadState *thr, uptr pc, uptr addr, + int kAccessSizeLog, bool from_interceptor) { + if (from_interceptor && flags()->ignore_interceptors_accesses) return; MemoryAccess(thr, pc, addr, kAccessSizeLog, false, true); } -void ALWAYS_INLINE MemoryWriteAtomic(ThreadState *thr, uptr pc, - uptr addr, int kAccessSizeLog) { +void ALWAYS_INLINE MemoryWriteAtomic(ThreadState *thr, uptr pc, uptr addr, + int kAccessSizeLog, + bool from_interceptor) { + if (from_interceptor && flags()->ignore_interceptors_accesses) return; MemoryAccess(thr, pc, addr, kAccessSizeLog, true, true); } Index: lib/tsan/rtl/tsan_rtl.cc =================================================================== --- lib/tsan/rtl/tsan_rtl.cc +++ lib/tsan/rtl/tsan_rtl.cc @@ -889,7 +889,7 @@ size = 1024; CHECK_EQ(thr->is_freeing, false); thr->is_freeing = true; - MemoryAccessRange(thr, pc, addr, size, true); + MemoryAccessRange(thr, pc, addr, size, true, true); thr->is_freeing = false; if (kCollectHistory) { thr->fast_state.IncrementEpoch(); Index: lib/tsan/rtl/tsan_rtl_mutex.cc =================================================================== --- lib/tsan/rtl/tsan_rtl_mutex.cc +++ lib/tsan/rtl/tsan_rtl_mutex.cc @@ -69,7 +69,7 @@ if (!linker_init && IsAppMem(addr)) { CHECK(!thr->is_freeing); thr->is_freeing = true; - MemoryWrite(thr, pc, addr, kSizeLog1); + MemoryWrite(thr, pc, addr, kSizeLog1, true); thr->is_freeing = false; } SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true); @@ -93,7 +93,7 @@ if (IsAppMem(addr)) { CHECK(!thr->is_freeing); thr->is_freeing = true; - MemoryWrite(thr, pc, addr, kSizeLog1); + MemoryWrite(thr, pc, addr, kSizeLog1, true); thr->is_freeing = false; } SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr); @@ -144,7 +144,7 @@ DPrintf("#%d: MutexLock %zx rec=%d\n", thr->tid, addr, rec); CHECK_GT(rec, 0); if (IsAppMem(addr)) - MemoryReadAtomic(thr, pc, addr, kSizeLog1); + MemoryReadAtomic(thr, pc, addr, kSizeLog1, true); SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true); thr->fast_state.IncrementEpoch(); TraceAddEvent(thr, thr->fast_state, EventTypeLock, s->GetId()); @@ -188,7 +188,7 @@ int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, bool all) { DPrintf("#%d: MutexUnlock %zx all=%d\n", thr->tid, addr, all); if (IsAppMem(addr)) - MemoryReadAtomic(thr, pc, addr, kSizeLog1); + MemoryReadAtomic(thr, pc, addr, kSizeLog1, true); SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true); thr->fast_state.IncrementEpoch(); TraceAddEvent(thr, thr->fast_state, EventTypeUnlock, s->GetId()); @@ -232,7 +232,7 @@ DPrintf("#%d: MutexReadLock %zx\n", thr->tid, addr); StatInc(thr, StatMutexReadLock); if (IsAppMem(addr)) - MemoryReadAtomic(thr, pc, addr, kSizeLog1); + MemoryReadAtomic(thr, pc, addr, kSizeLog1, true); SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, false); thr->fast_state.IncrementEpoch(); TraceAddEvent(thr, thr->fast_state, EventTypeRLock, s->GetId()); @@ -267,7 +267,7 @@ DPrintf("#%d: MutexReadUnlock %zx\n", thr->tid, addr); StatInc(thr, StatMutexReadUnlock); if (IsAppMem(addr)) - MemoryReadAtomic(thr, pc, addr, kSizeLog1); + MemoryReadAtomic(thr, pc, addr, kSizeLog1, true); SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true); thr->fast_state.IncrementEpoch(); TraceAddEvent(thr, thr->fast_state, EventTypeRUnlock, s->GetId()); @@ -298,7 +298,7 @@ void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) { DPrintf("#%d: MutexReadOrWriteUnlock %zx\n", thr->tid, addr); if (IsAppMem(addr)) - MemoryReadAtomic(thr, pc, addr, kSizeLog1); + MemoryReadAtomic(thr, pc, addr, kSizeLog1, true); SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true); bool write = true; bool report_bad_unlock = false; Index: lib/tsan/rtl/tsan_rtl_thread.cc =================================================================== --- lib/tsan/rtl/tsan_rtl_thread.cc +++ lib/tsan/rtl/tsan_rtl_thread.cc @@ -330,7 +330,8 @@ } void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr, - uptr size, bool is_write) { + uptr size, bool is_write, bool from_interceptor) { + if (from_interceptor && flags()->ignore_interceptors_accesses) return; if (size == 0) return;