tsan_interceptors.h 4.2 KB

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