141 lines · c
1#ifndef TSAN_INTERCEPTORS_H2#define TSAN_INTERCEPTORS_H3 4#if SANITIZER_APPLE && !SANITIZER_GO5# include "sanitizer_common/sanitizer_mac.h"6#endif7#include "sanitizer_common/sanitizer_stacktrace.h"8#include "tsan_rtl.h"9 10namespace __tsan {11 12class ScopedInterceptor {13 public:14 ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc);15 ~ScopedInterceptor();16 void DisableIgnores() {17 if (UNLIKELY(ignoring_))18 DisableIgnoresImpl();19 }20 void EnableIgnores() {21 if (UNLIKELY(ignoring_))22 EnableIgnoresImpl();23 }24 25 private:26 ThreadState *const thr_;27 bool in_ignored_lib_ = false;28 bool in_blocking_func_ = false;29 bool ignoring_ = false;30 31 void DisableIgnoresImpl();32 void EnableIgnoresImpl();33};34 35struct TsanInterceptorContext {36 ThreadState *thr;37 const uptr pc;38};39 40LibIgnore *libignore();41 42#if !SANITIZER_GO43inline bool in_symbolizer() {44 return UNLIKELY(cur_thread_init()->in_symbolizer);45}46#endif47 48inline bool MustIgnoreInterceptor(ThreadState *thr) {49 return !thr->is_inited || thr->ignore_interceptors || thr->in_ignored_lib50#if SANITIZER_APPLE && !SANITIZER_GO51 || (flags()->lock_during_write != kLockDuringAllWrites &&52 thr->in_internal_write_call)53#endif54 ;55}56 57} // namespace __tsan58 59#define SCOPED_INTERCEPTOR_RAW(func, ...) \60 ThreadState *thr = cur_thread_init(); \61 ScopedInterceptor si(thr, #func, GET_CALLER_PC()); \62 UNUSED const uptr pc = GET_CURRENT_PC();63 64#ifdef __powerpc64__65// Debugging of crashes on powerpc after commit:66// c80604f7a3 ("tsan: remove real func check from interceptors")67// Somehow replacing if with DCHECK leads to strange failures in:68// SanitizerCommon-tsan-powerpc64le-Linux :: Linux/ptrace.cpp69// https://lab.llvm.org/buildbot/#/builders/10570// https://lab.llvm.org/buildbot/#/builders/12171// https://lab.llvm.org/buildbot/#/builders/5772# define CHECK_REAL_FUNC(func) \73 if (REAL(func) == 0) { \74 Report("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \75 Die(); \76 }77#else78# define CHECK_REAL_FUNC(func) DCHECK(REAL(func))79#endif80 81#define SCOPED_TSAN_INTERCEPTOR(func, ...) \82 SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \83 CHECK_REAL_FUNC(func); \84 if (MustIgnoreInterceptor(thr)) \85 return REAL(func)(__VA_ARGS__);86 87#define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START() \88 si.DisableIgnores();89 90#define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END() \91 si.EnableIgnores();92 93#define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)94 95#if SANITIZER_FREEBSD96# define TSAN_INTERCEPTOR_FREEBSD_ALIAS(ret, func, ...) \97 TSAN_INTERCEPTOR(ret, _pthread_##func, __VA_ARGS__) \98 ALIAS(WRAP(pthread_##func));99#else100# define TSAN_INTERCEPTOR_FREEBSD_ALIAS(ret, func, ...)101#endif102 103#if SANITIZER_NETBSD104# define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...) \105 TSAN_INTERCEPTOR(ret, __libc_##func, __VA_ARGS__) \106 ALIAS(WRAP(pthread_##func));107# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) \108 TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \109 ALIAS(WRAP(pthread_##func));110# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...) \111 TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \112 ALIAS(WRAP(pthread_##func2));113#else114# define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...)115# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...)116# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...)117#endif118 119#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)120 121#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED \122 (!cur_thread_init()->is_inited)123 124#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \125 MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr, \126 ((TsanInterceptorContext *)ctx)->pc, (uptr)ptr, size, \127 true)128 129#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \130 MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr, \131 ((TsanInterceptorContext *) ctx)->pc, (uptr) ptr, size, \132 false)133 134#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \135 SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__); \136 TsanInterceptorContext _ctx = {thr, pc}; \137 ctx = (void *)&_ctx; \138 (void)ctx;139 140#endif // TSAN_INTERCEPTORS_H141