lsan_common.h revision b3b46dad13a2111a51fb1a67f36c8b633410e9b7
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 kIgnored = 3 37}; 38 39struct Flags { 40 uptr pointer_alignment() const { 41 return use_unaligned ? 1 : sizeof(uptr); 42 } 43 44 // Print addresses of leaked objects after main leak report. 45 bool report_objects; 46 // Aggregate two objects into one leak if this many stack frames match. If 47 // zero, the entire stack trace must match. 48 int resolution; 49 // The number of leaks reported. 50 int max_leaks; 51 // If nonzero kill the process with this exit code upon finding leaks. 52 int exitcode; 53 54 // Flags controlling the root set of reachable memory. 55 // Global variables (.data and .bss). 56 bool use_globals; 57 // Thread stacks. 58 bool use_stacks; 59 // Thread registers. 60 bool use_registers; 61 // TLS and thread-specific storage. 62 bool use_tls; 63 64 // Consider unaligned pointers valid. 65 bool use_unaligned; 66 67 // User-visible verbosity. 68 int verbosity; 69 70 // Debug logging. 71 bool log_pointers; 72 bool log_threads; 73}; 74 75extern Flags lsan_flags; 76inline Flags *flags() { return &lsan_flags; } 77 78void InitCommonLsan(); 79// Testing interface. Find leaked chunks and dump their addresses to vector. 80void ReportLeaked(InternalVector<void *> *leaked, uptr sources); 81// Normal leak check. Find leaks and print a report according to flags. 82void DoLeakCheck(); 83 84struct Leak { 85 uptr hit_count; 86 uptr total_size; 87 u32 stack_trace_id; 88 bool is_directly_leaked; 89}; 90 91// Aggregates leaks by stack trace prefix. 92class LeakReport { 93 public: 94 LeakReport() : leaks_(1) {} 95 void Add(u32 stack_trace_id, uptr leaked_size, ChunkTag tag); 96 void PrintLargest(uptr max_leaks); 97 void PrintSummary(); 98 bool IsEmpty() { return leaks_.size() == 0; } 99 private: 100 InternalVector<Leak> leaks_; 101}; 102 103// Platform-specific functions. 104void InitializePlatformSpecificModules(); 105void ProcessGlobalRegions(InternalVector<uptr> *frontier); 106void ProcessPlatformSpecificAllocations(InternalVector<uptr> *frontier); 107 108void ScanRangeForPointers(uptr begin, uptr end, InternalVector<uptr> *frontier, 109 const char *region_type, ChunkTag tag); 110 111// Callables for iterating over chunks. Those classes are used as template 112// parameters in ForEachChunk, so we must expose them here to allow for explicit 113// template instantiation. 114 115// Identifies unreachable chunks which must be treated as reachable. Marks them 116// as reachable and adds them to the frontier. 117class ProcessPlatformSpecificAllocationsCb { 118 public: 119 explicit ProcessPlatformSpecificAllocationsCb(InternalVector<uptr> *frontier) 120 : frontier_(frontier) {} 121 void operator()(void *p) const; 122 private: 123 InternalVector<uptr> *frontier_; 124}; 125 126// Prints addresses of unreachable chunks. 127class PrintLeakedCb { 128 public: 129 void operator()(void *p) const; 130}; 131 132// Aggregates unreachable chunks into a LeakReport. 133class CollectLeaksCb { 134 public: 135 explicit CollectLeaksCb(LeakReport *leak_report) 136 : leak_report_(leak_report) {} 137 void operator()(void *p) const; 138 private: 139 LeakReport *leak_report_; 140}; 141 142// Scans each leaked chunk for pointers to other leaked chunks, and marks each 143// of them as indirectly leaked. 144class MarkIndirectlyLeakedCb { 145 public: 146 void operator()(void *p) const; 147}; 148 149// Finds all chunk marked as kIgnored and adds their addresses to frontier. 150class CollectSuppressedCb { 151 public: 152 explicit CollectSuppressedCb(InternalVector<uptr> *frontier) 153 : frontier_(frontier) {} 154 void operator()(void *p) const; 155 private: 156 InternalVector<uptr> *frontier_; 157}; 158 159enum IgnoreObjectResult { 160 kIgnoreObjectSuccess, 161 kIgnoreObjectAlreadyIgnored, 162 kIgnoreObjectInvalid 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// Helper for __lsan_ignore_object(). 185IgnoreObjectResult IgnoreObjectLocked(const void *p); 186// Wrapper for chunk metadata operations. 187class LsanMetadata { 188 public: 189 // Constructor accepts pointer to user-visible chunk. 190 explicit LsanMetadata(void *chunk); 191 bool allocated() const; 192 ChunkTag tag() const; 193 void set_tag(ChunkTag value); 194 uptr requested_size() const; 195 u32 stack_trace_id() const; 196 private: 197 void *metadata_; 198}; 199 200} // namespace __lsan 201 202#endif // LSAN_COMMON_H 203