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