lsan_common.h revision 6c3634b1d5eeb0bffea01df10caa7168c48c8c5d
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};
37
38// Sources of pointers.
39// Global variables (.data and .bss).
40const uptr kSourceGlobals = 1 << 0;
41// Thread stacks.
42const uptr kSourceStacks = 1 << 1;
43// TLS and thread-specific storage.
44const uptr kSourceTLS = 1 << 2;
45// Thread registers.
46const uptr kSourceRegisters = 1 << 3;
47// Unaligned pointers.
48const uptr kSourceUnaligned = 1 << 4;
49
50// Aligned pointers everywhere.
51const uptr kSourceAllAligned =
52    kSourceGlobals | kSourceStacks | kSourceTLS | kSourceRegisters;
53
54struct Flags {
55  bool use_registers() const { return sources & kSourceRegisters; }
56  bool use_globals() const { return sources & kSourceGlobals; }
57  bool use_stacks() const { return sources & kSourceStacks; }
58  bool use_tls() const { return sources & kSourceTLS; }
59  uptr pointer_alignment() const {
60    return (sources & kSourceUnaligned) ? 1 : sizeof(uptr);
61  }
62
63  uptr sources;
64  // Print addresses of leaked blocks after main leak report.
65  bool report_blocks;
66  // Aggregate two blocks into one leak if this many stack frames match. If
67  // zero, the entire stack trace must match.
68  int resolution;
69  // The number of leaks reported.
70  int max_leaks;
71  // If nonzero kill the process with this exit code upon finding leaks.
72  int exitcode;
73
74  // Debug logging.
75  bool log_pointers;
76  bool log_threads;
77};
78
79extern Flags lsan_flags;
80inline Flags *flags() { return &lsan_flags; }
81
82void InitCommonLsan();
83// Testing interface. Find leaked chunks and dump their addresses to vector.
84void ReportLeaked(InternalVector<void *> *leaked, uptr sources);
85// Normal leak check. Find leaks and print a report according to flags.
86void DoLeakCheck();
87
88struct Leak {
89  uptr hit_count;
90  uptr total_size;
91  u32 stack_trace_id;
92  bool is_directly_leaked;
93};
94
95// Aggregates leaks by stack trace prefix.
96class LeakReport {
97 public:
98  LeakReport() : leaks_(1) {}
99  void Add(u32 stack_trace_id, uptr leaked_size, ChunkTag tag);
100  void PrintLargest(uptr max_leaks);
101  void PrintSummary();
102  bool IsEmpty() { return leaks_.size() == 0; }
103 private:
104  InternalVector<Leak> leaks_;
105};
106
107// Platform-specific functions.
108void InitializePlatformSpecificModules();
109void ProcessGlobalRegions(InternalVector<uptr> *frontier);
110void ProcessPlatformSpecificAllocations(InternalVector<uptr> *frontier);
111
112void ScanRangeForPointers(uptr begin, uptr end, InternalVector<uptr> *frontier,
113                          const char *region_type, ChunkTag tag);
114
115// Callables for iterating over chunks. Those classes are used as template
116// parameters in ForEachChunk, so we must expose them here to allow for explicit
117// template instantiation.
118
119// Identifies unreachable chunks which must be treated as reachable. Marks them
120// as reachable and adds them to the frontier.
121class ProcessPlatformSpecificAllocationsCb {
122 public:
123  explicit ProcessPlatformSpecificAllocationsCb(InternalVector<uptr> *frontier)
124      : frontier_(frontier) {}
125  void operator()(void *p) const;
126 private:
127  InternalVector<uptr> *frontier_;
128};
129
130// Prints addresses of unreachable chunks.
131class PrintLeakedCb {
132 public:
133  void operator()(void *p) const;
134};
135
136// Aggregates unreachable chunks into a LeakReport.
137class CollectLeaksCb {
138 public:
139  explicit CollectLeaksCb(LeakReport *leak_report)
140      : leak_report_(leak_report) {}
141  void operator()(void *p) const;
142 private:
143  LeakReport *leak_report_;
144};
145
146// Dumps addresses of unreachable chunks to a vector (for testing).
147class ReportLeakedCb {
148 public:
149  explicit ReportLeakedCb(InternalVector<void *> *leaked) : leaked_(leaked) {}
150  void operator()(void *p) const;
151 private:
152  InternalVector<void *> *leaked_;
153};
154
155// Resets each chunk's tag to default (kDirectlyLeaked).
156class ClearTagCb {
157 public:
158  void operator()(void *p) const;
159};
160
161// Scans each leaked chunk for pointers to other leaked chunks, and marks each
162// of them as indirectly leaked.
163class MarkIndirectlyLeakedCb {
164 public:
165  void operator()(void *p) const;
166};
167
168// The following must be implemented in the parent tool.
169
170template<typename Callable> void ForEachChunk(Callable const &callback);
171// The address range occupied by the global allocator object.
172void GetAllocatorGlobalRange(uptr *begin, uptr *end);
173// Wrappers for allocator's ForceLock()/ForceUnlock().
174void LockAllocator();
175void UnlockAllocator();
176// Wrappers for ThreadRegistry access.
177void LockThreadRegistry();
178void UnlockThreadRegistry();
179bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,
180                           uptr *tls_begin, uptr *tls_end,
181                           uptr *cache_begin, uptr *cache_end);
182// If p points into a chunk that has been allocated to the user, return its
183// user-visible address. Otherwise, return 0.
184void *PointsIntoChunk(void *p);
185// Return address of user-visible chunk contained in this allocator chunk.
186void *GetUserBegin(void *p);
187// Wrapper for chunk metadata operations.
188class LsanMetadata {
189 public:
190  // Constructor accepts pointer to user-visible chunk.
191  explicit LsanMetadata(void *chunk);
192  bool allocated() const;
193  ChunkTag tag() const;
194  void set_tag(ChunkTag value);
195  uptr requested_size() const;
196  u32 stack_trace_id() const;
197 private:
198  void *metadata_;
199};
200
201}  // namespace __lsan
202
203#endif  // LSAN_COMMON_H
204