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 30 namespace __lsan { 31 32 // Chunk tags. 33 enum ChunkTag { 34 kDirectlyLeaked = 0, // default 35 kIndirectlyLeaked = 1, 36 kReachable = 2, 37 kIgnored = 3 38 }; 39 40 struct 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 78 extern Flags lsan_flags; 79 inline Flags *flags() { return &lsan_flags; } 80 81 struct 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. 90 class 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 102 typedef InternalMmapVector<uptr> Frontier; 103 104 // Platform-specific functions. 105 void InitializePlatformSpecificModules(); 106 void ProcessGlobalRegions(Frontier *frontier); 107 void ProcessPlatformSpecificAllocations(Frontier *frontier); 108 109 void ScanRangeForPointers(uptr begin, uptr end, 110 Frontier *frontier, 111 const char *region_type, ChunkTag tag); 112 113 enum IgnoreObjectResult { 114 kIgnoreObjectSuccess, 115 kIgnoreObjectAlreadyIgnored, 116 kIgnoreObjectInvalid 117 }; 118 119 // Functions called from the parent tool. 120 void InitCommonLsan(); 121 void DoLeakCheck(); 122 bool DisabledInThisThread(); 123 124 // The following must be implemented in the parent tool. 125 126 void ForEachChunk(ForEachChunkCallback callback, void *arg); 127 // Returns the address range occupied by the global allocator object. 128 void GetAllocatorGlobalRange(uptr *begin, uptr *end); 129 // Wrappers for allocator's ForceLock()/ForceUnlock(). 130 void LockAllocator(); 131 void UnlockAllocator(); 132 // Wrappers for ThreadRegistry access. 133 void LockThreadRegistry(); 134 void UnlockThreadRegistry(); 135 bool 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). 144 void EnsureMainThreadIDIsCorrect(); 145 // If p points into a chunk that has been allocated to the user, returns its 146 // user-visible address. Otherwise, returns 0. 147 uptr PointsIntoChunk(void *p); 148 // Returns address of user-visible chunk contained in this allocator chunk. 149 uptr GetUserBegin(uptr chunk); 150 // Helper for __lsan_ignore_object(). 151 IgnoreObjectResult IgnoreObjectLocked(const void *p); 152 // Wrapper for chunk metadata operations. 153 class 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 168 extern "C" { 169 int __lsan_is_turned_off() SANITIZER_WEAK_ATTRIBUTE 170 SANITIZER_INTERFACE_ATTRIBUTE; 171 const char *__lsan_default_suppressions() SANITIZER_WEAK_ATTRIBUTE 172 SANITIZER_INTERFACE_ATTRIBUTE; 173 } // extern "C" 174 175 #endif // LSAN_COMMON_H 176