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