tsan_interceptors.h 3.3 KB

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