lsan_common.h revision 9bdf7802d403b53baee3433ddddc220f457e039c
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
72  // Debug logging.
73  bool log_pointers;
74  bool log_threads;
75};
76
77extern Flags lsan_flags;
78inline Flags *flags() { return &lsan_flags; }
79
80void InitCommonLsan();
81// Testing interface. Find leaked chunks and dump their addresses to vector.
82void ReportLeaked(InternalVector<void *> *leaked, uptr sources);
83// Normal leak check. Find leaks and print a report according to flags.
84void DoLeakCheck();
85
86struct Leak {
87  uptr hit_count;
88  uptr total_size;
89  u32 stack_trace_id;
90  bool is_directly_leaked;
91};
92
93// Aggregates leaks by stack trace prefix.
94class LeakReport {
95 public:
96  LeakReport() : leaks_(1) {}
97  void Add(u32 stack_trace_id, uptr leaked_size, ChunkTag tag);
98  void PrintLargest(uptr max_leaks);
99  bool IsEmpty() { return leaks_.size() == 0; }
100 private:
101  InternalVector<Leak> leaks_;
102};
103
104// Platform-specific functions.
105void InitializePlatformSpecificModules();
106void ProcessGlobalRegions(InternalVector<uptr> *frontier);
107void ProcessPlatformSpecificAllocations(InternalVector<uptr> *frontier);
108
109void ScanRangeForPointers(uptr begin, uptr end, InternalVector<uptr> *frontier,
110                          const char *region_type, ChunkTag tag);
111
112// Callables for iterating over chunks. Those classes are used as template
113// parameters in ForEachChunk, so we must expose them here to allow for explicit
114// template instantiation.
115
116// Identifies unreachable chunks which must be treated as reachable. Marks them
117// as reachable and adds them to the frontier.
118class ProcessPlatformSpecificAllocationsCb {
119 public:
120  explicit ProcessPlatformSpecificAllocationsCb(InternalVector<uptr> *frontier)
121      : frontier_(frontier) {}
122  void operator()(void *p) const;
123 private:
124  InternalVector<uptr> *frontier_;
125};
126
127// Prints addresses of unreachable chunks.
128class PrintLeakedCb {
129 public:
130  void operator()(void *p) const;
131};
132
133// Aggregates unreachable chunks into a LeakReport.
134class CollectLeaksCb {
135 public:
136  explicit CollectLeaksCb(LeakReport *leak_report)
137      : leak_report_(leak_report) {}
138  void operator()(void *p) const;
139 private:
140  LeakReport *leak_report_;
141};
142
143// Dumps addresses of unreachable chunks to a vector (for testing).
144class ReportLeakedCb {
145 public:
146  explicit ReportLeakedCb(InternalVector<void *> *leaked) : leaked_(leaked) {}
147  void operator()(void *p) const;
148 private:
149  InternalVector<void *> *leaked_;
150};
151
152// Resets each chunk's tag to default (kDirectlyLeaked).
153class ClearTagCb {
154 public:
155  void operator()(void *p) const;
156};
157
158// Scans each leaked chunk for pointers to other leaked chunks, and marks each
159// of them as indirectly leaked.
160class MarkIndirectlyLeakedCb {
161 public:
162  void operator()(void *p) const;
163};
164
165// The following must be implemented in the parent tool.
166
167template<typename Callable> void ForEachChunk(Callable const &callback);
168// The address range occupied by the global allocator object.
169void GetAllocatorGlobalRange(uptr *begin, uptr *end);
170// Wrappers for allocator's ForceLock()/ForceUnlock().
171void LockAllocator();
172void UnlockAllocator();
173// Wrappers for ThreadRegistry access.
174void LockThreadRegistry();
175void UnlockThreadRegistry();
176bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,
177                           uptr *tls_begin, uptr *tls_end,
178                           uptr *cache_begin, uptr *cache_end);
179// If p points into a chunk that has been allocated to the user, return its
180// user-visible address. Otherwise, return 0.
181void *PointsIntoChunk(void *p);
182// Return address of user-visible chunk contained in this allocator chunk.
183void *GetUserBegin(void *p);
184// Wrapper for chunk metadata operations.
185class LsanMetadata {
186 public:
187  // Constructor accepts pointer to user-visible chunk.
188  explicit LsanMetadata(void *chunk);
189  bool allocated() const;
190  ChunkTag tag() const;
191  void set_tag(ChunkTag value);
192  uptr requested_size() const;
193  u32 stack_trace_id() const;
194 private:
195  void *metadata_;
196};
197
198}  // namespace __lsan
199
200#endif  // LSAN_COMMON_H
201