tsan_interceptors.h 3.2 KB

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