1353944Sdim//===-- tsan_new_delete.cpp ---------------------------------------------===// 2353944Sdim// 3353944Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353944Sdim// See https://llvm.org/LICENSE.txt for license information. 5353944Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353944Sdim// 7353944Sdim//===----------------------------------------------------------------------===// 8353944Sdim// 9353944Sdim// This file is a part of ThreadSanitizer (TSan), a race detector. 10353944Sdim// 11353944Sdim// Interceptors for operators new and delete. 12353944Sdim//===----------------------------------------------------------------------===// 13353944Sdim#include "interception/interception.h" 14353944Sdim#include "sanitizer_common/sanitizer_allocator.h" 15353944Sdim#include "sanitizer_common/sanitizer_allocator_report.h" 16353944Sdim#include "sanitizer_common/sanitizer_internal_defs.h" 17353944Sdim#include "tsan_interceptors.h" 18353944Sdim#include "tsan_rtl.h" 19353944Sdim 20353944Sdimusing namespace __tsan; 21353944Sdim 22353944Sdimnamespace std { 23353944Sdimstruct nothrow_t {}; 24353944Sdimenum class align_val_t: __sanitizer::uptr {}; 25353944Sdim} // namespace std 26353944Sdim 27353944SdimDECLARE_REAL(void *, malloc, uptr size) 28353944SdimDECLARE_REAL(void, free, void *ptr) 29353944Sdim 30353944Sdim// TODO(alekseys): throw std::bad_alloc instead of dying on OOM. 31353944Sdim#define OPERATOR_NEW_BODY(mangled_name, nothrow) \ 32353944Sdim if (in_symbolizer()) \ 33353944Sdim return InternalAlloc(size); \ 34353944Sdim void *p = 0; \ 35353944Sdim { \ 36353944Sdim SCOPED_INTERCEPTOR_RAW(mangled_name, size); \ 37353944Sdim p = user_alloc(thr, pc, size); \ 38353944Sdim if (!nothrow && UNLIKELY(!p)) { \ 39353944Sdim GET_STACK_TRACE_FATAL(thr, pc); \ 40353944Sdim ReportOutOfMemory(size, &stack); \ 41353944Sdim } \ 42353944Sdim } \ 43353944Sdim invoke_malloc_hook(p, size); \ 44353944Sdim return p; 45353944Sdim 46353944Sdim#define OPERATOR_NEW_BODY_ALIGN(mangled_name, nothrow) \ 47353944Sdim if (in_symbolizer()) \ 48353944Sdim return InternalAlloc(size, nullptr, (uptr)align); \ 49353944Sdim void *p = 0; \ 50353944Sdim { \ 51353944Sdim SCOPED_INTERCEPTOR_RAW(mangled_name, size); \ 52353944Sdim p = user_memalign(thr, pc, (uptr)align, size); \ 53353944Sdim if (!nothrow && UNLIKELY(!p)) { \ 54353944Sdim GET_STACK_TRACE_FATAL(thr, pc); \ 55353944Sdim ReportOutOfMemory(size, &stack); \ 56353944Sdim } \ 57353944Sdim } \ 58353944Sdim invoke_malloc_hook(p, size); \ 59353944Sdim return p; 60353944Sdim 61353944SdimSANITIZER_INTERFACE_ATTRIBUTE 62353944Sdimvoid *operator new(__sanitizer::uptr size); 63353944Sdimvoid *operator new(__sanitizer::uptr size) { 64353944Sdim OPERATOR_NEW_BODY(_Znwm, false /*nothrow*/); 65353944Sdim} 66353944Sdim 67353944SdimSANITIZER_INTERFACE_ATTRIBUTE 68353944Sdimvoid *operator new[](__sanitizer::uptr size); 69353944Sdimvoid *operator new[](__sanitizer::uptr size) { 70353944Sdim OPERATOR_NEW_BODY(_Znam, false /*nothrow*/); 71353944Sdim} 72353944Sdim 73353944SdimSANITIZER_INTERFACE_ATTRIBUTE 74353944Sdimvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&); 75353944Sdimvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&) { 76353944Sdim OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t, true /*nothrow*/); 77353944Sdim} 78353944Sdim 79353944SdimSANITIZER_INTERFACE_ATTRIBUTE 80353944Sdimvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&); 81353944Sdimvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&) { 82353944Sdim OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t, true /*nothrow*/); 83353944Sdim} 84353944Sdim 85353944SdimSANITIZER_INTERFACE_ATTRIBUTE 86353944Sdimvoid *operator new(__sanitizer::uptr size, std::align_val_t align); 87353944Sdimvoid *operator new(__sanitizer::uptr size, std::align_val_t align) { 88353944Sdim OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_t, false /*nothrow*/); 89353944Sdim} 90353944Sdim 91353944SdimSANITIZER_INTERFACE_ATTRIBUTE 92353944Sdimvoid *operator new[](__sanitizer::uptr size, std::align_val_t align); 93353944Sdimvoid *operator new[](__sanitizer::uptr size, std::align_val_t align) { 94353944Sdim OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_t, false /*nothrow*/); 95353944Sdim} 96353944Sdim 97353944SdimSANITIZER_INTERFACE_ATTRIBUTE 98353944Sdimvoid *operator new(__sanitizer::uptr size, std::align_val_t align, 99353944Sdim std::nothrow_t const&); 100353944Sdimvoid *operator new(__sanitizer::uptr size, std::align_val_t align, 101353944Sdim std::nothrow_t const&) { 102353944Sdim OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_tRKSt9nothrow_t, 103353944Sdim true /*nothrow*/); 104353944Sdim} 105353944Sdim 106353944SdimSANITIZER_INTERFACE_ATTRIBUTE 107353944Sdimvoid *operator new[](__sanitizer::uptr size, std::align_val_t align, 108353944Sdim std::nothrow_t const&); 109353944Sdimvoid *operator new[](__sanitizer::uptr size, std::align_val_t align, 110353944Sdim std::nothrow_t const&) { 111353944Sdim OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_tRKSt9nothrow_t, 112353944Sdim true /*nothrow*/); 113353944Sdim} 114353944Sdim 115353944Sdim#define OPERATOR_DELETE_BODY(mangled_name) \ 116353944Sdim if (ptr == 0) return; \ 117353944Sdim if (in_symbolizer()) \ 118353944Sdim return InternalFree(ptr); \ 119353944Sdim invoke_free_hook(ptr); \ 120353944Sdim SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \ 121353944Sdim user_free(thr, pc, ptr); 122353944Sdim 123353944SdimSANITIZER_INTERFACE_ATTRIBUTE 124353944Sdimvoid operator delete(void *ptr) NOEXCEPT; 125353944Sdimvoid operator delete(void *ptr) NOEXCEPT { 126353944Sdim OPERATOR_DELETE_BODY(_ZdlPv); 127353944Sdim} 128353944Sdim 129353944SdimSANITIZER_INTERFACE_ATTRIBUTE 130353944Sdimvoid operator delete[](void *ptr) NOEXCEPT; 131353944Sdimvoid operator delete[](void *ptr) NOEXCEPT { 132353944Sdim OPERATOR_DELETE_BODY(_ZdaPv); 133353944Sdim} 134353944Sdim 135353944SdimSANITIZER_INTERFACE_ATTRIBUTE 136353944Sdimvoid operator delete(void *ptr, std::nothrow_t const&); 137353944Sdimvoid operator delete(void *ptr, std::nothrow_t const&) { 138353944Sdim OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t); 139353944Sdim} 140353944Sdim 141353944SdimSANITIZER_INTERFACE_ATTRIBUTE 142353944Sdimvoid operator delete[](void *ptr, std::nothrow_t const&); 143353944Sdimvoid operator delete[](void *ptr, std::nothrow_t const&) { 144353944Sdim OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t); 145353944Sdim} 146353944Sdim 147353944SdimSANITIZER_INTERFACE_ATTRIBUTE 148353944Sdimvoid operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT; 149353944Sdimvoid operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT { 150353944Sdim OPERATOR_DELETE_BODY(_ZdlPvm); 151353944Sdim} 152353944Sdim 153353944SdimSANITIZER_INTERFACE_ATTRIBUTE 154353944Sdimvoid operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT; 155353944Sdimvoid operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT { 156353944Sdim OPERATOR_DELETE_BODY(_ZdaPvm); 157353944Sdim} 158353944Sdim 159353944SdimSANITIZER_INTERFACE_ATTRIBUTE 160353944Sdimvoid operator delete(void *ptr, std::align_val_t align) NOEXCEPT; 161353944Sdimvoid operator delete(void *ptr, std::align_val_t align) NOEXCEPT { 162353944Sdim OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_t); 163353944Sdim} 164353944Sdim 165353944SdimSANITIZER_INTERFACE_ATTRIBUTE 166353944Sdimvoid operator delete[](void *ptr, std::align_val_t align) NOEXCEPT; 167353944Sdimvoid operator delete[](void *ptr, std::align_val_t align) NOEXCEPT { 168353944Sdim OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_t); 169353944Sdim} 170353944Sdim 171353944SdimSANITIZER_INTERFACE_ATTRIBUTE 172353944Sdimvoid operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&); 173353944Sdimvoid operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) { 174353944Sdim OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_tRKSt9nothrow_t); 175353944Sdim} 176353944Sdim 177353944SdimSANITIZER_INTERFACE_ATTRIBUTE 178353944Sdimvoid operator delete[](void *ptr, std::align_val_t align, 179353944Sdim std::nothrow_t const&); 180353944Sdimvoid operator delete[](void *ptr, std::align_val_t align, 181353944Sdim std::nothrow_t const&) { 182353944Sdim OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_tRKSt9nothrow_t); 183353944Sdim} 184353944Sdim 185353944SdimSANITIZER_INTERFACE_ATTRIBUTE 186353944Sdimvoid operator delete(void *ptr, __sanitizer::uptr size, 187353944Sdim std::align_val_t align) NOEXCEPT; 188353944Sdimvoid operator delete(void *ptr, __sanitizer::uptr size, 189353944Sdim std::align_val_t align) NOEXCEPT { 190353944Sdim OPERATOR_DELETE_BODY(_ZdlPvmSt11align_val_t); 191353944Sdim} 192353944Sdim 193353944SdimSANITIZER_INTERFACE_ATTRIBUTE 194353944Sdimvoid operator delete[](void *ptr, __sanitizer::uptr size, 195353944Sdim std::align_val_t align) NOEXCEPT; 196353944Sdimvoid operator delete[](void *ptr, __sanitizer::uptr size, 197353944Sdim std::align_val_t align) NOEXCEPT { 198353944Sdim OPERATOR_DELETE_BODY(_ZdaPvmSt11align_val_t); 199353944Sdim} 200