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. 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_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" 33 34 #include <stddef.h> 35 36 using namespace __lsan; 37 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); 44 } 45 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 54 } 55 static void OnFree(const void *ptr, uptr size) { 56 #if CAN_SANITIZE_LEAKS 57 __lsan_unregister_root_region(ptr, size); 58 #endif 59 } 60 }; 61 62 ///// Malloc/free interceptors. ///// 63 64 namespace std { 65 struct nothrow_t; 66 enum class align_val_t: size_t; 67 } 68 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); 76 } 77 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); 85 } 86 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); 93 } 94 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); 101 } 102 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); 107 } 108 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); 113 } 114 115 INTERCEPTOR(void*, valloc, uptr size) { 116 ENSURE_LSAN_INITED; 117 GET_STACK_TRACE_MALLOC; 118 return lsan_valloc(size, stack); 119 } 120 #endif // !SANITIZER_APPLE 121 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); 127 } 128 #define LSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign) 129 #else 130 #define LSAN_MAYBE_INTERCEPT_MEMALIGN 131 #endif // SANITIZER_INTERCEPT_MEMALIGN 132 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); 138 } 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 143 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); 149 } 150 #define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc) 151 #else 152 #define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC 153 #endif 154 155 #if SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE 156 INTERCEPTOR(uptr, malloc_usable_size, void *ptr) { 157 ENSURE_LSAN_INITED; 158 return GetMallocUsableSize(ptr); 159 } 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 165 166 #if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO 167 struct fake_mallinfo { 168 int x[10]; 169 }; 170 171 INTERCEPTOR(struct fake_mallinfo, mallinfo, void) { 172 struct fake_mallinfo res; 173 internal_memset(&res, 0, sizeof(res)); 174 return res; 175 } 176 #define LSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo) 177 178 INTERCEPTOR(int, mallopt, int cmd, int value) { 179 return 0; 180 } 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 186 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); 192 } 193 #define LSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc) 194 #else 195 #define LSAN_MAYBE_INTERCEPT_PVALLOC 196 #endif // SANITIZER_INTERCEPT_PVALLOC 197 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 204 205 #if SANITIZER_INTERCEPT_MCHECK_MPROBE 206 INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) { 207 return 0; 208 } 209 210 INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) { 211 return 0; 212 } 213 214 INTERCEPTOR(int, mprobe, void *ptr) { 215 return 0; 216 } 217 #endif // SANITIZER_INTERCEPT_MCHECK_MPROBE 218 219 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; 233 234 #define OPERATOR_DELETE_BODY\ 235 ENSURE_LSAN_INITED;\ 236 lsan_free(ptr); 237 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 245 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*/); } 268 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; } 302 303 #else // SANITIZER_APPLE 304 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*/); } 313 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; } 322 323 #endif // !SANITIZER_APPLE 324 325 326 ///// Thread initialization and finalization. ///// 327 328 #if !SANITIZER_NETBSD && !SANITIZER_FREEBSD && !SANITIZER_FUCHSIA 329 static unsigned g_thread_finalize_key; 330 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(); 337 } 338 return; 339 } 340 ThreadFinish(); 341 } 342 #endif 343 344 #if SANITIZER_NETBSD 345 INTERCEPTOR(void, _lwp_exit) { 346 ENSURE_LSAN_INITED; 347 ThreadFinish(); 348 REAL(_lwp_exit)(); 349 } 350 #define LSAN_MAYBE_INTERCEPT__LWP_EXIT INTERCEPT_FUNCTION(_lwp_exit) 351 #else 352 #define LSAN_MAYBE_INTERCEPT__LWP_EXIT 353 #endif 354 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); 360 } 361 #define LSAN_MAYBE_INTERCEPT_THR_EXIT INTERCEPT_FUNCTION(thr_exit) 362 #else 363 #define LSAN_MAYBE_INTERCEPT_THR_EXIT 364 #endif 365 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); 371 } 372 #define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT INTERCEPT_FUNCTION(__cxa_atexit) 373 #else 374 #define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT 375 #endif 376 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); 381 } 382 #define LSAN_MAYBE_INTERCEPT_ATEXIT INTERCEPT_FUNCTION(atexit) 383 #else 384 #define LSAN_MAYBE_INTERCEPT_ATEXIT 385 #endif 386 387 #if SANITIZER_INTERCEPT_PTHREAD_ATFORK 388 extern "C" { 389 extern int _pthread_atfork(void (*prepare)(), void (*parent)(), 390 void (*child)()); 391 } 392 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); 399 } 400 #define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK INTERCEPT_FUNCTION(pthread_atfork) 401 #else 402 #define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK 403 #endif 404 405 #if SANITIZER_INTERCEPT_STRERROR 406 INTERCEPTOR(char *, strerror, int errnum) { 407 __lsan::ScopedInterceptorDisabler disabler; 408 return REAL(strerror)(errnum); 409 } 410 #define LSAN_MAYBE_INTERCEPT_STRERROR INTERCEPT_FUNCTION(strerror) 411 #else 412 #define LSAN_MAYBE_INTERCEPT_STRERROR 413 #endif 414 415 #if SANITIZER_POSIX 416 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(); 428 } 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; 436 } 437 438 INTERCEPTOR(int, pthread_create, void *th, void *attr, 439 void *(*callback)(void *), void *param) { 440 ENSURE_LSAN_INITED; 441 EnsureMainThreadIDIsCorrect(); 442 443 bool detached = [attr]() { 444 int d = 0; 445 return attr && !pthread_attr_getdetachstate(attr, &d) && IsStateDetached(d); 446 }(); 447 448 __sanitizer_pthread_attr_t myattr; 449 if (!attr) { 450 pthread_attr_init(&myattr); 451 attr = &myattr; 452 } 453 AdjustStackSize(attr); 454 uptr this_tid = GetCurrentThreadId(); 455 int result; 456 { 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); 467 }); 468 } 469 if (attr == &myattr) 470 pthread_attr_destroy(&myattr); 471 return result; 472 } 473 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; 479 }); 480 return result; 481 } 482 483 INTERCEPTOR(int, pthread_detach, void *thread) { 484 int result; 485 GetThreadArgRetval().Detach((uptr)thread, [&]() { 486 result = REAL(pthread_detach)(thread); 487 return !result; 488 }); 489 return result; 490 } 491 492 INTERCEPTOR(void, pthread_exit, void *retval) { 493 GetThreadArgRetval().Finish(GetThreadSelf(), retval); 494 REAL(pthread_exit)(retval); 495 } 496 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; 503 }); 504 return result; 505 } 506 # define LSAN_MAYBE_INTERCEPT_TRYJOIN INTERCEPT_FUNCTION(pthread_tryjoin_np) 507 # else 508 # define LSAN_MAYBE_INTERCEPT_TRYJOIN 509 # endif // SANITIZER_INTERCEPT_TRYJOIN 510 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; 518 }); 519 return result; 520 } 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 526 527 DEFINE_INTERNAL_PTHREAD_FUNCTIONS 528 529 INTERCEPTOR(void, _exit, int status) { 530 if (status == 0 && HasReportedLeaks()) status = common_flags()->exitcode; 531 REAL(_exit)(status); 532 } 533 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" 537 538 #endif // SANITIZER_POSIX 539 540 namespace __lsan { 541 542 void InitializeInterceptors() { 543 // Fuchsia doesn't use interceptors that require any setup. 544 #if !SANITIZER_FUCHSIA 545 __interception::DoesNotSupportStaticLinking(); 546 InitializeSignalInterceptors(); 547 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); 569 570 LSAN_MAYBE_INTERCEPT__LWP_EXIT; 571 LSAN_MAYBE_INTERCEPT_THR_EXIT; 572 573 LSAN_MAYBE_INTERCEPT___CXA_ATEXIT; 574 LSAN_MAYBE_INTERCEPT_ATEXIT; 575 LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK; 576 577 LSAN_MAYBE_INTERCEPT_STRERROR; 578 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(); 583 } 584 #endif 585 586 #endif // !SANITIZER_FUCHSIA 587 } 588 589 } // namespace __lsan 590