624 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of LeakSanitizer.10// Interceptors for standalone LSan.11//12//===----------------------------------------------------------------------===//13 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_POSIX27#include "sanitizer_common/sanitizer_posix.h"28#endif29#include "lsan.h"30#include "lsan_allocator.h"31#include "lsan_common.h"32#include "lsan_thread.h"33 34#include <stddef.h>35 36using namespace __lsan;37 38extern "C" {39int pthread_attr_init(void *attr);40int pthread_attr_destroy(void *attr);41int pthread_attr_getdetachstate(void *attr, int *v);42int pthread_key_create(unsigned *key, void (*destructor)(void* v));43int pthread_setspecific(unsigned key, const void *v);44}45 46struct 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_LEAKS50 // Suppress leaks from dlerror(). Previously dlsym hack on global array was51 // used by leak sanitizer as a root region.52 __lsan_register_root_region(ptr, size);53#endif54 }55 static void OnFree(const void *ptr, uptr size) {56#if CAN_SANITIZE_LEAKS57 __lsan_unregister_root_region(ptr, size);58#endif59 }60};61 62///// Malloc/free interceptors. /////63 64namespace std {65 struct nothrow_t;66 enum class align_val_t: size_t;67}68 69#if !SANITIZER_APPLE70INTERCEPTOR(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);76}77 78INTERCEPTOR(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);85}86 87# if SANITIZER_INTERCEPT_FREE_SIZED88INTERCEPTOR(void, free_sized, void *p, uptr size) {89 if (UNLIKELY(!p))90 return;91 if (DlsymAlloc::PointerIsMine(p))92 return DlsymAlloc::Free(p);93 ENSURE_LSAN_INITED;94 lsan_free_sized(p, size);95}96# define LSAN_MAYBE_INTERCEPT_FREE_SIZED INTERCEPT_FUNCTION(free_sized)97# else98# define LSAN_MAYBE_INTERCEPT_FREE_SIZED99# endif100 101# if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED102INTERCEPTOR(void, free_aligned_sized, void *p, uptr alignment, uptr size) {103 if (UNLIKELY(!p))104 return;105 if (DlsymAlloc::PointerIsMine(p))106 return DlsymAlloc::Free(p);107 ENSURE_LSAN_INITED;108 lsan_free_aligned_sized(p, alignment, size);109}110# define LSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED \111 INTERCEPT_FUNCTION(free_aligned_sized)112# else113# define LSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED114# endif115 116INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {117 if (DlsymAlloc::Use())118 return DlsymAlloc::Callocate(nmemb, size);119 ENSURE_LSAN_INITED;120 GET_STACK_TRACE_MALLOC;121 return lsan_calloc(nmemb, size, stack);122}123 124INTERCEPTOR(void *, realloc, void *ptr, uptr size) {125 if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))126 return DlsymAlloc::Realloc(ptr, size);127 ENSURE_LSAN_INITED;128 GET_STACK_TRACE_MALLOC;129 return lsan_realloc(ptr, size, stack);130}131 132INTERCEPTOR(void*, reallocarray, void *q, uptr nmemb, uptr size) {133 ENSURE_LSAN_INITED;134 GET_STACK_TRACE_MALLOC;135 return lsan_reallocarray(q, nmemb, size, stack);136}137 138INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {139 ENSURE_LSAN_INITED;140 GET_STACK_TRACE_MALLOC;141 return lsan_posix_memalign(memptr, alignment, size, stack);142}143 144INTERCEPTOR(void*, valloc, uptr size) {145 ENSURE_LSAN_INITED;146 GET_STACK_TRACE_MALLOC;147 return lsan_valloc(size, stack);148}149#else150# define LSAN_MAYBE_INTERCEPT_FREE_SIZED151# define LSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED152#endif // !SANITIZER_APPLE153 154#if SANITIZER_INTERCEPT_MEMALIGN155INTERCEPTOR(void*, memalign, uptr alignment, uptr size) {156 ENSURE_LSAN_INITED;157 GET_STACK_TRACE_MALLOC;158 return lsan_memalign(alignment, size, stack);159}160#define LSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)161#else162#define LSAN_MAYBE_INTERCEPT_MEMALIGN163#endif // SANITIZER_INTERCEPT_MEMALIGN164 165#if SANITIZER_INTERCEPT___LIBC_MEMALIGN166INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {167 ENSURE_LSAN_INITED;168 GET_STACK_TRACE_MALLOC;169 return lsan_memalign(alignment, size, stack);170}171#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)172#else173#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN174#endif // SANITIZER_INTERCEPT___LIBC_MEMALIGN175 176#if SANITIZER_INTERCEPT_ALIGNED_ALLOC177INTERCEPTOR(void*, aligned_alloc, uptr alignment, uptr size) {178 ENSURE_LSAN_INITED;179 GET_STACK_TRACE_MALLOC;180 return lsan_aligned_alloc(alignment, size, stack);181}182#define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)183#else184#define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC185#endif186 187#if SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE188INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {189 ENSURE_LSAN_INITED;190 return GetMallocUsableSize(ptr);191}192#define LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE \193 INTERCEPT_FUNCTION(malloc_usable_size)194#else195#define LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE196#endif197 198#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO199struct fake_mallinfo {200 int x[10];201};202 203INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {204 struct fake_mallinfo res;205 internal_memset(&res, 0, sizeof(res));206 return res;207}208#define LSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)209 210INTERCEPTOR(int, mallopt, int cmd, int value) {211 return 0;212}213#define LSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)214#else215#define LSAN_MAYBE_INTERCEPT_MALLINFO216#define LSAN_MAYBE_INTERCEPT_MALLOPT217#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO218 219#if SANITIZER_INTERCEPT_PVALLOC220INTERCEPTOR(void*, pvalloc, uptr size) {221 ENSURE_LSAN_INITED;222 GET_STACK_TRACE_MALLOC;223 return lsan_pvalloc(size, stack);224}225#define LSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)226#else227#define LSAN_MAYBE_INTERCEPT_PVALLOC228#endif // SANITIZER_INTERCEPT_PVALLOC229 230#if SANITIZER_INTERCEPT_CFREE231INTERCEPTOR(void, cfree, void *p) ALIAS(WRAP(free));232#define LSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)233#else234#define LSAN_MAYBE_INTERCEPT_CFREE235#endif // SANITIZER_INTERCEPT_CFREE236 237#if SANITIZER_INTERCEPT_MCHECK_MPROBE238INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {239 return 0;240}241 242INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {243 return 0;244}245 246INTERCEPTOR(int, mprobe, void *ptr) {247 return 0;248}249#endif // SANITIZER_INTERCEPT_MCHECK_MPROBE250 251 252// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.253#define OPERATOR_NEW_BODY(nothrow)\254 ENSURE_LSAN_INITED;\255 GET_STACK_TRACE_MALLOC;\256 void *res = lsan_malloc(size, stack);\257 if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\258 return res;259#define OPERATOR_NEW_BODY_ALIGN(nothrow)\260 ENSURE_LSAN_INITED;\261 GET_STACK_TRACE_MALLOC;\262 void *res = lsan_memalign((uptr)align, size, stack);\263 if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\264 return res;265 266#define OPERATOR_DELETE_BODY\267 ENSURE_LSAN_INITED;\268 lsan_free(ptr);269 270// On OS X it's not enough to just provide our own 'operator new' and271// 'operator delete' implementations, because they're going to be in the runtime272// dylib, and the main executable will depend on both the runtime dylib and273// libstdc++, each of has its implementation of new and delete.274// To make sure that C++ allocation/deallocation operators are overridden on275// OS X we need to intercept them using their mangled names.276#if !SANITIZER_APPLE277 278INTERCEPTOR_ATTRIBUTE279void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }280INTERCEPTOR_ATTRIBUTE281void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }282INTERCEPTOR_ATTRIBUTE283void *operator new(size_t size, std::nothrow_t const&)284{ OPERATOR_NEW_BODY(true /*nothrow*/); }285INTERCEPTOR_ATTRIBUTE286void *operator new[](size_t size, std::nothrow_t const&)287{ OPERATOR_NEW_BODY(true /*nothrow*/); }288INTERCEPTOR_ATTRIBUTE289void *operator new(size_t size, std::align_val_t align)290{ OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); }291INTERCEPTOR_ATTRIBUTE292void *operator new[](size_t size, std::align_val_t align)293{ OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); }294INTERCEPTOR_ATTRIBUTE295void *operator new(size_t size, std::align_val_t align, std::nothrow_t const&)296{ OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); }297INTERCEPTOR_ATTRIBUTE298void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&)299{ OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); }300 301INTERCEPTOR_ATTRIBUTE302void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }303INTERCEPTOR_ATTRIBUTE304void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }305INTERCEPTOR_ATTRIBUTE306void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }307INTERCEPTOR_ATTRIBUTE308void operator delete[](void *ptr, std::nothrow_t const &)309{ OPERATOR_DELETE_BODY; }310INTERCEPTOR_ATTRIBUTE311void operator delete(void *ptr, size_t size) NOEXCEPT312{ OPERATOR_DELETE_BODY; }313INTERCEPTOR_ATTRIBUTE314void operator delete[](void *ptr, size_t size) NOEXCEPT315{ OPERATOR_DELETE_BODY; }316INTERCEPTOR_ATTRIBUTE317void operator delete(void *ptr, std::align_val_t) NOEXCEPT318{ OPERATOR_DELETE_BODY; }319INTERCEPTOR_ATTRIBUTE320void operator delete[](void *ptr, std::align_val_t) NOEXCEPT321{ OPERATOR_DELETE_BODY; }322INTERCEPTOR_ATTRIBUTE323void operator delete(void *ptr, std::align_val_t, std::nothrow_t const&)324{ OPERATOR_DELETE_BODY; }325INTERCEPTOR_ATTRIBUTE326void operator delete[](void *ptr, std::align_val_t, std::nothrow_t const&)327{ OPERATOR_DELETE_BODY; }328INTERCEPTOR_ATTRIBUTE329void operator delete(void *ptr, size_t size, std::align_val_t) NOEXCEPT330{ OPERATOR_DELETE_BODY; }331INTERCEPTOR_ATTRIBUTE332void operator delete[](void *ptr, size_t size, std::align_val_t) NOEXCEPT333{ OPERATOR_DELETE_BODY; }334 335#else // SANITIZER_APPLE336 337INTERCEPTOR(void *, _Znwm, size_t size)338{ OPERATOR_NEW_BODY(false /*nothrow*/); }339INTERCEPTOR(void *, _Znam, size_t size)340{ OPERATOR_NEW_BODY(false /*nothrow*/); }341INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&)342{ OPERATOR_NEW_BODY(true /*nothrow*/); }343INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&)344{ OPERATOR_NEW_BODY(true /*nothrow*/); }345 346INTERCEPTOR(void, _ZdlPv, void *ptr)347{ OPERATOR_DELETE_BODY; }348INTERCEPTOR(void, _ZdaPv, void *ptr)349{ OPERATOR_DELETE_BODY; }350INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)351{ OPERATOR_DELETE_BODY; }352INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)353{ OPERATOR_DELETE_BODY; }354 355#endif // !SANITIZER_APPLE356 357 358///// Thread initialization and finalization. /////359 360#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD && !SANITIZER_FUCHSIA361static unsigned g_thread_finalize_key;362 363static void thread_finalize(void *v) {364 uptr iter = (uptr)v;365 if (iter > 1) {366 if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) {367 Report("LeakSanitizer: failed to set thread key.\n");368 Die();369 }370 return;371 }372 ThreadFinish();373}374#endif375 376#if SANITIZER_NETBSD377INTERCEPTOR(void, _lwp_exit) {378 ENSURE_LSAN_INITED;379 ThreadFinish();380 REAL(_lwp_exit)();381}382#define LSAN_MAYBE_INTERCEPT__LWP_EXIT INTERCEPT_FUNCTION(_lwp_exit)383#else384#define LSAN_MAYBE_INTERCEPT__LWP_EXIT385#endif386 387#if SANITIZER_INTERCEPT_THR_EXIT388INTERCEPTOR(void, thr_exit, ThreadID *state) {389 ENSURE_LSAN_INITED;390 ThreadFinish();391 REAL(thr_exit)(state);392}393# define LSAN_MAYBE_INTERCEPT_THR_EXIT INTERCEPT_FUNCTION(thr_exit)394#else395#define LSAN_MAYBE_INTERCEPT_THR_EXIT396#endif397 398#if SANITIZER_INTERCEPT___CXA_ATEXIT399INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,400 void *dso_handle) {401 __lsan::ScopedInterceptorDisabler disabler;402 return REAL(__cxa_atexit)(func, arg, dso_handle);403}404#define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT INTERCEPT_FUNCTION(__cxa_atexit)405#else406#define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT407#endif408 409#if SANITIZER_INTERCEPT_ATEXIT410INTERCEPTOR(int, atexit, void (*f)()) {411 __lsan::ScopedInterceptorDisabler disabler;412 return REAL(__cxa_atexit)((void (*)(void *a))f, 0, 0);413}414#define LSAN_MAYBE_INTERCEPT_ATEXIT INTERCEPT_FUNCTION(atexit)415#else416#define LSAN_MAYBE_INTERCEPT_ATEXIT417#endif418 419#if SANITIZER_INTERCEPT_PTHREAD_ATFORK420extern "C" {421extern int _pthread_atfork(void (*prepare)(), void (*parent)(),422 void (*child)());423}424 425INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(),426 void (*child)()) {427 __lsan::ScopedInterceptorDisabler disabler;428 // REAL(pthread_atfork) cannot be called due to symbol indirections at least429 // on NetBSD430 return _pthread_atfork(prepare, parent, child);431}432#define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK INTERCEPT_FUNCTION(pthread_atfork)433#else434#define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK435#endif436 437#if SANITIZER_INTERCEPT_STRERROR438INTERCEPTOR(char *, strerror, int errnum) {439 __lsan::ScopedInterceptorDisabler disabler;440 return REAL(strerror)(errnum);441}442#define LSAN_MAYBE_INTERCEPT_STRERROR INTERCEPT_FUNCTION(strerror)443#else444#define LSAN_MAYBE_INTERCEPT_STRERROR445#endif446 447#if SANITIZER_POSIX448 449template <bool Detached>450static void *ThreadStartFunc(void *arg) {451 u32 parent_tid = (uptr)arg;452 uptr tid = ThreadCreate(parent_tid, Detached);453 // Wait until the last iteration to maximize the chance that we are the last454 // destructor to run.455#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD456 if (pthread_setspecific(g_thread_finalize_key,457 (void*)GetPthreadDestructorIterations())) {458 Report("LeakSanitizer: failed to set thread key.\n");459 Die();460 }461# endif462 ThreadStart(tid, GetTid());463 auto self = GetThreadSelf();464 auto args = GetThreadArgRetval().GetArgs(self);465 void *retval = (*args.routine)(args.arg_retval);466 GetThreadArgRetval().Finish(self, retval);467 return retval;468}469 470INTERCEPTOR(int, pthread_create, void *th, void *attr,471 void *(*callback)(void *), void *param) {472 ENSURE_LSAN_INITED;473 EnsureMainThreadIDIsCorrect();474 475 bool detached = [attr]() {476 int d = 0;477 return attr && !pthread_attr_getdetachstate(attr, &d) && IsStateDetached(d);478 }();479 480 __sanitizer_pthread_attr_t myattr;481 if (!attr) {482 pthread_attr_init(&myattr);483 attr = &myattr;484 }485 AdjustStackSize(attr);486 uptr this_tid = GetCurrentThreadId();487 int result;488 {489 // Ignore all allocations made by pthread_create: thread stack/TLS may be490 // stored by pthread for future reuse even after thread destruction, and491 // the linked list it's stored in doesn't even hold valid pointers to the492 // objects, the latter are calculated by obscure pointer arithmetic.493 ScopedInterceptorDisabler disabler;494 GetThreadArgRetval().Create(detached, {callback, param}, [&]() -> uptr {495 result = REAL(pthread_create)(496 th, attr, detached ? ThreadStartFunc<true> : ThreadStartFunc<false>,497 (void *)this_tid);498 return result ? 0 : *(uptr *)(th);499 });500 }501 if (attr == &myattr)502 pthread_attr_destroy(&myattr);503 return result;504}505 506INTERCEPTOR(int, pthread_join, void *thread, void **retval) {507 int result;508 GetThreadArgRetval().Join((uptr)thread, [&]() {509 result = REAL(pthread_join)(thread, retval);510 return !result;511 });512 return result;513}514 515INTERCEPTOR(int, pthread_detach, void *thread) {516 int result;517 GetThreadArgRetval().Detach((uptr)thread, [&]() {518 result = REAL(pthread_detach)(thread);519 return !result;520 });521 return result;522}523 524INTERCEPTOR(void, pthread_exit, void *retval) {525 GetThreadArgRetval().Finish(GetThreadSelf(), retval);526 REAL(pthread_exit)(retval);527}528 529# if SANITIZER_INTERCEPT_TRYJOIN530INTERCEPTOR(int, pthread_tryjoin_np, void *thread, void **ret) {531 int result;532 GetThreadArgRetval().Join((uptr)thread, [&]() {533 result = REAL(pthread_tryjoin_np)(thread, ret);534 return !result;535 });536 return result;537}538# define LSAN_MAYBE_INTERCEPT_TRYJOIN INTERCEPT_FUNCTION(pthread_tryjoin_np)539# else540# define LSAN_MAYBE_INTERCEPT_TRYJOIN541# endif // SANITIZER_INTERCEPT_TRYJOIN542 543# if SANITIZER_INTERCEPT_TIMEDJOIN544INTERCEPTOR(int, pthread_timedjoin_np, void *thread, void **ret,545 const struct timespec *abstime) {546 int result;547 GetThreadArgRetval().Join((uptr)thread, [&]() {548 result = REAL(pthread_timedjoin_np)(thread, ret, abstime);549 return !result;550 });551 return result;552}553# define LSAN_MAYBE_INTERCEPT_TIMEDJOIN \554 INTERCEPT_FUNCTION(pthread_timedjoin_np)555# else556# define LSAN_MAYBE_INTERCEPT_TIMEDJOIN557# endif // SANITIZER_INTERCEPT_TIMEDJOIN558 559DEFINE_INTERNAL_PTHREAD_FUNCTIONS560 561INTERCEPTOR(void, _exit, int status) {562 if (status == 0 && HasReportedLeaks()) status = common_flags()->exitcode;563 REAL(_exit)(status);564}565 566#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)567#define SIGNAL_INTERCEPTOR_ENTER() ENSURE_LSAN_INITED568#include "sanitizer_common/sanitizer_signal_interceptors.inc"569 570#endif // SANITIZER_POSIX571 572namespace __lsan {573 574void InitializeInterceptors() {575 // Fuchsia doesn't use interceptors that require any setup.576#if !SANITIZER_FUCHSIA577 __interception::DoesNotSupportStaticLinking();578 InitializeSignalInterceptors();579 580 INTERCEPT_FUNCTION(malloc);581 INTERCEPT_FUNCTION(free);582 LSAN_MAYBE_INTERCEPT_FREE_SIZED;583 LSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED;584 LSAN_MAYBE_INTERCEPT_CFREE;585 INTERCEPT_FUNCTION(calloc);586 INTERCEPT_FUNCTION(realloc);587 LSAN_MAYBE_INTERCEPT_MEMALIGN;588 LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;589 LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC;590 INTERCEPT_FUNCTION(posix_memalign);591 INTERCEPT_FUNCTION(valloc);592 LSAN_MAYBE_INTERCEPT_PVALLOC;593 LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE;594 LSAN_MAYBE_INTERCEPT_MALLINFO;595 LSAN_MAYBE_INTERCEPT_MALLOPT;596 INTERCEPT_FUNCTION(pthread_create);597 INTERCEPT_FUNCTION(pthread_join);598 INTERCEPT_FUNCTION(pthread_detach);599 INTERCEPT_FUNCTION(pthread_exit);600 LSAN_MAYBE_INTERCEPT_TIMEDJOIN;601 LSAN_MAYBE_INTERCEPT_TRYJOIN;602 INTERCEPT_FUNCTION(_exit);603 604 LSAN_MAYBE_INTERCEPT__LWP_EXIT;605 LSAN_MAYBE_INTERCEPT_THR_EXIT;606 607 LSAN_MAYBE_INTERCEPT___CXA_ATEXIT;608 LSAN_MAYBE_INTERCEPT_ATEXIT;609 LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK;610 611 LSAN_MAYBE_INTERCEPT_STRERROR;612 613#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD614 if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {615 Report("LeakSanitizer: failed to create thread key.\n");616 Die();617 }618#endif619 620#endif // !SANITIZER_FUCHSIA621}622 623} // namespace __lsan624