[Reland][Runtimes] Merge 'compile_commands.json' files from runtimes build (#116303)
[llvm-project.git] / compiler-rt / lib / lsan / lsan_interceptors.cpp
bloba8252cddacf25f59bb39f6a24e17664825fe0d06
1 //=-- lsan_interceptors.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 LeakSanitizer.
10 // Interceptors for standalone LSan.
12 //===----------------------------------------------------------------------===//
14 #include "interception/interception.h"
15 #include "sanitizer_common/sanitizer_allocator.h"
16 #include "sanitizer_common/sanitizer_allocator_dlsym.h"
17 #include "sanitizer_common/sanitizer_allocator_report.h"
18 #include "sanitizer_common/sanitizer_atomic.h"
19 #include "sanitizer_common/sanitizer_common.h"
20 #include "sanitizer_common/sanitizer_flags.h"
21 #include "sanitizer_common/sanitizer_internal_defs.h"
22 #include "sanitizer_common/sanitizer_linux.h"
23 #include "sanitizer_common/sanitizer_platform_interceptors.h"
24 #include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
25 #include "sanitizer_common/sanitizer_platform_limits_posix.h"
26 #if SANITIZER_POSIX
27 #include "sanitizer_common/sanitizer_posix.h"
28 #endif
29 #include "lsan.h"
30 #include "lsan_allocator.h"
31 #include "lsan_common.h"
32 #include "lsan_thread.h"
34 #include <stddef.h>
36 using namespace __lsan;
38 extern "C" {
39 int pthread_attr_init(void *attr);
40 int pthread_attr_destroy(void *attr);
41 int pthread_attr_getdetachstate(void *attr, int *v);
42 int pthread_key_create(unsigned *key, void (*destructor)(void* v));
43 int pthread_setspecific(unsigned key, const void *v);
46 struct DlsymAlloc : DlSymAllocator<DlsymAlloc> {
47 static bool UseImpl() { return lsan_init_is_running; }
48 static void OnAllocate(const void *ptr, uptr size) {
49 #if CAN_SANITIZE_LEAKS
50 // Suppress leaks from dlerror(). Previously dlsym hack on global array was
51 // used by leak sanitizer as a root region.
52 __lsan_register_root_region(ptr, size);
53 #endif
55 static void OnFree(const void *ptr, uptr size) {
56 #if CAN_SANITIZE_LEAKS
57 __lsan_unregister_root_region(ptr, size);
58 #endif
62 ///// Malloc/free interceptors. /////
64 namespace std {
65 struct nothrow_t;
66 enum class align_val_t: size_t;
69 #if !SANITIZER_APPLE
70 INTERCEPTOR(void*, malloc, uptr size) {
71 if (DlsymAlloc::Use())
72 return DlsymAlloc::Allocate(size);
73 ENSURE_LSAN_INITED;
74 GET_STACK_TRACE_MALLOC;
75 return lsan_malloc(size, stack);
78 INTERCEPTOR(void, free, void *p) {
79 if (UNLIKELY(!p))
80 return;
81 if (DlsymAlloc::PointerIsMine(p))
82 return DlsymAlloc::Free(p);
83 ENSURE_LSAN_INITED;
84 lsan_free(p);
87 INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
88 if (DlsymAlloc::Use())
89 return DlsymAlloc::Callocate(nmemb, size);
90 ENSURE_LSAN_INITED;
91 GET_STACK_TRACE_MALLOC;
92 return lsan_calloc(nmemb, size, stack);
95 INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
96 if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
97 return DlsymAlloc::Realloc(ptr, size);
98 ENSURE_LSAN_INITED;
99 GET_STACK_TRACE_MALLOC;
100 return lsan_realloc(ptr, size, stack);
103 INTERCEPTOR(void*, reallocarray, void *q, uptr nmemb, uptr size) {
104 ENSURE_LSAN_INITED;
105 GET_STACK_TRACE_MALLOC;
106 return lsan_reallocarray(q, nmemb, size, stack);
109 INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
110 ENSURE_LSAN_INITED;
111 GET_STACK_TRACE_MALLOC;
112 return lsan_posix_memalign(memptr, alignment, size, stack);
115 INTERCEPTOR(void*, valloc, uptr size) {
116 ENSURE_LSAN_INITED;
117 GET_STACK_TRACE_MALLOC;
118 return lsan_valloc(size, stack);
120 #endif // !SANITIZER_APPLE
122 #if SANITIZER_INTERCEPT_MEMALIGN
123 INTERCEPTOR(void*, memalign, uptr alignment, uptr size) {
124 ENSURE_LSAN_INITED;
125 GET_STACK_TRACE_MALLOC;
126 return lsan_memalign(alignment, size, stack);
128 #define LSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
129 #else
130 #define LSAN_MAYBE_INTERCEPT_MEMALIGN
131 #endif // SANITIZER_INTERCEPT_MEMALIGN
133 #if SANITIZER_INTERCEPT___LIBC_MEMALIGN
134 INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {
135 ENSURE_LSAN_INITED;
136 GET_STACK_TRACE_MALLOC;
137 return lsan_memalign(alignment, size, stack);
139 #define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)
140 #else
141 #define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
142 #endif // SANITIZER_INTERCEPT___LIBC_MEMALIGN
144 #if SANITIZER_INTERCEPT_ALIGNED_ALLOC
145 INTERCEPTOR(void*, aligned_alloc, uptr alignment, uptr size) {
146 ENSURE_LSAN_INITED;
147 GET_STACK_TRACE_MALLOC;
148 return lsan_aligned_alloc(alignment, size, stack);
150 #define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)
151 #else
152 #define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC
153 #endif
155 #if SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE
156 INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
157 ENSURE_LSAN_INITED;
158 return GetMallocUsableSize(ptr);
160 #define LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE \
161 INTERCEPT_FUNCTION(malloc_usable_size)
162 #else
163 #define LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE
164 #endif
166 #if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
167 struct fake_mallinfo {
168 int x[10];
171 INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
172 struct fake_mallinfo res;
173 internal_memset(&res, 0, sizeof(res));
174 return res;
176 #define LSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)
178 INTERCEPTOR(int, mallopt, int cmd, int value) {
179 return 0;
181 #define LSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)
182 #else
183 #define LSAN_MAYBE_INTERCEPT_MALLINFO
184 #define LSAN_MAYBE_INTERCEPT_MALLOPT
185 #endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
187 #if SANITIZER_INTERCEPT_PVALLOC
188 INTERCEPTOR(void*, pvalloc, uptr size) {
189 ENSURE_LSAN_INITED;
190 GET_STACK_TRACE_MALLOC;
191 return lsan_pvalloc(size, stack);
193 #define LSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
194 #else
195 #define LSAN_MAYBE_INTERCEPT_PVALLOC
196 #endif // SANITIZER_INTERCEPT_PVALLOC
198 #if SANITIZER_INTERCEPT_CFREE
199 INTERCEPTOR(void, cfree, void *p) ALIAS(WRAP(free));
200 #define LSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)
201 #else
202 #define LSAN_MAYBE_INTERCEPT_CFREE
203 #endif // SANITIZER_INTERCEPT_CFREE
205 #if SANITIZER_INTERCEPT_MCHECK_MPROBE
206 INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {
207 return 0;
210 INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {
211 return 0;
214 INTERCEPTOR(int, mprobe, void *ptr) {
215 return 0;
217 #endif // SANITIZER_INTERCEPT_MCHECK_MPROBE
220 // TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
221 #define OPERATOR_NEW_BODY(nothrow)\
222 ENSURE_LSAN_INITED;\
223 GET_STACK_TRACE_MALLOC;\
224 void *res = lsan_malloc(size, stack);\
225 if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
226 return res;
227 #define OPERATOR_NEW_BODY_ALIGN(nothrow)\
228 ENSURE_LSAN_INITED;\
229 GET_STACK_TRACE_MALLOC;\
230 void *res = lsan_memalign((uptr)align, size, stack);\
231 if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
232 return res;
234 #define OPERATOR_DELETE_BODY\
235 ENSURE_LSAN_INITED;\
236 lsan_free(ptr);
238 // On OS X it's not enough to just provide our own 'operator new' and
239 // 'operator delete' implementations, because they're going to be in the runtime
240 // dylib, and the main executable will depend on both the runtime dylib and
241 // libstdc++, each of has its implementation of new and delete.
242 // To make sure that C++ allocation/deallocation operators are overridden on
243 // OS X we need to intercept them using their mangled names.
244 #if !SANITIZER_APPLE
246 INTERCEPTOR_ATTRIBUTE
247 void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
248 INTERCEPTOR_ATTRIBUTE
249 void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
250 INTERCEPTOR_ATTRIBUTE
251 void *operator new(size_t size, std::nothrow_t const&)
252 { OPERATOR_NEW_BODY(true /*nothrow*/); }
253 INTERCEPTOR_ATTRIBUTE
254 void *operator new[](size_t size, std::nothrow_t const&)
255 { OPERATOR_NEW_BODY(true /*nothrow*/); }
256 INTERCEPTOR_ATTRIBUTE
257 void *operator new(size_t size, std::align_val_t align)
258 { OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); }
259 INTERCEPTOR_ATTRIBUTE
260 void *operator new[](size_t size, std::align_val_t align)
261 { OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); }
262 INTERCEPTOR_ATTRIBUTE
263 void *operator new(size_t size, std::align_val_t align, std::nothrow_t const&)
264 { OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); }
265 INTERCEPTOR_ATTRIBUTE
266 void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&)
267 { OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); }
269 INTERCEPTOR_ATTRIBUTE
270 void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
271 INTERCEPTOR_ATTRIBUTE
272 void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
273 INTERCEPTOR_ATTRIBUTE
274 void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }
275 INTERCEPTOR_ATTRIBUTE
276 void operator delete[](void *ptr, std::nothrow_t const &)
277 { OPERATOR_DELETE_BODY; }
278 INTERCEPTOR_ATTRIBUTE
279 void operator delete(void *ptr, size_t size) NOEXCEPT
280 { OPERATOR_DELETE_BODY; }
281 INTERCEPTOR_ATTRIBUTE
282 void operator delete[](void *ptr, size_t size) NOEXCEPT
283 { OPERATOR_DELETE_BODY; }
284 INTERCEPTOR_ATTRIBUTE
285 void operator delete(void *ptr, std::align_val_t) NOEXCEPT
286 { OPERATOR_DELETE_BODY; }
287 INTERCEPTOR_ATTRIBUTE
288 void operator delete[](void *ptr, std::align_val_t) NOEXCEPT
289 { OPERATOR_DELETE_BODY; }
290 INTERCEPTOR_ATTRIBUTE
291 void operator delete(void *ptr, std::align_val_t, std::nothrow_t const&)
292 { OPERATOR_DELETE_BODY; }
293 INTERCEPTOR_ATTRIBUTE
294 void operator delete[](void *ptr, std::align_val_t, std::nothrow_t const&)
295 { OPERATOR_DELETE_BODY; }
296 INTERCEPTOR_ATTRIBUTE
297 void operator delete(void *ptr, size_t size, std::align_val_t) NOEXCEPT
298 { OPERATOR_DELETE_BODY; }
299 INTERCEPTOR_ATTRIBUTE
300 void operator delete[](void *ptr, size_t size, std::align_val_t) NOEXCEPT
301 { OPERATOR_DELETE_BODY; }
303 #else // SANITIZER_APPLE
305 INTERCEPTOR(void *, _Znwm, size_t size)
306 { OPERATOR_NEW_BODY(false /*nothrow*/); }
307 INTERCEPTOR(void *, _Znam, size_t size)
308 { OPERATOR_NEW_BODY(false /*nothrow*/); }
309 INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&)
310 { OPERATOR_NEW_BODY(true /*nothrow*/); }
311 INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&)
312 { OPERATOR_NEW_BODY(true /*nothrow*/); }
314 INTERCEPTOR(void, _ZdlPv, void *ptr)
315 { OPERATOR_DELETE_BODY; }
316 INTERCEPTOR(void, _ZdaPv, void *ptr)
317 { OPERATOR_DELETE_BODY; }
318 INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)
319 { OPERATOR_DELETE_BODY; }
320 INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)
321 { OPERATOR_DELETE_BODY; }
323 #endif // !SANITIZER_APPLE
326 ///// Thread initialization and finalization. /////
328 #if !SANITIZER_NETBSD && !SANITIZER_FREEBSD && !SANITIZER_FUCHSIA
329 static unsigned g_thread_finalize_key;
331 static void thread_finalize(void *v) {
332 uptr iter = (uptr)v;
333 if (iter > 1) {
334 if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) {
335 Report("LeakSanitizer: failed to set thread key.\n");
336 Die();
338 return;
340 ThreadFinish();
342 #endif
344 #if SANITIZER_NETBSD
345 INTERCEPTOR(void, _lwp_exit) {
346 ENSURE_LSAN_INITED;
347 ThreadFinish();
348 REAL(_lwp_exit)();
350 #define LSAN_MAYBE_INTERCEPT__LWP_EXIT INTERCEPT_FUNCTION(_lwp_exit)
351 #else
352 #define LSAN_MAYBE_INTERCEPT__LWP_EXIT
353 #endif
355 #if SANITIZER_INTERCEPT_THR_EXIT
356 INTERCEPTOR(void, thr_exit, tid_t *state) {
357 ENSURE_LSAN_INITED;
358 ThreadFinish();
359 REAL(thr_exit)(state);
361 #define LSAN_MAYBE_INTERCEPT_THR_EXIT INTERCEPT_FUNCTION(thr_exit)
362 #else
363 #define LSAN_MAYBE_INTERCEPT_THR_EXIT
364 #endif
366 #if SANITIZER_INTERCEPT___CXA_ATEXIT
367 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
368 void *dso_handle) {
369 __lsan::ScopedInterceptorDisabler disabler;
370 return REAL(__cxa_atexit)(func, arg, dso_handle);
372 #define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT INTERCEPT_FUNCTION(__cxa_atexit)
373 #else
374 #define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT
375 #endif
377 #if SANITIZER_INTERCEPT_ATEXIT
378 INTERCEPTOR(int, atexit, void (*f)()) {
379 __lsan::ScopedInterceptorDisabler disabler;
380 return REAL(__cxa_atexit)((void (*)(void *a))f, 0, 0);
382 #define LSAN_MAYBE_INTERCEPT_ATEXIT INTERCEPT_FUNCTION(atexit)
383 #else
384 #define LSAN_MAYBE_INTERCEPT_ATEXIT
385 #endif
387 #if SANITIZER_INTERCEPT_PTHREAD_ATFORK
388 extern "C" {
389 extern int _pthread_atfork(void (*prepare)(), void (*parent)(),
390 void (*child)());
393 INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(),
394 void (*child)()) {
395 __lsan::ScopedInterceptorDisabler disabler;
396 // REAL(pthread_atfork) cannot be called due to symbol indirections at least
397 // on NetBSD
398 return _pthread_atfork(prepare, parent, child);
400 #define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK INTERCEPT_FUNCTION(pthread_atfork)
401 #else
402 #define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK
403 #endif
405 #if SANITIZER_INTERCEPT_STRERROR
406 INTERCEPTOR(char *, strerror, int errnum) {
407 __lsan::ScopedInterceptorDisabler disabler;
408 return REAL(strerror)(errnum);
410 #define LSAN_MAYBE_INTERCEPT_STRERROR INTERCEPT_FUNCTION(strerror)
411 #else
412 #define LSAN_MAYBE_INTERCEPT_STRERROR
413 #endif
415 #if SANITIZER_POSIX
417 template <bool Detached>
418 static void *ThreadStartFunc(void *arg) {
419 u32 parent_tid = (uptr)arg;
420 uptr tid = ThreadCreate(parent_tid, Detached);
421 // Wait until the last iteration to maximize the chance that we are the last
422 // destructor to run.
423 #if !SANITIZER_NETBSD && !SANITIZER_FREEBSD
424 if (pthread_setspecific(g_thread_finalize_key,
425 (void*)GetPthreadDestructorIterations())) {
426 Report("LeakSanitizer: failed to set thread key.\n");
427 Die();
429 # endif
430 ThreadStart(tid, GetTid());
431 auto self = GetThreadSelf();
432 auto args = GetThreadArgRetval().GetArgs(self);
433 void *retval = (*args.routine)(args.arg_retval);
434 GetThreadArgRetval().Finish(self, retval);
435 return retval;
438 INTERCEPTOR(int, pthread_create, void *th, void *attr,
439 void *(*callback)(void *), void *param) {
440 ENSURE_LSAN_INITED;
441 EnsureMainThreadIDIsCorrect();
443 bool detached = [attr]() {
444 int d = 0;
445 return attr && !pthread_attr_getdetachstate(attr, &d) && IsStateDetached(d);
446 }();
448 __sanitizer_pthread_attr_t myattr;
449 if (!attr) {
450 pthread_attr_init(&myattr);
451 attr = &myattr;
453 AdjustStackSize(attr);
454 uptr this_tid = GetCurrentThreadId();
455 int result;
457 // Ignore all allocations made by pthread_create: thread stack/TLS may be
458 // stored by pthread for future reuse even after thread destruction, and
459 // the linked list it's stored in doesn't even hold valid pointers to the
460 // objects, the latter are calculated by obscure pointer arithmetic.
461 ScopedInterceptorDisabler disabler;
462 GetThreadArgRetval().Create(detached, {callback, param}, [&]() -> uptr {
463 result = REAL(pthread_create)(
464 th, attr, detached ? ThreadStartFunc<true> : ThreadStartFunc<false>,
465 (void *)this_tid);
466 return result ? 0 : *(uptr *)(th);
469 if (attr == &myattr)
470 pthread_attr_destroy(&myattr);
471 return result;
474 INTERCEPTOR(int, pthread_join, void *thread, void **retval) {
475 int result;
476 GetThreadArgRetval().Join((uptr)thread, [&]() {
477 result = REAL(pthread_join)(thread, retval);
478 return !result;
480 return result;
483 INTERCEPTOR(int, pthread_detach, void *thread) {
484 int result;
485 GetThreadArgRetval().Detach((uptr)thread, [&]() {
486 result = REAL(pthread_detach)(thread);
487 return !result;
489 return result;
492 INTERCEPTOR(void, pthread_exit, void *retval) {
493 GetThreadArgRetval().Finish(GetThreadSelf(), retval);
494 REAL(pthread_exit)(retval);
497 # if SANITIZER_INTERCEPT_TRYJOIN
498 INTERCEPTOR(int, pthread_tryjoin_np, void *thread, void **ret) {
499 int result;
500 GetThreadArgRetval().Join((uptr)thread, [&]() {
501 result = REAL(pthread_tryjoin_np)(thread, ret);
502 return !result;
504 return result;
506 # define LSAN_MAYBE_INTERCEPT_TRYJOIN INTERCEPT_FUNCTION(pthread_tryjoin_np)
507 # else
508 # define LSAN_MAYBE_INTERCEPT_TRYJOIN
509 # endif // SANITIZER_INTERCEPT_TRYJOIN
511 # if SANITIZER_INTERCEPT_TIMEDJOIN
512 INTERCEPTOR(int, pthread_timedjoin_np, void *thread, void **ret,
513 const struct timespec *abstime) {
514 int result;
515 GetThreadArgRetval().Join((uptr)thread, [&]() {
516 result = REAL(pthread_timedjoin_np)(thread, ret, abstime);
517 return !result;
519 return result;
521 # define LSAN_MAYBE_INTERCEPT_TIMEDJOIN \
522 INTERCEPT_FUNCTION(pthread_timedjoin_np)
523 # else
524 # define LSAN_MAYBE_INTERCEPT_TIMEDJOIN
525 # endif // SANITIZER_INTERCEPT_TIMEDJOIN
527 DEFINE_INTERNAL_PTHREAD_FUNCTIONS
529 INTERCEPTOR(void, _exit, int status) {
530 if (status == 0 && HasReportedLeaks()) status = common_flags()->exitcode;
531 REAL(_exit)(status);
534 #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
535 #define SIGNAL_INTERCEPTOR_ENTER() ENSURE_LSAN_INITED
536 #include "sanitizer_common/sanitizer_signal_interceptors.inc"
538 #endif // SANITIZER_POSIX
540 namespace __lsan {
542 void InitializeInterceptors() {
543 // Fuchsia doesn't use interceptors that require any setup.
544 #if !SANITIZER_FUCHSIA
545 __interception::DoesNotSupportStaticLinking();
546 InitializeSignalInterceptors();
548 INTERCEPT_FUNCTION(malloc);
549 INTERCEPT_FUNCTION(free);
550 LSAN_MAYBE_INTERCEPT_CFREE;
551 INTERCEPT_FUNCTION(calloc);
552 INTERCEPT_FUNCTION(realloc);
553 LSAN_MAYBE_INTERCEPT_MEMALIGN;
554 LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
555 LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC;
556 INTERCEPT_FUNCTION(posix_memalign);
557 INTERCEPT_FUNCTION(valloc);
558 LSAN_MAYBE_INTERCEPT_PVALLOC;
559 LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE;
560 LSAN_MAYBE_INTERCEPT_MALLINFO;
561 LSAN_MAYBE_INTERCEPT_MALLOPT;
562 INTERCEPT_FUNCTION(pthread_create);
563 INTERCEPT_FUNCTION(pthread_join);
564 INTERCEPT_FUNCTION(pthread_detach);
565 INTERCEPT_FUNCTION(pthread_exit);
566 LSAN_MAYBE_INTERCEPT_TIMEDJOIN;
567 LSAN_MAYBE_INTERCEPT_TRYJOIN;
568 INTERCEPT_FUNCTION(_exit);
570 LSAN_MAYBE_INTERCEPT__LWP_EXIT;
571 LSAN_MAYBE_INTERCEPT_THR_EXIT;
573 LSAN_MAYBE_INTERCEPT___CXA_ATEXIT;
574 LSAN_MAYBE_INTERCEPT_ATEXIT;
575 LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK;
577 LSAN_MAYBE_INTERCEPT_STRERROR;
579 #if !SANITIZER_NETBSD && !SANITIZER_FREEBSD
580 if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {
581 Report("LeakSanitizer: failed to create thread key.\n");
582 Die();
584 #endif
586 #endif // !SANITIZER_FUCHSIA
589 } // namespace __lsan