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