brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · fc44a52 Raw
200 lines · cpp
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-exception6//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 20using namespace __tsan;21 22namespace std {23struct nothrow_t {};24enum class align_val_t: __sanitizer::uptr {};25}  // namespace std26 27DECLARE_REAL(void *, malloc, uptr size)28DECLARE_REAL(void, free, void *ptr)29 30// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.31#define OPERATOR_NEW_BODY(mangled_name, nothrow) \32  if (in_symbolizer()) \33    return InternalAlloc(size); \34  void *p = 0; \35  {  \36    SCOPED_INTERCEPTOR_RAW(mangled_name, size); \37    p = user_alloc(thr, pc, size); \38    if (!nothrow && UNLIKELY(!p)) { \39      GET_STACK_TRACE_FATAL(thr, pc); \40      ReportOutOfMemory(size, &stack); \41    } \42  }  \43  invoke_malloc_hook(p, size);  \44  return p;45 46#define OPERATOR_NEW_BODY_ALIGN(mangled_name, nothrow) \47  if (in_symbolizer()) \48    return InternalAlloc(size, nullptr, (uptr)align); \49  void *p = 0; \50  {  \51    SCOPED_INTERCEPTOR_RAW(mangled_name, size); \52    p = user_memalign(thr, pc, (uptr)align, size); \53    if (!nothrow && UNLIKELY(!p)) { \54      GET_STACK_TRACE_FATAL(thr, pc); \55      ReportOutOfMemory(size, &stack); \56    } \57  }  \58  invoke_malloc_hook(p, size);  \59  return p;60 61SANITIZER_INTERFACE_ATTRIBUTE62void *operator new(__sanitizer::uptr size);63void *operator new(__sanitizer::uptr size) {64  OPERATOR_NEW_BODY(_Znwm, false /*nothrow*/);65}66 67SANITIZER_INTERFACE_ATTRIBUTE68void *operator new[](__sanitizer::uptr size);69void *operator new[](__sanitizer::uptr size) {70  OPERATOR_NEW_BODY(_Znam, false /*nothrow*/);71}72 73SANITIZER_INTERFACE_ATTRIBUTE74void *operator new(__sanitizer::uptr size, std::nothrow_t const&);75void *operator new(__sanitizer::uptr size, std::nothrow_t const&) {76  OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t, true /*nothrow*/);77}78 79SANITIZER_INTERFACE_ATTRIBUTE80void *operator new[](__sanitizer::uptr size, std::nothrow_t const&);81void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {82  OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t, true /*nothrow*/);83}84 85SANITIZER_INTERFACE_ATTRIBUTE86void *operator new(__sanitizer::uptr size, std::align_val_t align);87void *operator new(__sanitizer::uptr size, std::align_val_t align) {88  OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_t, false /*nothrow*/);89}90 91SANITIZER_INTERFACE_ATTRIBUTE92void *operator new[](__sanitizer::uptr size, std::align_val_t align);93void *operator new[](__sanitizer::uptr size, std::align_val_t align) {94  OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_t, false /*nothrow*/);95}96 97SANITIZER_INTERFACE_ATTRIBUTE98void *operator new(__sanitizer::uptr size, std::align_val_t align,99                   std::nothrow_t const&);100void *operator new(__sanitizer::uptr size, std::align_val_t align,101                   std::nothrow_t const&) {102  OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_tRKSt9nothrow_t,103                          true /*nothrow*/);104}105 106SANITIZER_INTERFACE_ATTRIBUTE107void *operator new[](__sanitizer::uptr size, std::align_val_t align,108                     std::nothrow_t const&);109void *operator new[](__sanitizer::uptr size, std::align_val_t align,110                     std::nothrow_t const&) {111  OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_tRKSt9nothrow_t,112                          true /*nothrow*/);113}114 115#define OPERATOR_DELETE_BODY(mangled_name) \116  if (ptr == 0) return;  \117  if (in_symbolizer()) \118    return InternalFree(ptr); \119  invoke_free_hook(ptr);  \120  SCOPED_INTERCEPTOR_RAW(mangled_name, ptr);  \121  user_free(thr, pc, ptr);122 123SANITIZER_INTERFACE_ATTRIBUTE124void operator delete(void *ptr) NOEXCEPT;125void operator delete(void *ptr) NOEXCEPT {126  OPERATOR_DELETE_BODY(_ZdlPv);127}128 129SANITIZER_INTERFACE_ATTRIBUTE130void operator delete[](void *ptr) NOEXCEPT;131void operator delete[](void *ptr) NOEXCEPT {132  OPERATOR_DELETE_BODY(_ZdaPv);133}134 135SANITIZER_INTERFACE_ATTRIBUTE136void operator delete(void *ptr, std::nothrow_t const&);137void operator delete(void *ptr, std::nothrow_t const&) {138  OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);139}140 141SANITIZER_INTERFACE_ATTRIBUTE142void operator delete[](void *ptr, std::nothrow_t const&);143void operator delete[](void *ptr, std::nothrow_t const&) {144  OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);145}146 147SANITIZER_INTERFACE_ATTRIBUTE148void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT;149void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT {150  OPERATOR_DELETE_BODY(_ZdlPvm);151}152 153SANITIZER_INTERFACE_ATTRIBUTE154void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT;155void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT {156  OPERATOR_DELETE_BODY(_ZdaPvm);157}158 159SANITIZER_INTERFACE_ATTRIBUTE160void operator delete(void *ptr, std::align_val_t align) NOEXCEPT;161void operator delete(void *ptr, std::align_val_t align) NOEXCEPT {162  OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_t);163}164 165SANITIZER_INTERFACE_ATTRIBUTE166void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT;167void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {168  OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_t);169}170 171SANITIZER_INTERFACE_ATTRIBUTE172void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&);173void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) {174  OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_tRKSt9nothrow_t);175}176 177SANITIZER_INTERFACE_ATTRIBUTE178void operator delete[](void *ptr, std::align_val_t align,179                       std::nothrow_t const&);180void operator delete[](void *ptr, std::align_val_t align,181                       std::nothrow_t const&) {182  OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_tRKSt9nothrow_t);183}184 185SANITIZER_INTERFACE_ATTRIBUTE186void operator delete(void *ptr, __sanitizer::uptr size,187                     std::align_val_t align) NOEXCEPT;188void operator delete(void *ptr, __sanitizer::uptr size,189                     std::align_val_t align) NOEXCEPT {190  OPERATOR_DELETE_BODY(_ZdlPvmSt11align_val_t);191}192 193SANITIZER_INTERFACE_ATTRIBUTE194void operator delete[](void *ptr, __sanitizer::uptr size,195                       std::align_val_t align) NOEXCEPT;196void operator delete[](void *ptr, __sanitizer::uptr size,197                       std::align_val_t align) NOEXCEPT {198  OPERATOR_DELETE_BODY(_ZdaPvmSt11align_val_t);199}200