Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_new_delete.cpp
35266 views
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-exception
6
//
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
20
using namespace __tsan;
21
22
namespace std {
23
struct nothrow_t {};
24
enum class align_val_t: __sanitizer::uptr {};
25
} // namespace std
26
27
DECLARE_REAL(void *, malloc, uptr size)
28
DECLARE_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
61
SANITIZER_INTERFACE_ATTRIBUTE
62
void *operator new(__sanitizer::uptr size);
63
void *operator new(__sanitizer::uptr size) {
64
OPERATOR_NEW_BODY(_Znwm, false /*nothrow*/);
65
}
66
67
SANITIZER_INTERFACE_ATTRIBUTE
68
void *operator new[](__sanitizer::uptr size);
69
void *operator new[](__sanitizer::uptr size) {
70
OPERATOR_NEW_BODY(_Znam, false /*nothrow*/);
71
}
72
73
SANITIZER_INTERFACE_ATTRIBUTE
74
void *operator new(__sanitizer::uptr size, std::nothrow_t const&);
75
void *operator new(__sanitizer::uptr size, std::nothrow_t const&) {
76
OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t, true /*nothrow*/);
77
}
78
79
SANITIZER_INTERFACE_ATTRIBUTE
80
void *operator new[](__sanitizer::uptr size, std::nothrow_t const&);
81
void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {
82
OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t, true /*nothrow*/);
83
}
84
85
SANITIZER_INTERFACE_ATTRIBUTE
86
void *operator new(__sanitizer::uptr size, std::align_val_t align);
87
void *operator new(__sanitizer::uptr size, std::align_val_t align) {
88
OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_t, false /*nothrow*/);
89
}
90
91
SANITIZER_INTERFACE_ATTRIBUTE
92
void *operator new[](__sanitizer::uptr size, std::align_val_t align);
93
void *operator new[](__sanitizer::uptr size, std::align_val_t align) {
94
OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_t, false /*nothrow*/);
95
}
96
97
SANITIZER_INTERFACE_ATTRIBUTE
98
void *operator new(__sanitizer::uptr size, std::align_val_t align,
99
std::nothrow_t const&);
100
void *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
106
SANITIZER_INTERFACE_ATTRIBUTE
107
void *operator new[](__sanitizer::uptr size, std::align_val_t align,
108
std::nothrow_t const&);
109
void *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
123
SANITIZER_INTERFACE_ATTRIBUTE
124
void operator delete(void *ptr) NOEXCEPT;
125
void operator delete(void *ptr) NOEXCEPT {
126
OPERATOR_DELETE_BODY(_ZdlPv);
127
}
128
129
SANITIZER_INTERFACE_ATTRIBUTE
130
void operator delete[](void *ptr) NOEXCEPT;
131
void operator delete[](void *ptr) NOEXCEPT {
132
OPERATOR_DELETE_BODY(_ZdaPv);
133
}
134
135
SANITIZER_INTERFACE_ATTRIBUTE
136
void operator delete(void *ptr, std::nothrow_t const&);
137
void operator delete(void *ptr, std::nothrow_t const&) {
138
OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
139
}
140
141
SANITIZER_INTERFACE_ATTRIBUTE
142
void operator delete[](void *ptr, std::nothrow_t const&);
143
void operator delete[](void *ptr, std::nothrow_t const&) {
144
OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
145
}
146
147
SANITIZER_INTERFACE_ATTRIBUTE
148
void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT;
149
void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT {
150
OPERATOR_DELETE_BODY(_ZdlPvm);
151
}
152
153
SANITIZER_INTERFACE_ATTRIBUTE
154
void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT;
155
void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT {
156
OPERATOR_DELETE_BODY(_ZdaPvm);
157
}
158
159
SANITIZER_INTERFACE_ATTRIBUTE
160
void operator delete(void *ptr, std::align_val_t align) NOEXCEPT;
161
void operator delete(void *ptr, std::align_val_t align) NOEXCEPT {
162
OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_t);
163
}
164
165
SANITIZER_INTERFACE_ATTRIBUTE
166
void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT;
167
void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {
168
OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_t);
169
}
170
171
SANITIZER_INTERFACE_ATTRIBUTE
172
void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&);
173
void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) {
174
OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_tRKSt9nothrow_t);
175
}
176
177
SANITIZER_INTERFACE_ATTRIBUTE
178
void operator delete[](void *ptr, std::align_val_t align,
179
std::nothrow_t const&);
180
void operator delete[](void *ptr, std::align_val_t align,
181
std::nothrow_t const&) {
182
OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_tRKSt9nothrow_t);
183
}
184
185
SANITIZER_INTERFACE_ATTRIBUTE
186
void operator delete(void *ptr, __sanitizer::uptr size,
187
std::align_val_t align) NOEXCEPT;
188
void operator delete(void *ptr, __sanitizer::uptr size,
189
std::align_val_t align) NOEXCEPT {
190
OPERATOR_DELETE_BODY(_ZdlPvmSt11align_val_t);
191
}
192
193
SANITIZER_INTERFACE_ATTRIBUTE
194
void operator delete[](void *ptr, __sanitizer::uptr size,
195
std::align_val_t align) NOEXCEPT;
196
void operator delete[](void *ptr, __sanitizer::uptr size,
197
std::align_val_t align) NOEXCEPT {
198
OPERATOR_DELETE_BODY(_ZdaPvmSt11align_val_t);
199
}
200
201