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_internal_defs.h" 16 #include "tsan_interceptors.h" 17 18 using namespace __tsan; // NOLINT 19 20 namespace std { 21 struct nothrow_t {}; 22 } // namespace std 23 24 DECLARE_REAL(void *, malloc, uptr size) 25 DECLARE_REAL(void, free, void *ptr) 26 #if SANITIZER_MAC || SANITIZER_ANDROID 27 #define __libc_malloc REAL(malloc) 28 #define __libc_free REAL(free) 29 #endif 30 31 #define OPERATOR_NEW_BODY(mangled_name) \ 32 if (cur_thread()->in_symbolizer) \ 33 return __libc_malloc(size); \ 34 void *p = 0; \ 35 { \ 36 SCOPED_INTERCEPTOR_RAW(mangled_name, size); \ 37 p = user_alloc(thr, pc, size); \ 38 } \ 39 invoke_malloc_hook(p, size); \ 40 return p; 41 42 SANITIZER_INTERFACE_ATTRIBUTE 43 void *operator new(__sanitizer::uptr size); 44 void *operator new(__sanitizer::uptr size) { 45 OPERATOR_NEW_BODY(_Znwm); 46 } 47 48 SANITIZER_INTERFACE_ATTRIBUTE 49 void *operator new[](__sanitizer::uptr size); 50 void *operator new[](__sanitizer::uptr size) { 51 OPERATOR_NEW_BODY(_Znam); 52 } 53 54 SANITIZER_INTERFACE_ATTRIBUTE 55 void *operator new(__sanitizer::uptr size, std::nothrow_t const&); 56 void *operator new(__sanitizer::uptr size, std::nothrow_t const&) { 57 OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t); 58 } 59 60 SANITIZER_INTERFACE_ATTRIBUTE 61 void *operator new[](__sanitizer::uptr size, std::nothrow_t const&); 62 void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) { 63 OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t); 64 } 65 66 #define OPERATOR_DELETE_BODY(mangled_name) \ 67 if (ptr == 0) return; \ 68 if (cur_thread()->in_symbolizer) \ 69 return __libc_free(ptr); \ 70 invoke_free_hook(ptr); \ 71 SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \ 72 user_free(thr, pc, ptr); 73 74 SANITIZER_INTERFACE_ATTRIBUTE 75 void operator delete(void *ptr) NOEXCEPT; 76 void operator delete(void *ptr) NOEXCEPT { 77 OPERATOR_DELETE_BODY(_ZdlPv); 78 } 79 80 SANITIZER_INTERFACE_ATTRIBUTE 81 void operator delete[](void *ptr) NOEXCEPT; 82 void operator delete[](void *ptr) NOEXCEPT { 83 OPERATOR_DELETE_BODY(_ZdaPv); 84 } 85 86 SANITIZER_INTERFACE_ATTRIBUTE 87 void operator delete(void *ptr, std::nothrow_t const&); 88 void operator delete(void *ptr, std::nothrow_t const&) { 89 OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t); 90 } 91 92 SANITIZER_INTERFACE_ATTRIBUTE 93 void operator delete[](void *ptr, std::nothrow_t const&); 94 void operator delete[](void *ptr, std::nothrow_t const&) { 95 OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t); 96 } 97