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