lsan_common.h revision 29b756851c04df07f1584dfd77021dd2f37a7391
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_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// user-visible address. Otherwise, return 0. 174void *PointsIntoChunk(void *p); 175// Return address of user-visible chunk contained in this allocator chunk. 176void *GetUserBegin(void *p); 177// Wrapper for chunk metadata operations. 178class LsanMetadata { 179 public: 180 // Constructor accepts pointer to user-visible chunk. 181 explicit LsanMetadata(void *chunk); 182 bool allocated() const; 183 ChunkTag tag() const; 184 void set_tag(ChunkTag value); 185 uptr requested_size() const; 186 u32 stack_trace_id() const; 187 private: 188 void *metadata_; 189}; 190 191} // namespace __lsan 192 193#endif // LSAN_COMMON_H 194