brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.7 KiB · 5340c6f Raw
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