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