@@ -140,12 +140,19 @@ static void RawInternalFree(void *ptr, InternalAllocatorCache *cache) {
140
140
141
141
const u64 kBlockMagic = 0x6A6CB03ABCEBC041ull ;
142
142
143
+ static void NORETURN ReportInternalAllocatorOutOfMemory (uptr requested_size) {
144
+ SetAllocatorOutOfMemory ();
145
+ Report (" FATAL: %s: internal allocator is out of memory trying to allocate "
146
+ " 0x%zx bytes\n " , SanitizerToolName, requested_size);
147
+ Die ();
148
+ }
149
+
143
150
void *InternalAlloc (uptr size, InternalAllocatorCache *cache, uptr alignment) {
144
151
if (size + sizeof (u64) < size)
145
152
return nullptr ;
146
153
void *p = RawInternalAlloc (size + sizeof (u64), cache, alignment);
147
154
if (UNLIKELY (!p))
148
- return DieOnFailure::OnOOM ( );
155
+ ReportInternalAllocatorOutOfMemory (size + sizeof (u64) );
149
156
((u64*)p)[0 ] = kBlockMagic ;
150
157
return (char *)p + sizeof (u64);
151
158
}
@@ -160,13 +167,17 @@ void *InternalRealloc(void *addr, uptr size, InternalAllocatorCache *cache) {
160
167
CHECK_EQ (kBlockMagic , ((u64*)addr)[0 ]);
161
168
void *p = RawInternalRealloc (addr, size, cache);
162
169
if (UNLIKELY (!p))
163
- return DieOnFailure::OnOOM ( );
170
+ ReportInternalAllocatorOutOfMemory (size );
164
171
return (char *)p + sizeof (u64);
165
172
}
166
173
167
174
void *InternalCalloc (uptr count, uptr size, InternalAllocatorCache *cache) {
168
- if (UNLIKELY (CheckForCallocOverflow (count, size)))
169
- return DieOnFailure::OnBadRequest ();
175
+ if (UNLIKELY (CheckForCallocOverflow (count, size))) {
176
+ Report (" FATAL: %s: calloc parameters overflow: count * size (%zd * %zd) "
177
+ " cannot be represented in type size_t\n " , SanitizerToolName, count,
178
+ size);
179
+ Die ();
180
+ }
170
181
void *p = InternalAlloc (count * size, cache);
171
182
if (LIKELY (p))
172
183
internal_memset (p, 0 , count * size);
@@ -215,6 +226,8 @@ void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback) {
215
226
low_level_alloc_callback = callback;
216
227
}
217
228
229
+ // Allocator's OOM and other errors handling support.
230
+
218
231
static atomic_uint8_t allocator_out_of_memory = {0 };
219
232
static atomic_uint8_t allocator_may_return_null = {0 };
220
233
@@ -226,15 +239,6 @@ void SetAllocatorOutOfMemory() {
226
239
atomic_store_relaxed (&allocator_out_of_memory, 1 );
227
240
}
228
241
229
- // Prints error message and kills the program.
230
- void NORETURN ReportAllocatorCannotReturnNull () {
231
- Report (" %s's allocator is terminating the process instead of returning 0\n " ,
232
- SanitizerToolName);
233
- Report (" If you don't like this behavior set allocator_may_return_null=1\n " );
234
- CHECK (0 );
235
- Die ();
236
- }
237
-
238
242
bool AllocatorMayReturnNull () {
239
243
return atomic_load (&allocator_may_return_null, memory_order_relaxed);
240
244
}
@@ -244,32 +248,9 @@ void SetAllocatorMayReturnNull(bool may_return_null) {
244
248
memory_order_relaxed);
245
249
}
246
250
247
- void *ReturnNullOrDieOnFailure::OnBadRequest () {
248
- if (AllocatorMayReturnNull ())
249
- return nullptr ;
250
- ReportAllocatorCannotReturnNull ();
251
- }
252
-
253
- void *ReturnNullOrDieOnFailure::OnOOM () {
254
- atomic_store_relaxed (&allocator_out_of_memory, 1 );
255
- if (AllocatorMayReturnNull ())
256
- return nullptr ;
257
- ReportAllocatorCannotReturnNull ();
258
- }
259
-
260
- void NORETURN *DieOnFailure::OnBadRequest () {
261
- ReportAllocatorCannotReturnNull ();
262
- }
263
-
264
- void NORETURN *DieOnFailure::OnOOM () {
265
- atomic_store_relaxed (&allocator_out_of_memory, 1 );
266
- ReportAllocatorCannotReturnNull ();
267
- }
268
-
269
- // Prints hint message.
270
- void PrintHintAllocatorCannotReturnNull (const char *options_name) {
251
+ void PrintHintAllocatorCannotReturnNull () {
271
252
Report (" HINT: if you don't care about these errors you may set "
272
- " %s= allocator_may_return_null=1\n " , options_name );
253
+ " allocator_may_return_null=1\n " );
273
254
}
274
255
275
256
} // namespace __sanitizer
0 commit comments