1 #ifndef TSAN_INTERCEPTORS_H 2 #define TSAN_INTERCEPTORS_H 3 4 #include "sanitizer_common/sanitizer_stacktrace.h" 5 #include "tsan_rtl.h" 6 7 namespace __tsan { 8 9 class ScopedInterceptor { 10 public: 11 ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc); 12 ~ScopedInterceptor(); 13 void DisableIgnores() { 14 if (UNLIKELY(ignoring_)) 15 DisableIgnoresImpl(); 16 } 17 void EnableIgnores() { 18 if (UNLIKELY(ignoring_)) 19 EnableIgnoresImpl(); 20 } 21 22 private: 23 ThreadState *const thr_; 24 bool in_ignored_lib_ = false; 25 bool in_blocking_func_ = false; 26 bool ignoring_ = false; 27 28 void DisableIgnoresImpl(); 29 void EnableIgnoresImpl(); 30 }; 31 32 LibIgnore *libignore(); 33 34 #if !SANITIZER_GO 35 inline bool in_symbolizer() { 36 return UNLIKELY(cur_thread_init()->in_symbolizer); 37 } 38 #endif 39 40 inline bool MustIgnoreInterceptor(ThreadState *thr) { 41 return !thr->is_inited || thr->ignore_interceptors || thr->in_ignored_lib; 42 } 43 44 } // namespace __tsan 45 46 #define SCOPED_INTERCEPTOR_RAW(func, ...) \ 47 ThreadState *thr = cur_thread_init(); \ 48 ScopedInterceptor si(thr, #func, GET_CALLER_PC()); \ 49 UNUSED const uptr pc = GET_CURRENT_PC(); 50 51 #ifdef __powerpc64__ 52 // Debugging of crashes on powerpc after commit: 53 // c80604f7a3 ("tsan: remove real func check from interceptors") 54 // Somehow replacing if with DCHECK leads to strange failures in: 55 // SanitizerCommon-tsan-powerpc64le-Linux :: Linux/ptrace.cpp 56 // https://lab.llvm.org/buildbot/#/builders/105 57 // https://lab.llvm.org/buildbot/#/builders/121 58 // https://lab.llvm.org/buildbot/#/builders/57 59 # define CHECK_REAL_FUNC(func) \ 60 if (REAL(func) == 0) { \ 61 Report("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \ 62 Die(); \ 63 } 64 #else 65 # define CHECK_REAL_FUNC(func) DCHECK(REAL(func)) 66 #endif 67 68 #define SCOPED_TSAN_INTERCEPTOR(func, ...) \ 69 SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \ 70 CHECK_REAL_FUNC(func); \ 71 if (MustIgnoreInterceptor(thr)) \ 72 return REAL(func)(__VA_ARGS__); 73 74 #define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START() \ 75 si.DisableIgnores(); 76 77 #define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END() \ 78 si.EnableIgnores(); 79 80 #define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__) 81 82 #if SANITIZER_FREEBSD 83 # define TSAN_INTERCEPTOR_FREEBSD_ALIAS(ret, func, ...) \ 84 TSAN_INTERCEPTOR(ret, _pthread_##func, __VA_ARGS__) \ 85 ALIAS(WRAPPER_NAME(pthread_##func)); 86 #else 87 # define TSAN_INTERCEPTOR_FREEBSD_ALIAS(ret, func, ...) 88 #endif 89 90 #if SANITIZER_NETBSD 91 # define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...) \ 92 TSAN_INTERCEPTOR(ret, __libc_##func, __VA_ARGS__) \ 93 ALIAS(WRAPPER_NAME(pthread_##func)); 94 # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) \ 95 TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \ 96 ALIAS(WRAPPER_NAME(pthread_##func)); 97 # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...) \ 98 TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \ 99 ALIAS(WRAPPER_NAME(pthread_##func2)); 100 #else 101 # define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...) 102 # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) 103 # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...) 104 #endif 105 106 #endif // TSAN_INTERCEPTORS_H 107