146 lines · cpp
1//===-- memprof_interceptors.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 MemProfiler, a memory profiler.10//11// Interceptors for operators new and delete.12//===----------------------------------------------------------------------===//13 14#include "memprof_allocator.h"15#include "memprof_internal.h"16#include "memprof_stack.h"17#include "sanitizer_common/sanitizer_allocator_report.h"18 19#include "interception/interception.h"20 21#include <stddef.h>22 23#define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE24 25using namespace __memprof;26 27// Fake std::nothrow_t and std::align_val_t to avoid including <new>.28namespace std {29struct nothrow_t {};30enum class align_val_t : size_t {};31} // namespace std32 33#define OPERATOR_NEW_BODY(type, nothrow) \34 GET_STACK_TRACE_MALLOC; \35 void *res = memprof_memalign(0, size, &stack, type); \36 if (!nothrow && UNLIKELY(!res)) \37 ReportOutOfMemory(size, &stack); \38 return res;39#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \40 GET_STACK_TRACE_MALLOC; \41 void *res = memprof_memalign((uptr)align, size, &stack, type); \42 if (!nothrow && UNLIKELY(!res)) \43 ReportOutOfMemory(size, &stack); \44 return res;45 46CXX_OPERATOR_ATTRIBUTE47void *operator new(size_t size) {48 OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/);49}50CXX_OPERATOR_ATTRIBUTE51void *operator new[](size_t size) {52 OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/);53}54CXX_OPERATOR_ATTRIBUTE55void *operator new(size_t size, std::nothrow_t const &) {56 OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/);57}58CXX_OPERATOR_ATTRIBUTE59void *operator new[](size_t size, std::nothrow_t const &) {60 OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/);61}62CXX_OPERATOR_ATTRIBUTE63void *operator new(size_t size, std::align_val_t align) {64 OPERATOR_NEW_BODY_ALIGN(FROM_NEW, false /*nothrow*/);65}66CXX_OPERATOR_ATTRIBUTE67void *operator new[](size_t size, std::align_val_t align) {68 OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, false /*nothrow*/);69}70CXX_OPERATOR_ATTRIBUTE71void *operator new(size_t size, std::align_val_t align,72 std::nothrow_t const &) {73 OPERATOR_NEW_BODY_ALIGN(FROM_NEW, true /*nothrow*/);74}75CXX_OPERATOR_ATTRIBUTE76void *operator new[](size_t size, std::align_val_t align,77 std::nothrow_t const &) {78 OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, true /*nothrow*/);79}80 81#define OPERATOR_DELETE_BODY(type) \82 GET_STACK_TRACE_FREE; \83 memprof_delete(ptr, 0, 0, &stack, type);84 85#define OPERATOR_DELETE_BODY_SIZE(type) \86 GET_STACK_TRACE_FREE; \87 memprof_delete(ptr, size, 0, &stack, type);88 89#define OPERATOR_DELETE_BODY_ALIGN(type) \90 GET_STACK_TRACE_FREE; \91 memprof_delete(ptr, 0, static_cast<uptr>(align), &stack, type);92 93#define OPERATOR_DELETE_BODY_SIZE_ALIGN(type) \94 GET_STACK_TRACE_FREE; \95 memprof_delete(ptr, size, static_cast<uptr>(align), &stack, type);96 97CXX_OPERATOR_ATTRIBUTE98void operator delete(void *ptr)NOEXCEPT { OPERATOR_DELETE_BODY(FROM_NEW); }99CXX_OPERATOR_ATTRIBUTE100void operator delete[](void *ptr) NOEXCEPT {101 OPERATOR_DELETE_BODY(FROM_NEW_BR);102}103CXX_OPERATOR_ATTRIBUTE104void operator delete(void *ptr, std::nothrow_t const &) {105 OPERATOR_DELETE_BODY(FROM_NEW);106}107CXX_OPERATOR_ATTRIBUTE108void operator delete[](void *ptr, std::nothrow_t const &) {109 OPERATOR_DELETE_BODY(FROM_NEW_BR);110}111CXX_OPERATOR_ATTRIBUTE112void operator delete(void *ptr, size_t size)NOEXCEPT {113 OPERATOR_DELETE_BODY_SIZE(FROM_NEW);114}115CXX_OPERATOR_ATTRIBUTE116void operator delete[](void *ptr, size_t size) NOEXCEPT {117 OPERATOR_DELETE_BODY_SIZE(FROM_NEW_BR);118}119CXX_OPERATOR_ATTRIBUTE120void operator delete(void *ptr, std::align_val_t align)NOEXCEPT {121 OPERATOR_DELETE_BODY_ALIGN(FROM_NEW);122}123CXX_OPERATOR_ATTRIBUTE124void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {125 OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR);126}127CXX_OPERATOR_ATTRIBUTE128void operator delete(void *ptr, std::align_val_t align,129 std::nothrow_t const &) {130 OPERATOR_DELETE_BODY_ALIGN(FROM_NEW);131}132CXX_OPERATOR_ATTRIBUTE133void operator delete[](void *ptr, std::align_val_t align,134 std::nothrow_t const &) {135 OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR);136}137CXX_OPERATOR_ATTRIBUTE138void operator delete(void *ptr, size_t size, std::align_val_t align)NOEXCEPT {139 OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW);140}141CXX_OPERATOR_ATTRIBUTE142void operator delete[](void *ptr, size_t size,143 std::align_val_t align) NOEXCEPT {144 OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW_BR);145}146