1 //=-- lsan_common.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 // Implementation of common leak checking functionality. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "lsan_common.h" 15 16 #include "sanitizer_common/sanitizer_common.h" 17 #include "sanitizer_common/sanitizer_flag_parser.h" 18 #include "sanitizer_common/sanitizer_flags.h" 19 #include "sanitizer_common/sanitizer_placement_new.h" 20 #include "sanitizer_common/sanitizer_procmaps.h" 21 #include "sanitizer_common/sanitizer_report_decorator.h" 22 #include "sanitizer_common/sanitizer_stackdepot.h" 23 #include "sanitizer_common/sanitizer_stacktrace.h" 24 #include "sanitizer_common/sanitizer_suppressions.h" 25 #include "sanitizer_common/sanitizer_thread_registry.h" 26 #include "sanitizer_common/sanitizer_tls_get_addr.h" 27 28 #if CAN_SANITIZE_LEAKS 29 namespace __lsan { 30 31 // This mutex is used to prevent races between DoLeakCheck and IgnoreObject, and 32 // also to protect the global list of root regions. 33 Mutex global_mutex; 34 35 Flags lsan_flags; 36 37 void DisableCounterUnderflow() { 38 if (common_flags()->detect_leaks) { 39 Report("Unmatched call to __lsan_enable().\n"); 40 Die(); 41 } 42 } 43 44 void Flags::SetDefaults() { 45 # define LSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 46 # include "lsan_flags.inc" 47 # undef LSAN_FLAG 48 } 49 50 void RegisterLsanFlags(FlagParser *parser, Flags *f) { 51 # define LSAN_FLAG(Type, Name, DefaultValue, Description) \ 52 RegisterFlag(parser, #Name, Description, &f->Name); 53 # include "lsan_flags.inc" 54 # undef LSAN_FLAG 55 } 56 57 # define LOG_POINTERS(...) \ 58 do { \ 59 if (flags()->log_pointers) \ 60 Report(__VA_ARGS__); \ 61 } while (0) 62 63 # define LOG_THREADS(...) \ 64 do { \ 65 if (flags()->log_threads) \ 66 Report(__VA_ARGS__); \ 67 } while (0) 68 69 class LeakSuppressionContext { 70 bool parsed = false; 71 SuppressionContext context; 72 bool suppressed_stacks_sorted = true; 73 InternalMmapVector<u32> suppressed_stacks; 74 75 Suppression *GetSuppressionForAddr(uptr addr); 76 void LazyInit(); 77 bool SuppressByRule(const StackTrace &stack, uptr hit_count, uptr total_size); 78 79 public: 80 LeakSuppressionContext(const char *supprression_types[], 81 int suppression_types_num) 82 : context(supprression_types, suppression_types_num) {} 83 84 bool Suppress(u32 stack_trace_id, uptr hit_count, uptr total_size); 85 86 const InternalMmapVector<u32> &GetSortedSuppressedStacks() { 87 if (!suppressed_stacks_sorted) { 88 suppressed_stacks_sorted = true; 89 SortAndDedup(suppressed_stacks); 90 } 91 return suppressed_stacks; 92 } 93 void PrintMatchedSuppressions(); 94 }; 95 96 ALIGNED(64) static char suppression_placeholder[sizeof(LeakSuppressionContext)]; 97 static LeakSuppressionContext *suppression_ctx = nullptr; 98 static const char kSuppressionLeak[] = "leak"; 99 static const char *kSuppressionTypes[] = {kSuppressionLeak}; 100 static const char kStdSuppressions[] = 101 # if SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 102 // For more details refer to the SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 103 // definition. 104 "leak:*pthread_exit*\n" 105 # endif // SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 106 # if SANITIZER_MAC 107 // For Darwin and os_log/os_trace: https://reviews.llvm.org/D35173 108 "leak:*_os_trace*\n" 109 # endif 110 // TLS leak in some glibc versions, described in 111 // https://sourceware.org/bugzilla/show_bug.cgi?id=12650. 112 "leak:*tls_get_addr*\n"; 113 114 void InitializeSuppressions() { 115 CHECK_EQ(nullptr, suppression_ctx); 116 suppression_ctx = new (suppression_placeholder) 117 LeakSuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); 118 } 119 120 void LeakSuppressionContext::LazyInit() { 121 if (!parsed) { 122 parsed = true; 123 context.ParseFromFile(flags()->suppressions); 124 if (&__lsan_default_suppressions) 125 context.Parse(__lsan_default_suppressions()); 126 context.Parse(kStdSuppressions); 127 } 128 } 129 130 Suppression *LeakSuppressionContext::GetSuppressionForAddr(uptr addr) { 131 Suppression *s = nullptr; 132 133 // Suppress by module name. 134 if (const char *module_name = 135 Symbolizer::GetOrInit()->GetModuleNameForPc(addr)) 136 if (context.Match(module_name, kSuppressionLeak, &s)) 137 return s; 138 139 // Suppress by file or function name. 140 SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(addr); 141 for (SymbolizedStack *cur = frames; cur; cur = cur->next) { 142 if (context.Match(cur->info.function, kSuppressionLeak, &s) || 143 context.Match(cur->info.file, kSuppressionLeak, &s)) { 144 break; 145 } 146 } 147 frames->ClearAll(); 148 return s; 149 } 150 151 bool LeakSuppressionContext::SuppressByRule(const StackTrace &stack, 152 uptr hit_count, uptr total_size) { 153 for (uptr i = 0; i < stack.size; i++) { 154 Suppression *s = GetSuppressionForAddr( 155 StackTrace::GetPreviousInstructionPc(stack.trace[i])); 156 if (s) { 157 s->weight += total_size; 158 atomic_fetch_add(&s->hit_count, hit_count, memory_order_relaxed); 159 return true; 160 } 161 } 162 return false; 163 } 164 165 bool LeakSuppressionContext::Suppress(u32 stack_trace_id, uptr hit_count, 166 uptr total_size) { 167 LazyInit(); 168 StackTrace stack = StackDepotGet(stack_trace_id); 169 if (!SuppressByRule(stack, hit_count, total_size)) 170 return false; 171 suppressed_stacks_sorted = false; 172 suppressed_stacks.push_back(stack_trace_id); 173 return true; 174 } 175 176 static LeakSuppressionContext *GetSuppressionContext() { 177 CHECK(suppression_ctx); 178 return suppression_ctx; 179 } 180 181 static InternalMmapVectorNoCtor<RootRegion> root_regions; 182 183 InternalMmapVectorNoCtor<RootRegion> const *GetRootRegions() { 184 return &root_regions; 185 } 186 187 void InitCommonLsan() { 188 if (common_flags()->detect_leaks) { 189 // Initialization which can fail or print warnings should only be done if 190 // LSan is actually enabled. 191 InitializeSuppressions(); 192 InitializePlatformSpecificModules(); 193 } 194 } 195 196 class Decorator : public __sanitizer::SanitizerCommonDecorator { 197 public: 198 Decorator() : SanitizerCommonDecorator() {} 199 const char *Error() { return Red(); } 200 const char *Leak() { return Blue(); } 201 }; 202 203 static inline bool CanBeAHeapPointer(uptr p) { 204 // Since our heap is located in mmap-ed memory, we can assume a sensible lower 205 // bound on heap addresses. 206 const uptr kMinAddress = 4 * 4096; 207 if (p < kMinAddress) 208 return false; 209 # if defined(__x86_64__) 210 // Accept only canonical form user-space addresses. 211 return ((p >> 47) == 0); 212 # elif defined(__mips64) 213 return ((p >> 40) == 0); 214 # elif defined(__aarch64__) 215 unsigned runtimeVMA = (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1); 216 return ((p >> runtimeVMA) == 0); 217 # else 218 return true; 219 # endif 220 } 221 222 // Scans the memory range, looking for byte patterns that point into allocator 223 // chunks. Marks those chunks with |tag| and adds them to |frontier|. 224 // There are two usage modes for this function: finding reachable chunks 225 // (|tag| = kReachable) and finding indirectly leaked chunks 226 // (|tag| = kIndirectlyLeaked). In the second case, there's no flood fill, 227 // so |frontier| = 0. 228 void ScanRangeForPointers(uptr begin, uptr end, Frontier *frontier, 229 const char *region_type, ChunkTag tag) { 230 CHECK(tag == kReachable || tag == kIndirectlyLeaked); 231 const uptr alignment = flags()->pointer_alignment(); 232 LOG_POINTERS("Scanning %s range %p-%p.\n", region_type, (void *)begin, 233 (void *)end); 234 uptr pp = begin; 235 if (pp % alignment) 236 pp = pp + alignment - pp % alignment; 237 for (; pp + sizeof(void *) <= end; pp += alignment) { 238 void *p = *reinterpret_cast<void **>(pp); 239 if (!CanBeAHeapPointer(reinterpret_cast<uptr>(p))) 240 continue; 241 uptr chunk = PointsIntoChunk(p); 242 if (!chunk) 243 continue; 244 // Pointers to self don't count. This matters when tag == kIndirectlyLeaked. 245 if (chunk == begin) 246 continue; 247 LsanMetadata m(chunk); 248 if (m.tag() == kReachable || m.tag() == kIgnored) 249 continue; 250 251 // Do this check relatively late so we can log only the interesting cases. 252 if (!flags()->use_poisoned && WordIsPoisoned(pp)) { 253 LOG_POINTERS( 254 "%p is poisoned: ignoring %p pointing into chunk %p-%p of size " 255 "%zu.\n", 256 (void *)pp, p, (void *)chunk, (void *)(chunk + m.requested_size()), 257 m.requested_size()); 258 continue; 259 } 260 261 m.set_tag(tag); 262 LOG_POINTERS("%p: found %p pointing into chunk %p-%p of size %zu.\n", 263 (void *)pp, p, (void *)chunk, 264 (void *)(chunk + m.requested_size()), m.requested_size()); 265 if (frontier) 266 frontier->push_back(chunk); 267 } 268 } 269 270 // Scans a global range for pointers 271 void ScanGlobalRange(uptr begin, uptr end, Frontier *frontier) { 272 uptr allocator_begin = 0, allocator_end = 0; 273 GetAllocatorGlobalRange(&allocator_begin, &allocator_end); 274 if (begin <= allocator_begin && allocator_begin < end) { 275 CHECK_LE(allocator_begin, allocator_end); 276 CHECK_LE(allocator_end, end); 277 if (begin < allocator_begin) 278 ScanRangeForPointers(begin, allocator_begin, frontier, "GLOBAL", 279 kReachable); 280 if (allocator_end < end) 281 ScanRangeForPointers(allocator_end, end, frontier, "GLOBAL", kReachable); 282 } else { 283 ScanRangeForPointers(begin, end, frontier, "GLOBAL", kReachable); 284 } 285 } 286 287 void ForEachExtraStackRangeCb(uptr begin, uptr end, void *arg) { 288 Frontier *frontier = reinterpret_cast<Frontier *>(arg); 289 ScanRangeForPointers(begin, end, frontier, "FAKE STACK", kReachable); 290 } 291 292 # if SANITIZER_FUCHSIA 293 294 // Fuchsia handles all threads together with its own callback. 295 static void ProcessThreads(SuspendedThreadsList const &, Frontier *) {} 296 297 # else 298 299 # if SANITIZER_ANDROID 300 // FIXME: Move this out into *libcdep.cpp 301 extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_iterate_dynamic_tls( 302 pid_t, void (*cb)(void *, void *, uptr, void *), void *); 303 # endif 304 305 static void ProcessThreadRegistry(Frontier *frontier) { 306 InternalMmapVector<uptr> ptrs; 307 GetThreadRegistryLocked()->RunCallbackForEachThreadLocked( 308 GetAdditionalThreadContextPtrs, &ptrs); 309 310 for (uptr i = 0; i < ptrs.size(); ++i) { 311 void *ptr = reinterpret_cast<void *>(ptrs[i]); 312 uptr chunk = PointsIntoChunk(ptr); 313 if (!chunk) 314 continue; 315 LsanMetadata m(chunk); 316 if (!m.allocated()) 317 continue; 318 319 // Mark as reachable and add to frontier. 320 LOG_POINTERS("Treating pointer %p from ThreadContext as reachable\n", ptr); 321 m.set_tag(kReachable); 322 frontier->push_back(chunk); 323 } 324 } 325 326 // Scans thread data (stacks and TLS) for heap pointers. 327 static void ProcessThreads(SuspendedThreadsList const &suspended_threads, 328 Frontier *frontier) { 329 InternalMmapVector<uptr> registers; 330 for (uptr i = 0; i < suspended_threads.ThreadCount(); i++) { 331 tid_t os_id = static_cast<tid_t>(suspended_threads.GetThreadID(i)); 332 LOG_THREADS("Processing thread %llu.\n", os_id); 333 uptr stack_begin, stack_end, tls_begin, tls_end, cache_begin, cache_end; 334 DTLS *dtls; 335 bool thread_found = 336 GetThreadRangesLocked(os_id, &stack_begin, &stack_end, &tls_begin, 337 &tls_end, &cache_begin, &cache_end, &dtls); 338 if (!thread_found) { 339 // If a thread can't be found in the thread registry, it's probably in the 340 // process of destruction. Log this event and move on. 341 LOG_THREADS("Thread %llu not found in registry.\n", os_id); 342 continue; 343 } 344 uptr sp; 345 PtraceRegistersStatus have_registers = 346 suspended_threads.GetRegistersAndSP(i, ®isters, &sp); 347 if (have_registers != REGISTERS_AVAILABLE) { 348 Report("Unable to get registers from thread %llu.\n", os_id); 349 // If unable to get SP, consider the entire stack to be reachable unless 350 // GetRegistersAndSP failed with ESRCH. 351 if (have_registers == REGISTERS_UNAVAILABLE_FATAL) 352 continue; 353 sp = stack_begin; 354 } 355 356 if (flags()->use_registers && have_registers) { 357 uptr registers_begin = reinterpret_cast<uptr>(registers.data()); 358 uptr registers_end = 359 reinterpret_cast<uptr>(registers.data() + registers.size()); 360 ScanRangeForPointers(registers_begin, registers_end, frontier, 361 "REGISTERS", kReachable); 362 } 363 364 if (flags()->use_stacks) { 365 LOG_THREADS("Stack at %p-%p (SP = %p).\n", (void *)stack_begin, 366 (void *)stack_end, (void *)sp); 367 if (sp < stack_begin || sp >= stack_end) { 368 // SP is outside the recorded stack range (e.g. the thread is running a 369 // signal handler on alternate stack, or swapcontext was used). 370 // Again, consider the entire stack range to be reachable. 371 LOG_THREADS("WARNING: stack pointer not in stack range.\n"); 372 uptr page_size = GetPageSizeCached(); 373 int skipped = 0; 374 while (stack_begin < stack_end && 375 !IsAccessibleMemoryRange(stack_begin, 1)) { 376 skipped++; 377 stack_begin += page_size; 378 } 379 LOG_THREADS("Skipped %d guard page(s) to obtain stack %p-%p.\n", 380 skipped, (void *)stack_begin, (void *)stack_end); 381 } else { 382 // Shrink the stack range to ignore out-of-scope values. 383 stack_begin = sp; 384 } 385 ScanRangeForPointers(stack_begin, stack_end, frontier, "STACK", 386 kReachable); 387 ForEachExtraStackRange(os_id, ForEachExtraStackRangeCb, frontier); 388 } 389 390 if (flags()->use_tls) { 391 if (tls_begin) { 392 LOG_THREADS("TLS at %p-%p.\n", (void *)tls_begin, (void *)tls_end); 393 // If the tls and cache ranges don't overlap, scan full tls range, 394 // otherwise, only scan the non-overlapping portions 395 if (cache_begin == cache_end || tls_end < cache_begin || 396 tls_begin > cache_end) { 397 ScanRangeForPointers(tls_begin, tls_end, frontier, "TLS", kReachable); 398 } else { 399 if (tls_begin < cache_begin) 400 ScanRangeForPointers(tls_begin, cache_begin, frontier, "TLS", 401 kReachable); 402 if (tls_end > cache_end) 403 ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", 404 kReachable); 405 } 406 } 407 # if SANITIZER_ANDROID 408 auto *cb = +[](void *dtls_begin, void *dtls_end, uptr /*dso_idd*/, 409 void *arg) -> void { 410 ScanRangeForPointers(reinterpret_cast<uptr>(dtls_begin), 411 reinterpret_cast<uptr>(dtls_end), 412 reinterpret_cast<Frontier *>(arg), "DTLS", 413 kReachable); 414 }; 415 416 // FIXME: There might be a race-condition here (and in Bionic) if the 417 // thread is suspended in the middle of updating its DTLS. IOWs, we 418 // could scan already freed memory. (probably fine for now) 419 __libc_iterate_dynamic_tls(os_id, cb, frontier); 420 # else 421 if (dtls && !DTLSInDestruction(dtls)) { 422 ForEachDVT(dtls, [&](const DTLS::DTV &dtv, int id) { 423 uptr dtls_beg = dtv.beg; 424 uptr dtls_end = dtls_beg + dtv.size; 425 if (dtls_beg < dtls_end) { 426 LOG_THREADS("DTLS %d at %p-%p.\n", id, (void *)dtls_beg, 427 (void *)dtls_end); 428 ScanRangeForPointers(dtls_beg, dtls_end, frontier, "DTLS", 429 kReachable); 430 } 431 }); 432 } else { 433 // We are handling a thread with DTLS under destruction. Log about 434 // this and continue. 435 LOG_THREADS("Thread %llu has DTLS under destruction.\n", os_id); 436 } 437 # endif 438 } 439 } 440 441 // Add pointers reachable from ThreadContexts 442 ProcessThreadRegistry(frontier); 443 } 444 445 # endif // SANITIZER_FUCHSIA 446 447 void ScanRootRegion(Frontier *frontier, const RootRegion &root_region, 448 uptr region_begin, uptr region_end, bool is_readable) { 449 uptr intersection_begin = Max(root_region.begin, region_begin); 450 uptr intersection_end = Min(region_end, root_region.begin + root_region.size); 451 if (intersection_begin >= intersection_end) 452 return; 453 LOG_POINTERS("Root region %p-%p intersects with mapped region %p-%p (%s)\n", 454 (void *)root_region.begin, 455 (void *)(root_region.begin + root_region.size), 456 (void *)region_begin, (void *)region_end, 457 is_readable ? "readable" : "unreadable"); 458 if (is_readable) 459 ScanRangeForPointers(intersection_begin, intersection_end, frontier, "ROOT", 460 kReachable); 461 } 462 463 static void ProcessRootRegion(Frontier *frontier, 464 const RootRegion &root_region) { 465 MemoryMappingLayout proc_maps(/*cache_enabled*/ true); 466 MemoryMappedSegment segment; 467 while (proc_maps.Next(&segment)) { 468 ScanRootRegion(frontier, root_region, segment.start, segment.end, 469 segment.IsReadable()); 470 } 471 } 472 473 // Scans root regions for heap pointers. 474 static void ProcessRootRegions(Frontier *frontier) { 475 if (!flags()->use_root_regions) 476 return; 477 for (uptr i = 0; i < root_regions.size(); i++) 478 ProcessRootRegion(frontier, root_regions[i]); 479 } 480 481 static void FloodFillTag(Frontier *frontier, ChunkTag tag) { 482 while (frontier->size()) { 483 uptr next_chunk = frontier->back(); 484 frontier->pop_back(); 485 LsanMetadata m(next_chunk); 486 ScanRangeForPointers(next_chunk, next_chunk + m.requested_size(), frontier, 487 "HEAP", tag); 488 } 489 } 490 491 // ForEachChunk callback. If the chunk is marked as leaked, marks all chunks 492 // which are reachable from it as indirectly leaked. 493 static void MarkIndirectlyLeakedCb(uptr chunk, void *arg) { 494 chunk = GetUserBegin(chunk); 495 LsanMetadata m(chunk); 496 if (m.allocated() && m.tag() != kReachable) { 497 ScanRangeForPointers(chunk, chunk + m.requested_size(), 498 /* frontier */ nullptr, "HEAP", kIndirectlyLeaked); 499 } 500 } 501 502 static void IgnoredSuppressedCb(uptr chunk, void *arg) { 503 CHECK(arg); 504 chunk = GetUserBegin(chunk); 505 LsanMetadata m(chunk); 506 if (!m.allocated() || m.tag() == kIgnored) 507 return; 508 509 const InternalMmapVector<u32> &suppressed = 510 *static_cast<const InternalMmapVector<u32> *>(arg); 511 uptr idx = InternalLowerBound(suppressed, m.stack_trace_id()); 512 if (idx >= suppressed.size() || m.stack_trace_id() != suppressed[idx]) 513 return; 514 515 LOG_POINTERS("Suppressed: chunk %p-%p of size %zu.\n", (void *)chunk, 516 (void *)(chunk + m.requested_size()), m.requested_size()); 517 m.set_tag(kIgnored); 518 } 519 520 // ForEachChunk callback. If chunk is marked as ignored, adds its address to 521 // frontier. 522 static void CollectIgnoredCb(uptr chunk, void *arg) { 523 CHECK(arg); 524 chunk = GetUserBegin(chunk); 525 LsanMetadata m(chunk); 526 if (m.allocated() && m.tag() == kIgnored) { 527 LOG_POINTERS("Ignored: chunk %p-%p of size %zu.\n", (void *)chunk, 528 (void *)(chunk + m.requested_size()), m.requested_size()); 529 reinterpret_cast<Frontier *>(arg)->push_back(chunk); 530 } 531 } 532 533 static uptr GetCallerPC(const StackTrace &stack) { 534 // The top frame is our malloc/calloc/etc. The next frame is the caller. 535 if (stack.size >= 2) 536 return stack.trace[1]; 537 return 0; 538 } 539 540 struct InvalidPCParam { 541 Frontier *frontier; 542 bool skip_linker_allocations; 543 }; 544 545 // ForEachChunk callback. If the caller pc is invalid or is within the linker, 546 // mark as reachable. Called by ProcessPlatformSpecificAllocations. 547 static void MarkInvalidPCCb(uptr chunk, void *arg) { 548 CHECK(arg); 549 InvalidPCParam *param = reinterpret_cast<InvalidPCParam *>(arg); 550 chunk = GetUserBegin(chunk); 551 LsanMetadata m(chunk); 552 if (m.allocated() && m.tag() != kReachable && m.tag() != kIgnored) { 553 u32 stack_id = m.stack_trace_id(); 554 uptr caller_pc = 0; 555 if (stack_id > 0) 556 caller_pc = GetCallerPC(StackDepotGet(stack_id)); 557 // If caller_pc is unknown, this chunk may be allocated in a coroutine. Mark 558 // it as reachable, as we can't properly report its allocation stack anyway. 559 if (caller_pc == 0 || (param->skip_linker_allocations && 560 GetLinker()->containsAddress(caller_pc))) { 561 m.set_tag(kIgnored); 562 param->frontier->push_back(chunk); 563 } 564 } 565 } 566 567 // On Linux, treats all chunks allocated from ld-linux.so as reachable, which 568 // covers dynamically allocated TLS blocks, internal dynamic loader's loaded 569 // modules accounting etc. 570 // Dynamic TLS blocks contain the TLS variables of dynamically loaded modules. 571 // They are allocated with a __libc_memalign() call in allocate_and_init() 572 // (elf/dl-tls.c). Glibc won't tell us the address ranges occupied by those 573 // blocks, but we can make sure they come from our own allocator by intercepting 574 // __libc_memalign(). On top of that, there is no easy way to reach them. Their 575 // addresses are stored in a dynamically allocated array (the DTV) which is 576 // referenced from the static TLS. Unfortunately, we can't just rely on the DTV 577 // being reachable from the static TLS, and the dynamic TLS being reachable from 578 // the DTV. This is because the initial DTV is allocated before our interception 579 // mechanism kicks in, and thus we don't recognize it as allocated memory. We 580 // can't special-case it either, since we don't know its size. 581 // Our solution is to include in the root set all allocations made from 582 // ld-linux.so (which is where allocate_and_init() is implemented). This is 583 // guaranteed to include all dynamic TLS blocks (and possibly other allocations 584 // which we don't care about). 585 // On all other platforms, this simply checks to ensure that the caller pc is 586 // valid before reporting chunks as leaked. 587 static void ProcessPC(Frontier *frontier) { 588 InvalidPCParam arg; 589 arg.frontier = frontier; 590 arg.skip_linker_allocations = 591 flags()->use_tls && flags()->use_ld_allocations && GetLinker() != nullptr; 592 ForEachChunk(MarkInvalidPCCb, &arg); 593 } 594 595 // Sets the appropriate tag on each chunk. 596 static void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads, 597 Frontier *frontier) { 598 const InternalMmapVector<u32> &suppressed_stacks = 599 GetSuppressionContext()->GetSortedSuppressedStacks(); 600 if (!suppressed_stacks.empty()) { 601 ForEachChunk(IgnoredSuppressedCb, 602 const_cast<InternalMmapVector<u32> *>(&suppressed_stacks)); 603 } 604 ForEachChunk(CollectIgnoredCb, frontier); 605 ProcessGlobalRegions(frontier); 606 ProcessThreads(suspended_threads, frontier); 607 ProcessRootRegions(frontier); 608 FloodFillTag(frontier, kReachable); 609 610 CHECK_EQ(0, frontier->size()); 611 ProcessPC(frontier); 612 613 // The check here is relatively expensive, so we do this in a separate flood 614 // fill. That way we can skip the check for chunks that are reachable 615 // otherwise. 616 LOG_POINTERS("Processing platform-specific allocations.\n"); 617 ProcessPlatformSpecificAllocations(frontier); 618 FloodFillTag(frontier, kReachable); 619 620 // Iterate over leaked chunks and mark those that are reachable from other 621 // leaked chunks. 622 LOG_POINTERS("Scanning leaked chunks.\n"); 623 ForEachChunk(MarkIndirectlyLeakedCb, nullptr); 624 } 625 626 // ForEachChunk callback. Resets the tags to pre-leak-check state. 627 static void ResetTagsCb(uptr chunk, void *arg) { 628 (void)arg; 629 chunk = GetUserBegin(chunk); 630 LsanMetadata m(chunk); 631 if (m.allocated() && m.tag() != kIgnored) 632 m.set_tag(kDirectlyLeaked); 633 } 634 635 // ForEachChunk callback. Aggregates information about unreachable chunks into 636 // a LeakReport. 637 static void CollectLeaksCb(uptr chunk, void *arg) { 638 CHECK(arg); 639 LeakedChunks *leaks = reinterpret_cast<LeakedChunks *>(arg); 640 chunk = GetUserBegin(chunk); 641 LsanMetadata m(chunk); 642 if (!m.allocated()) 643 return; 644 if (m.tag() == kDirectlyLeaked || m.tag() == kIndirectlyLeaked) 645 leaks->push_back({chunk, m.stack_trace_id(), m.requested_size(), m.tag()}); 646 } 647 648 void LeakSuppressionContext::PrintMatchedSuppressions() { 649 InternalMmapVector<Suppression *> matched; 650 context.GetMatched(&matched); 651 if (!matched.size()) 652 return; 653 const char *line = "-----------------------------------------------------"; 654 Printf("%s\n", line); 655 Printf("Suppressions used:\n"); 656 Printf(" count bytes template\n"); 657 for (uptr i = 0; i < matched.size(); i++) { 658 Printf("%7zu %10zu %s\n", 659 static_cast<uptr>(atomic_load_relaxed(&matched[i]->hit_count)), 660 matched[i]->weight, matched[i]->templ); 661 } 662 Printf("%s\n\n", line); 663 } 664 665 static void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg) { 666 const InternalMmapVector<tid_t> &suspended_threads = 667 *(const InternalMmapVector<tid_t> *)arg; 668 if (tctx->status == ThreadStatusRunning) { 669 uptr i = InternalLowerBound(suspended_threads, tctx->os_id); 670 if (i >= suspended_threads.size() || suspended_threads[i] != tctx->os_id) 671 Report( 672 "Running thread %llu was not suspended. False leaks are possible.\n", 673 tctx->os_id); 674 } 675 } 676 677 # if SANITIZER_FUCHSIA 678 679 // Fuchsia provides a libc interface that guarantees all threads are 680 // covered, and SuspendedThreadList is never really used. 681 static void ReportUnsuspendedThreads(const SuspendedThreadsList &) {} 682 683 # else // !SANITIZER_FUCHSIA 684 685 static void ReportUnsuspendedThreads( 686 const SuspendedThreadsList &suspended_threads) { 687 InternalMmapVector<tid_t> threads(suspended_threads.ThreadCount()); 688 for (uptr i = 0; i < suspended_threads.ThreadCount(); ++i) 689 threads[i] = suspended_threads.GetThreadID(i); 690 691 Sort(threads.data(), threads.size()); 692 693 GetThreadRegistryLocked()->RunCallbackForEachThreadLocked( 694 &ReportIfNotSuspended, &threads); 695 } 696 697 # endif // !SANITIZER_FUCHSIA 698 699 static void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads, 700 void *arg) { 701 CheckForLeaksParam *param = reinterpret_cast<CheckForLeaksParam *>(arg); 702 CHECK(param); 703 CHECK(!param->success); 704 ReportUnsuspendedThreads(suspended_threads); 705 ClassifyAllChunks(suspended_threads, ¶m->frontier); 706 ForEachChunk(CollectLeaksCb, ¶m->leaks); 707 // Clean up for subsequent leak checks. This assumes we did not overwrite any 708 // kIgnored tags. 709 ForEachChunk(ResetTagsCb, nullptr); 710 param->success = true; 711 } 712 713 static bool PrintResults(LeakReport &report) { 714 uptr unsuppressed_count = report.UnsuppressedLeakCount(); 715 if (unsuppressed_count) { 716 Decorator d; 717 Printf( 718 "\n" 719 "=================================================================" 720 "\n"); 721 Printf("%s", d.Error()); 722 Report("ERROR: LeakSanitizer: detected memory leaks\n"); 723 Printf("%s", d.Default()); 724 report.ReportTopLeaks(flags()->max_leaks); 725 } 726 if (common_flags()->print_suppressions) 727 GetSuppressionContext()->PrintMatchedSuppressions(); 728 if (unsuppressed_count > 0) { 729 report.PrintSummary(); 730 return true; 731 } 732 return false; 733 } 734 735 static bool CheckForLeaks() { 736 if (&__lsan_is_turned_off && __lsan_is_turned_off()) 737 return false; 738 // Inside LockStuffAndStopTheWorld we can't run symbolizer, so we can't match 739 // suppressions. However if a stack id was previously suppressed, it should be 740 // suppressed in future checks as well. 741 for (int i = 0;; ++i) { 742 EnsureMainThreadIDIsCorrect(); 743 CheckForLeaksParam param; 744 LockStuffAndStopTheWorld(CheckForLeaksCallback, ¶m); 745 if (!param.success) { 746 Report("LeakSanitizer has encountered a fatal error.\n"); 747 Report( 748 "HINT: For debugging, try setting environment variable " 749 "LSAN_OPTIONS=verbosity=1:log_threads=1\n"); 750 Report( 751 "HINT: LeakSanitizer does not work under ptrace (strace, gdb, " 752 "etc)\n"); 753 Die(); 754 } 755 LeakReport leak_report; 756 leak_report.AddLeakedChunks(param.leaks); 757 758 // No new suppressions stacks, so rerun will not help and we can report. 759 if (!leak_report.ApplySuppressions()) 760 return PrintResults(leak_report); 761 762 // No indirect leaks to report, so we are done here. 763 if (!leak_report.IndirectUnsuppressedLeakCount()) 764 return PrintResults(leak_report); 765 766 if (i >= 8) { 767 Report("WARNING: LeakSanitizer gave up on indirect leaks suppression.\n"); 768 return PrintResults(leak_report); 769 } 770 771 // We found a new previously unseen suppressed call stack. Rerun to make 772 // sure it does not hold indirect leaks. 773 VReport(1, "Rerun with %zu suppressed stacks.", 774 GetSuppressionContext()->GetSortedSuppressedStacks().size()); 775 } 776 } 777 778 static bool has_reported_leaks = false; 779 bool HasReportedLeaks() { return has_reported_leaks; } 780 781 void DoLeakCheck() { 782 Lock l(&global_mutex); 783 static bool already_done; 784 if (already_done) 785 return; 786 already_done = true; 787 has_reported_leaks = CheckForLeaks(); 788 if (has_reported_leaks) 789 HandleLeaks(); 790 } 791 792 static int DoRecoverableLeakCheck() { 793 Lock l(&global_mutex); 794 bool have_leaks = CheckForLeaks(); 795 return have_leaks ? 1 : 0; 796 } 797 798 void DoRecoverableLeakCheckVoid() { DoRecoverableLeakCheck(); } 799 800 ///// LeakReport implementation. ///// 801 802 // A hard limit on the number of distinct leaks, to avoid quadratic complexity 803 // in LeakReport::AddLeakedChunk(). We don't expect to ever see this many leaks 804 // in real-world applications. 805 // FIXME: Get rid of this limit by moving logic into DedupLeaks. 806 const uptr kMaxLeaksConsidered = 5000; 807 808 void LeakReport::AddLeakedChunks(const LeakedChunks &chunks) { 809 for (const LeakedChunk &leak : chunks) { 810 uptr chunk = leak.chunk; 811 u32 stack_trace_id = leak.stack_trace_id; 812 uptr leaked_size = leak.leaked_size; 813 ChunkTag tag = leak.tag; 814 CHECK(tag == kDirectlyLeaked || tag == kIndirectlyLeaked); 815 816 if (u32 resolution = flags()->resolution) { 817 StackTrace stack = StackDepotGet(stack_trace_id); 818 stack.size = Min(stack.size, resolution); 819 stack_trace_id = StackDepotPut(stack); 820 } 821 822 bool is_directly_leaked = (tag == kDirectlyLeaked); 823 uptr i; 824 for (i = 0; i < leaks_.size(); i++) { 825 if (leaks_[i].stack_trace_id == stack_trace_id && 826 leaks_[i].is_directly_leaked == is_directly_leaked) { 827 leaks_[i].hit_count++; 828 leaks_[i].total_size += leaked_size; 829 break; 830 } 831 } 832 if (i == leaks_.size()) { 833 if (leaks_.size() == kMaxLeaksConsidered) 834 return; 835 Leak leak = {next_id_++, /* hit_count */ 1, 836 leaked_size, stack_trace_id, 837 is_directly_leaked, /* is_suppressed */ false}; 838 leaks_.push_back(leak); 839 } 840 if (flags()->report_objects) { 841 LeakedObject obj = {leaks_[i].id, chunk, leaked_size}; 842 leaked_objects_.push_back(obj); 843 } 844 } 845 } 846 847 static bool LeakComparator(const Leak &leak1, const Leak &leak2) { 848 if (leak1.is_directly_leaked == leak2.is_directly_leaked) 849 return leak1.total_size > leak2.total_size; 850 else 851 return leak1.is_directly_leaked; 852 } 853 854 void LeakReport::ReportTopLeaks(uptr num_leaks_to_report) { 855 CHECK(leaks_.size() <= kMaxLeaksConsidered); 856 Printf("\n"); 857 if (leaks_.size() == kMaxLeaksConsidered) 858 Printf( 859 "Too many leaks! Only the first %zu leaks encountered will be " 860 "reported.\n", 861 kMaxLeaksConsidered); 862 863 uptr unsuppressed_count = UnsuppressedLeakCount(); 864 if (num_leaks_to_report > 0 && num_leaks_to_report < unsuppressed_count) 865 Printf("The %zu top leak(s):\n", num_leaks_to_report); 866 Sort(leaks_.data(), leaks_.size(), &LeakComparator); 867 uptr leaks_reported = 0; 868 for (uptr i = 0; i < leaks_.size(); i++) { 869 if (leaks_[i].is_suppressed) 870 continue; 871 PrintReportForLeak(i); 872 leaks_reported++; 873 if (leaks_reported == num_leaks_to_report) 874 break; 875 } 876 if (leaks_reported < unsuppressed_count) { 877 uptr remaining = unsuppressed_count - leaks_reported; 878 Printf("Omitting %zu more leak(s).\n", remaining); 879 } 880 } 881 882 void LeakReport::PrintReportForLeak(uptr index) { 883 Decorator d; 884 Printf("%s", d.Leak()); 885 Printf("%s leak of %zu byte(s) in %zu object(s) allocated from:\n", 886 leaks_[index].is_directly_leaked ? "Direct" : "Indirect", 887 leaks_[index].total_size, leaks_[index].hit_count); 888 Printf("%s", d.Default()); 889 890 CHECK(leaks_[index].stack_trace_id); 891 StackDepotGet(leaks_[index].stack_trace_id).Print(); 892 893 if (flags()->report_objects) { 894 Printf("Objects leaked above:\n"); 895 PrintLeakedObjectsForLeak(index); 896 Printf("\n"); 897 } 898 } 899 900 void LeakReport::PrintLeakedObjectsForLeak(uptr index) { 901 u32 leak_id = leaks_[index].id; 902 for (uptr j = 0; j < leaked_objects_.size(); j++) { 903 if (leaked_objects_[j].leak_id == leak_id) 904 Printf("%p (%zu bytes)\n", (void *)leaked_objects_[j].addr, 905 leaked_objects_[j].size); 906 } 907 } 908 909 void LeakReport::PrintSummary() { 910 CHECK(leaks_.size() <= kMaxLeaksConsidered); 911 uptr bytes = 0, allocations = 0; 912 for (uptr i = 0; i < leaks_.size(); i++) { 913 if (leaks_[i].is_suppressed) 914 continue; 915 bytes += leaks_[i].total_size; 916 allocations += leaks_[i].hit_count; 917 } 918 InternalScopedString summary; 919 summary.append("%zu byte(s) leaked in %zu allocation(s).", bytes, 920 allocations); 921 ReportErrorSummary(summary.data()); 922 } 923 924 uptr LeakReport::ApplySuppressions() { 925 LeakSuppressionContext *suppressions = GetSuppressionContext(); 926 uptr new_suppressions = false; 927 for (uptr i = 0; i < leaks_.size(); i++) { 928 if (suppressions->Suppress(leaks_[i].stack_trace_id, leaks_[i].hit_count, 929 leaks_[i].total_size)) { 930 leaks_[i].is_suppressed = true; 931 ++new_suppressions; 932 } 933 } 934 return new_suppressions; 935 } 936 937 uptr LeakReport::UnsuppressedLeakCount() { 938 uptr result = 0; 939 for (uptr i = 0; i < leaks_.size(); i++) 940 if (!leaks_[i].is_suppressed) 941 result++; 942 return result; 943 } 944 945 uptr LeakReport::IndirectUnsuppressedLeakCount() { 946 uptr result = 0; 947 for (uptr i = 0; i < leaks_.size(); i++) 948 if (!leaks_[i].is_suppressed && !leaks_[i].is_directly_leaked) 949 result++; 950 return result; 951 } 952 953 } // namespace __lsan 954 #else // CAN_SANITIZE_LEAKS 955 namespace __lsan { 956 void InitCommonLsan() {} 957 void DoLeakCheck() {} 958 void DoRecoverableLeakCheckVoid() {} 959 void DisableInThisThread() {} 960 void EnableInThisThread() {} 961 } // namespace __lsan 962 #endif // CAN_SANITIZE_LEAKS 963 964 using namespace __lsan; 965 966 extern "C" { 967 SANITIZER_INTERFACE_ATTRIBUTE 968 void __lsan_ignore_object(const void *p) { 969 #if CAN_SANITIZE_LEAKS 970 if (!common_flags()->detect_leaks) 971 return; 972 // Cannot use PointsIntoChunk or LsanMetadata here, since the allocator is not 973 // locked. 974 Lock l(&global_mutex); 975 IgnoreObjectResult res = IgnoreObjectLocked(p); 976 if (res == kIgnoreObjectInvalid) 977 VReport(1, "__lsan_ignore_object(): no heap object found at %p", p); 978 if (res == kIgnoreObjectAlreadyIgnored) 979 VReport(1, 980 "__lsan_ignore_object(): " 981 "heap object at %p is already being ignored\n", 982 p); 983 if (res == kIgnoreObjectSuccess) 984 VReport(1, "__lsan_ignore_object(): ignoring heap object at %p\n", p); 985 #endif // CAN_SANITIZE_LEAKS 986 } 987 988 SANITIZER_INTERFACE_ATTRIBUTE 989 void __lsan_register_root_region(const void *begin, uptr size) { 990 #if CAN_SANITIZE_LEAKS 991 Lock l(&global_mutex); 992 RootRegion region = {reinterpret_cast<uptr>(begin), size}; 993 root_regions.push_back(region); 994 VReport(1, "Registered root region at %p of size %zu\n", begin, size); 995 #endif // CAN_SANITIZE_LEAKS 996 } 997 998 SANITIZER_INTERFACE_ATTRIBUTE 999 void __lsan_unregister_root_region(const void *begin, uptr size) { 1000 #if CAN_SANITIZE_LEAKS 1001 Lock l(&global_mutex); 1002 bool removed = false; 1003 for (uptr i = 0; i < root_regions.size(); i++) { 1004 RootRegion region = root_regions[i]; 1005 if (region.begin == reinterpret_cast<uptr>(begin) && region.size == size) { 1006 removed = true; 1007 uptr last_index = root_regions.size() - 1; 1008 root_regions[i] = root_regions[last_index]; 1009 root_regions.pop_back(); 1010 VReport(1, "Unregistered root region at %p of size %zu\n", begin, size); 1011 break; 1012 } 1013 } 1014 if (!removed) { 1015 Report( 1016 "__lsan_unregister_root_region(): region at %p of size %zu has not " 1017 "been registered.\n", 1018 begin, size); 1019 Die(); 1020 } 1021 #endif // CAN_SANITIZE_LEAKS 1022 } 1023 1024 SANITIZER_INTERFACE_ATTRIBUTE 1025 void __lsan_disable() { 1026 #if CAN_SANITIZE_LEAKS 1027 __lsan::DisableInThisThread(); 1028 #endif 1029 } 1030 1031 SANITIZER_INTERFACE_ATTRIBUTE 1032 void __lsan_enable() { 1033 #if CAN_SANITIZE_LEAKS 1034 __lsan::EnableInThisThread(); 1035 #endif 1036 } 1037 1038 SANITIZER_INTERFACE_ATTRIBUTE 1039 void __lsan_do_leak_check() { 1040 #if CAN_SANITIZE_LEAKS 1041 if (common_flags()->detect_leaks) 1042 __lsan::DoLeakCheck(); 1043 #endif // CAN_SANITIZE_LEAKS 1044 } 1045 1046 SANITIZER_INTERFACE_ATTRIBUTE 1047 int __lsan_do_recoverable_leak_check() { 1048 #if CAN_SANITIZE_LEAKS 1049 if (common_flags()->detect_leaks) 1050 return __lsan::DoRecoverableLeakCheck(); 1051 #endif // CAN_SANITIZE_LEAKS 1052 return 0; 1053 } 1054 1055 SANITIZER_INTERFACE_WEAK_DEF(const char *, __lsan_default_options, void) { 1056 return ""; 1057 } 1058 1059 #if !SANITIZER_SUPPORTS_WEAK_HOOKS 1060 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE int 1061 __lsan_is_turned_off() { 1062 return 0; 1063 } 1064 1065 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE const char * 1066 __lsan_default_suppressions() { 1067 return ""; 1068 } 1069 #endif 1070 } // extern "C" 1071