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