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