tsan_new_delete.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //===-- tsan_new_delete.cpp ---------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is a part of ThreadSanitizer (TSan), a race detector.
  10. //
  11. // Interceptors for operators new and delete.
  12. //===----------------------------------------------------------------------===//
  13. #include "interception/interception.h"
  14. #include "sanitizer_common/sanitizer_allocator.h"
  15. #include "sanitizer_common/sanitizer_allocator_report.h"
  16. #include "sanitizer_common/sanitizer_internal_defs.h"
  17. #include "tsan_interceptors.h"
  18. #include "tsan_rtl.h"
  19. using namespace __tsan;
  20. namespace std {
  21. struct nothrow_t {};
  22. enum class align_val_t: __sanitizer::uptr {};
  23. } // namespace std
  24. DECLARE_REAL(void *, malloc, uptr size)
  25. DECLARE_REAL(void, free, void *ptr)
  26. // TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
  27. #define OPERATOR_NEW_BODY(mangled_name, nothrow) \
  28. if (in_symbolizer()) \
  29. return InternalAlloc(size); \
  30. void *p = 0; \
  31. { \
  32. SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
  33. p = user_alloc(thr, pc, size); \
  34. if (!nothrow && UNLIKELY(!p)) { \
  35. GET_STACK_TRACE_FATAL(thr, pc); \
  36. ReportOutOfMemory(size, &stack); \
  37. } \
  38. } \
  39. invoke_malloc_hook(p, size); \
  40. return p;
  41. #define OPERATOR_NEW_BODY_ALIGN(mangled_name, nothrow) \
  42. if (in_symbolizer()) \
  43. return InternalAlloc(size, nullptr, (uptr)align); \
  44. void *p = 0; \
  45. { \
  46. SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
  47. p = user_memalign(thr, pc, (uptr)align, size); \
  48. if (!nothrow && UNLIKELY(!p)) { \
  49. GET_STACK_TRACE_FATAL(thr, pc); \
  50. ReportOutOfMemory(size, &stack); \
  51. } \
  52. } \
  53. invoke_malloc_hook(p, size); \
  54. return p;
  55. SANITIZER_INTERFACE_ATTRIBUTE
  56. void *operator new(__sanitizer::uptr size);
  57. void *operator new(__sanitizer::uptr size) {
  58. OPERATOR_NEW_BODY(_Znwm, false /*nothrow*/);
  59. }
  60. SANITIZER_INTERFACE_ATTRIBUTE
  61. void *operator new[](__sanitizer::uptr size);
  62. void *operator new[](__sanitizer::uptr size) {
  63. OPERATOR_NEW_BODY(_Znam, false /*nothrow*/);
  64. }
  65. SANITIZER_INTERFACE_ATTRIBUTE
  66. void *operator new(__sanitizer::uptr size, std::nothrow_t const&);
  67. void *operator new(__sanitizer::uptr size, std::nothrow_t const&) {
  68. OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t, true /*nothrow*/);
  69. }
  70. SANITIZER_INTERFACE_ATTRIBUTE
  71. void *operator new[](__sanitizer::uptr size, std::nothrow_t const&);
  72. void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {
  73. OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t, true /*nothrow*/);
  74. }
  75. SANITIZER_INTERFACE_ATTRIBUTE
  76. void *operator new(__sanitizer::uptr size, std::align_val_t align);
  77. void *operator new(__sanitizer::uptr size, std::align_val_t align) {
  78. OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_t, false /*nothrow*/);
  79. }
  80. SANITIZER_INTERFACE_ATTRIBUTE
  81. void *operator new[](__sanitizer::uptr size, std::align_val_t align);
  82. void *operator new[](__sanitizer::uptr size, std::align_val_t align) {
  83. OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_t, false /*nothrow*/);
  84. }
  85. SANITIZER_INTERFACE_ATTRIBUTE
  86. void *operator new(__sanitizer::uptr size, std::align_val_t align,
  87. std::nothrow_t const&);
  88. void *operator new(__sanitizer::uptr size, std::align_val_t align,
  89. std::nothrow_t const&) {
  90. OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_tRKSt9nothrow_t,
  91. true /*nothrow*/);
  92. }
  93. SANITIZER_INTERFACE_ATTRIBUTE
  94. void *operator new[](__sanitizer::uptr size, std::align_val_t align,
  95. std::nothrow_t const&);
  96. void *operator new[](__sanitizer::uptr size, std::align_val_t align,
  97. std::nothrow_t const&) {
  98. OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_tRKSt9nothrow_t,
  99. true /*nothrow*/);
  100. }
  101. #define OPERATOR_DELETE_BODY(mangled_name) \
  102. if (ptr == 0) return; \
  103. if (in_symbolizer()) \
  104. return InternalFree(ptr); \
  105. invoke_free_hook(ptr); \
  106. SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \
  107. user_free(thr, pc, ptr);
  108. SANITIZER_INTERFACE_ATTRIBUTE
  109. void operator delete(void *ptr) NOEXCEPT;
  110. void operator delete(void *ptr) NOEXCEPT {
  111. OPERATOR_DELETE_BODY(_ZdlPv);
  112. }
  113. SANITIZER_INTERFACE_ATTRIBUTE
  114. void operator delete[](void *ptr) NOEXCEPT;
  115. void operator delete[](void *ptr) NOEXCEPT {
  116. OPERATOR_DELETE_BODY(_ZdaPv);
  117. }
  118. SANITIZER_INTERFACE_ATTRIBUTE
  119. void operator delete(void *ptr, std::nothrow_t const&);
  120. void operator delete(void *ptr, std::nothrow_t const&) {
  121. OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
  122. }
  123. SANITIZER_INTERFACE_ATTRIBUTE
  124. void operator delete[](void *ptr, std::nothrow_t const&);
  125. void operator delete[](void *ptr, std::nothrow_t const&) {
  126. OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
  127. }
  128. SANITIZER_INTERFACE_ATTRIBUTE
  129. void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT;
  130. void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT {
  131. OPERATOR_DELETE_BODY(_ZdlPvm);
  132. }
  133. SANITIZER_INTERFACE_ATTRIBUTE
  134. void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT;
  135. void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT {
  136. OPERATOR_DELETE_BODY(_ZdaPvm);
  137. }
  138. SANITIZER_INTERFACE_ATTRIBUTE
  139. void operator delete(void *ptr, std::align_val_t align) NOEXCEPT;
  140. void operator delete(void *ptr, std::align_val_t align) NOEXCEPT {
  141. OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_t);
  142. }
  143. SANITIZER_INTERFACE_ATTRIBUTE
  144. void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT;
  145. void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {
  146. OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_t);
  147. }
  148. SANITIZER_INTERFACE_ATTRIBUTE
  149. void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&);
  150. void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) {
  151. OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_tRKSt9nothrow_t);
  152. }
  153. SANITIZER_INTERFACE_ATTRIBUTE
  154. void operator delete[](void *ptr, std::align_val_t align,
  155. std::nothrow_t const&);
  156. void operator delete[](void *ptr, std::align_val_t align,
  157. std::nothrow_t const&) {
  158. OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_tRKSt9nothrow_t);
  159. }
  160. SANITIZER_INTERFACE_ATTRIBUTE
  161. void operator delete(void *ptr, __sanitizer::uptr size,
  162. std::align_val_t align) NOEXCEPT;
  163. void operator delete(void *ptr, __sanitizer::uptr size,
  164. std::align_val_t align) NOEXCEPT {
  165. OPERATOR_DELETE_BODY(_ZdlPvmSt11align_val_t);
  166. }
  167. SANITIZER_INTERFACE_ATTRIBUTE
  168. void operator delete[](void *ptr, __sanitizer::uptr size,
  169. std::align_val_t align) NOEXCEPT;
  170. void operator delete[](void *ptr, __sanitizer::uptr size,
  171. std::align_val_t align) NOEXCEPT {
  172. OPERATOR_DELETE_BODY(_ZdaPvmSt11align_val_t);
  173. }