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