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