1 //=-- lsan_common.h -------------------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of LeakSanitizer.
9 // Private LSan header.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LSAN_COMMON_H
14 #define LSAN_COMMON_H
15 
16 #include "sanitizer_common/sanitizer_allocator.h"
17 #include "sanitizer_common/sanitizer_common.h"
18 #include "sanitizer_common/sanitizer_internal_defs.h"
19 #include "sanitizer_common/sanitizer_platform.h"
20 #include "sanitizer_common/sanitizer_symbolizer.h"
21 
22 #if SANITIZER_LINUX && defined(__x86_64__)
23 #define CAN_SANITIZE_LEAKS 1
24 #else
25 #define CAN_SANITIZE_LEAKS 0
26 #endif
27 
28 namespace __lsan {
29 
30 // Chunk tags.
31 enum ChunkTag {
32   kDirectlyLeaked = 0,  // default
33   kIndirectlyLeaked = 1,
34   kReachable = 2,
35   kIgnored = 3
36 };
37 
38 struct Flags {
pointer_alignmentFlags39   uptr pointer_alignment() const {
40     return use_unaligned ? 1 : sizeof(uptr);
41   }
42 
43   // Print addresses of leaked objects after main leak report.
44   bool report_objects;
45   // Aggregate two objects into one leak if this many stack frames match. If
46   // zero, the entire stack trace must match.
47   int resolution;
48   // The number of leaks reported.
49   int max_leaks;
50   // If nonzero kill the process with this exit code upon finding leaks.
51   int exitcode;
52   // Suppressions file name.
53   const char* suppressions;
54 
55   // Flags controlling the root set of reachable memory.
56   // Global variables (.data and .bss).
57   bool use_globals;
58   // Thread stacks.
59   bool use_stacks;
60   // Thread registers.
61   bool use_registers;
62   // TLS and thread-specific storage.
63   bool use_tls;
64 
65   // Consider unaligned pointers valid.
66   bool use_unaligned;
67 
68   // User-visible verbosity.
69   int verbosity;
70 
71   // Debug logging.
72   bool log_pointers;
73   bool log_threads;
74 };
75 
76 extern Flags lsan_flags;
flags()77 inline Flags *flags() { return &lsan_flags; }
78 
79 struct Leak {
80   uptr hit_count;
81   uptr total_size;
82   u32 stack_trace_id;
83   bool is_directly_leaked;
84   bool is_suppressed;
85 };
86 
87 // Aggregates leaks by stack trace prefix.
88 class LeakReport {
89  public:
LeakReport()90   LeakReport() : leaks_(1) {}
91   void Add(u32 stack_trace_id, uptr leaked_size, ChunkTag tag);
92   void PrintLargest(uptr max_leaks);
93   void PrintSummary();
IsEmpty()94   bool IsEmpty() { return leaks_.size() == 0; }
95   uptr ApplySuppressions();
96  private:
97   InternalMmapVector<Leak> leaks_;
98 };
99 
100 typedef InternalMmapVector<uptr> Frontier;
101 
102 // Platform-specific functions.
103 void InitializePlatformSpecificModules();
104 void ProcessGlobalRegions(Frontier *frontier);
105 void ProcessPlatformSpecificAllocations(Frontier *frontier);
106 
107 void ScanRangeForPointers(uptr begin, uptr end,
108                           Frontier *frontier,
109                           const char *region_type, ChunkTag tag);
110 
111 enum IgnoreObjectResult {
112   kIgnoreObjectSuccess,
113   kIgnoreObjectAlreadyIgnored,
114   kIgnoreObjectInvalid
115 };
116 
117 // Functions called from the parent tool.
118 void InitCommonLsan();
119 void DoLeakCheck();
120 bool DisabledInThisThread();
121 
122 // The following must be implemented in the parent tool.
123 
124 void ForEachChunk(ForEachChunkCallback callback, void *arg);
125 // Returns the address range occupied by the global allocator object.
126 void GetAllocatorGlobalRange(uptr *begin, uptr *end);
127 // Wrappers for allocator's ForceLock()/ForceUnlock().
128 void LockAllocator();
129 void UnlockAllocator();
130 // Wrappers for ThreadRegistry access.
131 void LockThreadRegistry();
132 void UnlockThreadRegistry();
133 bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,
134                            uptr *tls_begin, uptr *tls_end,
135                            uptr *cache_begin, uptr *cache_end);
136 void ForEachExtraStackRange(uptr os_id, RangeIteratorCallback callback,
137                             void *arg);
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 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
170 int __lsan_is_turned_off();
171 
172 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
173 const char *__lsan_default_suppressions();
174 }  // extern "C"
175 
176 #endif  // LSAN_COMMON_H
177