lsan_common.h revision 5e719a705666988781b9735d62cafc808ade60e2
1//=-- lsan_common.h -------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of LeakSanitizer.
11// Private LSan header.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LSAN_COMMON_H
16#define LSAN_COMMON_H
17
18#include "sanitizer_common/sanitizer_common.h"
19#include "sanitizer_common/sanitizer_internal_defs.h"
20#include "sanitizer_common/sanitizer_platform.h"
21#include "sanitizer_common/sanitizer_symbolizer.h"
22
23#if SANITIZER_LINUX && defined(__x86_64__)
24#define CAN_SANITIZE_LEAKS 1
25#else
26#define CAN_SANITIZE_LEAKS 0
27#endif
28
29namespace __lsan {
30
31// Chunk tags.
32enum ChunkTag {
33  kDirectlyLeaked = 0,  // default
34  kIndirectlyLeaked = 1,
35  kReachable = 2,
36  kSuppressed = 3
37};
38
39struct Flags {
40  uptr pointer_alignment() const {
41    return use_unaligned ? 1 : sizeof(uptr);
42  }
43
44  // Print addresses of leaked blocks after main leak report.
45  bool report_blocks;
46  // Aggregate two blocks into one leak if this many stack frames match. If
47  // zero, the entire stack trace must match.
48  int resolution;
49  // The number of leaks reported.
50  int max_leaks;
51  // If nonzero kill the process with this exit code upon finding leaks.
52  int exitcode;
53
54  // Flags controlling the root set of reachable memory.
55  // Global variables (.data and .bss).
56  bool use_globals;
57  // Thread stacks.
58  bool use_stacks;
59  // Thread registers.
60  bool use_registers;
61  // TLS and thread-specific storage.
62  bool use_tls;
63
64  // Consider unaligned pointers valid.
65  bool use_unaligned;
66
67  // Debug logging.
68  bool log_pointers;
69  bool log_threads;
70};
71
72extern Flags lsan_flags;
73inline Flags *flags() { return &lsan_flags; }
74
75void InitCommonLsan();
76// Testing interface. Find leaked chunks and dump their addresses to vector.
77void ReportLeaked(InternalVector<void *> *leaked, uptr sources);
78// Normal leak check. Find leaks and print a report according to flags.
79void DoLeakCheck();
80
81struct Leak {
82  uptr hit_count;
83  uptr total_size;
84  u32 stack_trace_id;
85  bool is_directly_leaked;
86};
87
88// Aggregates leaks by stack trace prefix.
89class LeakReport {
90 public:
91  LeakReport() : leaks_(1) {}
92  void Add(u32 stack_trace_id, uptr leaked_size, ChunkTag tag);
93  void PrintLargest(uptr max_leaks);
94  void PrintSummary();
95  bool IsEmpty() { return leaks_.size() == 0; }
96 private:
97  InternalVector<Leak> leaks_;
98};
99
100// Platform-specific functions.
101void InitializePlatformSpecificModules();
102void ProcessGlobalRegions(InternalVector<uptr> *frontier);
103void ProcessPlatformSpecificAllocations(InternalVector<uptr> *frontier);
104
105void ScanRangeForPointers(uptr begin, uptr end, InternalVector<uptr> *frontier,
106                          const char *region_type, ChunkTag tag);
107
108// Callables for iterating over chunks. Those classes are used as template
109// parameters in ForEachChunk, so we must expose them here to allow for explicit
110// template instantiation.
111
112// Identifies unreachable chunks which must be treated as reachable. Marks them
113// as reachable and adds them to the frontier.
114class ProcessPlatformSpecificAllocationsCb {
115 public:
116  explicit ProcessPlatformSpecificAllocationsCb(InternalVector<uptr> *frontier)
117      : frontier_(frontier) {}
118  void operator()(void *p) const;
119 private:
120  InternalVector<uptr> *frontier_;
121};
122
123// Prints addresses of unreachable chunks.
124class PrintLeakedCb {
125 public:
126  void operator()(void *p) const;
127};
128
129// Aggregates unreachable chunks into a LeakReport.
130class CollectLeaksCb {
131 public:
132  explicit CollectLeaksCb(LeakReport *leak_report)
133      : leak_report_(leak_report) {}
134  void operator()(void *p) const;
135 private:
136  LeakReport *leak_report_;
137};
138
139// Scans each leaked chunk for pointers to other leaked chunks, and marks each
140// of them as indirectly leaked.
141class MarkIndirectlyLeakedCb {
142 public:
143  void operator()(void *p) const;
144};
145
146// Finds all chunk marked as kSuppressed and adds their addresses to frontier.
147class CollectSuppressedCb {
148 public:
149  explicit CollectSuppressedCb(InternalVector<uptr> *frontier)
150      : frontier_(frontier) {}
151  void operator()(void *p) const;
152 private:
153  InternalVector<uptr> *frontier_;
154};
155
156// The following must be implemented in the parent tool.
157
158template<typename Callable> void ForEachChunk(Callable const &callback);
159// The address range occupied by the global allocator object.
160void GetAllocatorGlobalRange(uptr *begin, uptr *end);
161// Wrappers for allocator's ForceLock()/ForceUnlock().
162void LockAllocator();
163void UnlockAllocator();
164// Wrappers for ThreadRegistry access.
165void LockThreadRegistry();
166void UnlockThreadRegistry();
167bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,
168                           uptr *tls_begin, uptr *tls_end,
169                           uptr *cache_begin, uptr *cache_end);
170// If p points into a chunk that has been allocated to the user, return its
171// user-visible address. Otherwise, return 0.
172void *PointsIntoChunk(void *p);
173// Return address of user-visible chunk contained in this allocator chunk.
174void *GetUserBegin(void *p);
175// Wrapper for chunk metadata operations.
176class LsanMetadata {
177 public:
178  // Constructor accepts pointer to user-visible chunk.
179  explicit LsanMetadata(void *chunk);
180  bool allocated() const;
181  ChunkTag tag() const;
182  void set_tag(ChunkTag value);
183  uptr requested_size() const;
184  u32 stack_trace_id() const;
185 private:
186  void *metadata_;
187};
188
189}  // namespace __lsan
190
191#endif  // LSAN_COMMON_H
192