lsan_common.h revision c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6
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_allocator.h" 19#include "sanitizer_common/sanitizer_common.h" 20#include "sanitizer_common/sanitizer_internal_defs.h" 21#include "sanitizer_common/sanitizer_platform.h" 22#include "sanitizer_common/sanitizer_symbolizer.h" 23 24#if SANITIZER_LINUX && defined(__x86_64__) 25#define CAN_SANITIZE_LEAKS 1 26#else 27#define CAN_SANITIZE_LEAKS 0 28#endif 29 30namespace __lsan { 31 32// Chunk tags. 33enum ChunkTag { 34 kDirectlyLeaked = 0, // default 35 kIndirectlyLeaked = 1, 36 kReachable = 2, 37 kIgnored = 3 38}; 39 40struct Flags { 41 uptr pointer_alignment() const { 42 return use_unaligned ? 1 : sizeof(uptr); 43 } 44 45 // Print addresses of leaked objects after main leak report. 46 bool report_objects; 47 // Aggregate two objects into one leak if this many stack frames match. If 48 // zero, the entire stack trace must match. 49 int resolution; 50 // The number of leaks reported. 51 int max_leaks; 52 // If nonzero kill the process with this exit code upon finding leaks. 53 int exitcode; 54 // Suppressions file name. 55 const char* suppressions; 56 57 // Flags controlling the root set of reachable memory. 58 // Global variables (.data and .bss). 59 bool use_globals; 60 // Thread stacks. 61 bool use_stacks; 62 // Thread registers. 63 bool use_registers; 64 // TLS and thread-specific storage. 65 bool use_tls; 66 67 // Consider unaligned pointers valid. 68 bool use_unaligned; 69 70 // User-visible verbosity. 71 int verbosity; 72 73 // Debug logging. 74 bool log_pointers; 75 bool log_threads; 76}; 77 78extern Flags lsan_flags; 79inline Flags *flags() { return &lsan_flags; } 80 81struct Leak { 82 uptr hit_count; 83 uptr total_size; 84 u32 stack_trace_id; 85 bool is_directly_leaked; 86 bool is_suppressed; 87}; 88 89// Aggregates leaks by stack trace prefix. 90class LeakReport { 91 public: 92 LeakReport() : leaks_(1) {} 93 void Add(u32 stack_trace_id, uptr leaked_size, ChunkTag tag); 94 void PrintLargest(uptr max_leaks); 95 void PrintSummary(); 96 bool IsEmpty() { return leaks_.size() == 0; } 97 uptr ApplySuppressions(); 98 private: 99 InternalMmapVector<Leak> leaks_; 100}; 101 102typedef InternalMmapVector<uptr> Frontier; 103 104// Platform-specific functions. 105void InitializePlatformSpecificModules(); 106void ProcessGlobalRegions(Frontier *frontier); 107void ProcessPlatformSpecificAllocations(Frontier *frontier); 108 109void ScanRangeForPointers(uptr begin, uptr end, 110 Frontier *frontier, 111 const char *region_type, ChunkTag tag); 112 113enum IgnoreObjectResult { 114 kIgnoreObjectSuccess, 115 kIgnoreObjectAlreadyIgnored, 116 kIgnoreObjectInvalid 117}; 118 119// Functions called from the parent tool. 120void InitCommonLsan(); 121void DoLeakCheck(); 122bool DisabledInThisThread(); 123 124// The following must be implemented in the parent tool. 125 126void ForEachChunk(ForEachChunkCallback callback, void *arg); 127// Returns the address range occupied by the global allocator object. 128void GetAllocatorGlobalRange(uptr *begin, uptr *end); 129// Wrappers for allocator's ForceLock()/ForceUnlock(). 130void LockAllocator(); 131void UnlockAllocator(); 132// Wrappers for ThreadRegistry access. 133void LockThreadRegistry(); 134void UnlockThreadRegistry(); 135bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end, 136 uptr *tls_begin, uptr *tls_end, 137 uptr *cache_begin, uptr *cache_end); 138// If called from the main thread, updates the main thread's TID in the thread 139// registry. We need this to handle processes that fork() without a subsequent 140// exec(), which invalidates the recorded TID. To update it, we must call 141// gettid() from the main thread. Our solution is to call this function before 142// leak checking and also before every call to pthread_create() (to handle cases 143// where leak checking is initiated from a non-main thread). 144void EnsureMainThreadIDIsCorrect(); 145// If p points into a chunk that has been allocated to the user, returns its 146// user-visible address. Otherwise, returns 0. 147uptr PointsIntoChunk(void *p); 148// Returns address of user-visible chunk contained in this allocator chunk. 149uptr GetUserBegin(uptr chunk); 150// Helper for __lsan_ignore_object(). 151IgnoreObjectResult IgnoreObjectLocked(const void *p); 152// Wrapper for chunk metadata operations. 153class LsanMetadata { 154 public: 155 // Constructor accepts address of user-visible chunk. 156 explicit LsanMetadata(uptr chunk); 157 bool allocated() const; 158 ChunkTag tag() const; 159 void set_tag(ChunkTag value); 160 uptr requested_size() const; 161 u32 stack_trace_id() const; 162 private: 163 void *metadata_; 164}; 165 166} // namespace __lsan 167 168extern "C" { 169int __lsan_is_turned_off() SANITIZER_WEAK_ATTRIBUTE 170 SANITIZER_INTERFACE_ATTRIBUTE; 171const char *__lsan_default_suppressions() SANITIZER_WEAK_ATTRIBUTE 172 SANITIZER_INTERFACE_ATTRIBUTE; 173} // extern "C" 174 175#endif // LSAN_COMMON_H 176