1 //===-- tsan_new_delete.cc ----------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
9 //
10 // Interceptors for operators new and delete.
11 //===----------------------------------------------------------------------===//
12 #include "interception/interception.h"
13 #include "sanitizer_common/sanitizer_allocator.h"
14 #include "sanitizer_common/sanitizer_internal_defs.h"
15 #include "tsan_interceptors.h"
16 
17 using namespace __tsan;  // NOLINT
18 
19 namespace std {
20 struct nothrow_t {};
21 }  // namespace std
22 
23 DECLARE_REAL(void *, malloc, uptr size)
24 DECLARE_REAL(void, free, void *ptr)
25 
26 // TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
27 #define OPERATOR_NEW_BODY(mangled_name, nothrow) \
28   if (cur_thread()->in_symbolizer) \
29     return InternalAlloc(size); \
30   void *p = 0; \
31   {  \
32     SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
33     p = user_alloc(thr, pc, size); \
34     if (!nothrow && UNLIKELY(!p)) DieOnFailure::OnOOM(); \
35   }  \
36   invoke_malloc_hook(p, size);  \
37   return p;
38 
39 SANITIZER_INTERFACE_ATTRIBUTE
40 void *operator new(__sanitizer::uptr size);
operator new(__sanitizer::uptr size)41 void *operator new(__sanitizer::uptr size) {
42   OPERATOR_NEW_BODY(_Znwm, false /*nothrow*/);
43 }
44 
45 SANITIZER_INTERFACE_ATTRIBUTE
46 void *operator new[](__sanitizer::uptr size);
operator new[](__sanitizer::uptr size)47 void *operator new[](__sanitizer::uptr size) {
48   OPERATOR_NEW_BODY(_Znam, false /*nothrow*/);
49 }
50 
51 SANITIZER_INTERFACE_ATTRIBUTE
52 void *operator new(__sanitizer::uptr size, std::nothrow_t const&);
operator new(__sanitizer::uptr size,std::nothrow_t const &)53 void *operator new(__sanitizer::uptr size, std::nothrow_t const&) {
54   OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t, true /*nothrow*/);
55 }
56 
57 SANITIZER_INTERFACE_ATTRIBUTE
58 void *operator new[](__sanitizer::uptr size, std::nothrow_t const&);
operator new[](__sanitizer::uptr size,std::nothrow_t const &)59 void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {
60   OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t, true /*nothrow*/);
61 }
62 
63 #define OPERATOR_DELETE_BODY(mangled_name) \
64   if (ptr == 0) return;  \
65   if (cur_thread()->in_symbolizer) \
66     return InternalFree(ptr); \
67   invoke_free_hook(ptr);  \
68   SCOPED_INTERCEPTOR_RAW(mangled_name, ptr);  \
69   user_free(thr, pc, ptr);
70 
71 SANITIZER_INTERFACE_ATTRIBUTE
72 void operator delete(void *ptr) NOEXCEPT;
operator delete(void * ptr)73 void operator delete(void *ptr) NOEXCEPT {
74   OPERATOR_DELETE_BODY(_ZdlPv);
75 }
76 
77 SANITIZER_INTERFACE_ATTRIBUTE
78 void operator delete[](void *ptr) NOEXCEPT;
operator delete[](void * ptr)79 void operator delete[](void *ptr) NOEXCEPT {
80   OPERATOR_DELETE_BODY(_ZdaPv);
81 }
82 
83 SANITIZER_INTERFACE_ATTRIBUTE
84 void operator delete(void *ptr, std::nothrow_t const&);
operator delete(void * ptr,std::nothrow_t const &)85 void operator delete(void *ptr, std::nothrow_t const&) {
86   OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
87 }
88 
89 SANITIZER_INTERFACE_ATTRIBUTE
90 void operator delete[](void *ptr, std::nothrow_t const&);
operator delete[](void * ptr,std::nothrow_t const &)91 void operator delete[](void *ptr, std::nothrow_t const&) {
92   OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
93 }
94