lsan_common.h revision 1.6 1 1.1 mrg //=-- lsan_common.h -------------------------------------------------------===//
2 1.1 mrg //
3 1.6 mrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 1.6 mrg // See https://llvm.org/LICENSE.txt for license information.
5 1.6 mrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 1.1 mrg //
7 1.1 mrg //===----------------------------------------------------------------------===//
8 1.1 mrg //
9 1.1 mrg // This file is a part of LeakSanitizer.
10 1.1 mrg // Private LSan header.
11 1.1 mrg //
12 1.1 mrg //===----------------------------------------------------------------------===//
13 1.1 mrg
14 1.1 mrg #ifndef LSAN_COMMON_H
15 1.1 mrg #define LSAN_COMMON_H
16 1.1 mrg
17 1.1 mrg #include "sanitizer_common/sanitizer_allocator.h"
18 1.1 mrg #include "sanitizer_common/sanitizer_common.h"
19 1.1 mrg #include "sanitizer_common/sanitizer_internal_defs.h"
20 1.1 mrg #include "sanitizer_common/sanitizer_platform.h"
21 1.6 mrg #include "sanitizer_common/sanitizer_stackdepot.h"
22 1.3 mrg #include "sanitizer_common/sanitizer_stoptheworld.h"
23 1.1 mrg #include "sanitizer_common/sanitizer_symbolizer.h"
24 1.1 mrg
25 1.5 mrg // LeakSanitizer relies on some Glibc's internals (e.g. TLS machinery) on Linux.
26 1.5 mrg // Also, LSan doesn't like 32 bit architectures
27 1.4 mrg // because of "small" (4 bytes) pointer size that leads to high false negative
28 1.4 mrg // ratio on large leaks. But we still want to have it for some 32 bit arches
29 1.4 mrg // (e.g. x86), see https://github.com/google/sanitizers/issues/403.
30 1.5 mrg // To enable LeakSanitizer on a new architecture, one needs to implement the
31 1.5 mrg // internal_clone function as well as (probably) adjust the TLS machinery for
32 1.5 mrg // the new architecture inside the sanitizer library.
33 1.6 mrg // Exclude leak-detection on arm32 for Android because `__aeabi_read_tp`
34 1.6 mrg // is missing. This caused a link error.
35 1.6 mrg #if SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__))
36 1.6 mrg #define CAN_SANITIZE_LEAKS 0
37 1.6 mrg #elif (SANITIZER_LINUX || SANITIZER_MAC) && (SANITIZER_WORDSIZE == 64) && \
38 1.6 mrg (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \
39 1.6 mrg defined(__powerpc64__) || defined(__s390x__))
40 1.6 mrg #define CAN_SANITIZE_LEAKS 1
41 1.6 mrg #elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_MAC)
42 1.4 mrg #define CAN_SANITIZE_LEAKS 1
43 1.6 mrg #elif defined(__arm__) && SANITIZER_LINUX
44 1.4 mrg #define CAN_SANITIZE_LEAKS 1
45 1.6 mrg #elif SANITIZER_RISCV64 && SANITIZER_LINUX
46 1.1 mrg #define CAN_SANITIZE_LEAKS 1
47 1.6 mrg #elif SANITIZER_NETBSD || SANITIZER_FUCHSIA
48 1.5 mrg #define CAN_SANITIZE_LEAKS 1
49 1.1 mrg #else
50 1.1 mrg #define CAN_SANITIZE_LEAKS 0
51 1.1 mrg #endif
52 1.1 mrg
53 1.3 mrg namespace __sanitizer {
54 1.3 mrg class FlagParser;
55 1.5 mrg class ThreadRegistry;
56 1.6 mrg class ThreadContextBase;
57 1.3 mrg struct DTLS;
58 1.3 mrg }
59 1.3 mrg
60 1.1 mrg namespace __lsan {
61 1.1 mrg
62 1.1 mrg // Chunk tags.
63 1.1 mrg enum ChunkTag {
64 1.1 mrg kDirectlyLeaked = 0, // default
65 1.1 mrg kIndirectlyLeaked = 1,
66 1.1 mrg kReachable = 2,
67 1.1 mrg kIgnored = 3
68 1.1 mrg };
69 1.1 mrg
70 1.1 mrg struct Flags {
71 1.3 mrg #define LSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;
72 1.3 mrg #include "lsan_flags.inc"
73 1.3 mrg #undef LSAN_FLAG
74 1.3 mrg
75 1.3 mrg void SetDefaults();
76 1.1 mrg uptr pointer_alignment() const {
77 1.1 mrg return use_unaligned ? 1 : sizeof(uptr);
78 1.1 mrg }
79 1.1 mrg };
80 1.1 mrg
81 1.1 mrg extern Flags lsan_flags;
82 1.1 mrg inline Flags *flags() { return &lsan_flags; }
83 1.3 mrg void RegisterLsanFlags(FlagParser *parser, Flags *f);
84 1.1 mrg
85 1.1 mrg struct Leak {
86 1.1 mrg u32 id;
87 1.1 mrg uptr hit_count;
88 1.1 mrg uptr total_size;
89 1.1 mrg u32 stack_trace_id;
90 1.1 mrg bool is_directly_leaked;
91 1.1 mrg bool is_suppressed;
92 1.1 mrg };
93 1.1 mrg
94 1.1 mrg struct LeakedObject {
95 1.1 mrg u32 leak_id;
96 1.1 mrg uptr addr;
97 1.1 mrg uptr size;
98 1.1 mrg };
99 1.1 mrg
100 1.1 mrg // Aggregates leaks by stack trace prefix.
101 1.1 mrg class LeakReport {
102 1.1 mrg public:
103 1.5 mrg LeakReport() {}
104 1.1 mrg void AddLeakedChunk(uptr chunk, u32 stack_trace_id, uptr leaked_size,
105 1.1 mrg ChunkTag tag);
106 1.1 mrg void ReportTopLeaks(uptr max_leaks);
107 1.1 mrg void PrintSummary();
108 1.6 mrg uptr ApplySuppressions();
109 1.1 mrg uptr UnsuppressedLeakCount();
110 1.6 mrg uptr IndirectUnsuppressedLeakCount();
111 1.1 mrg
112 1.1 mrg private:
113 1.1 mrg void PrintReportForLeak(uptr index);
114 1.1 mrg void PrintLeakedObjectsForLeak(uptr index);
115 1.1 mrg
116 1.5 mrg u32 next_id_ = 0;
117 1.1 mrg InternalMmapVector<Leak> leaks_;
118 1.1 mrg InternalMmapVector<LeakedObject> leaked_objects_;
119 1.1 mrg };
120 1.1 mrg
121 1.1 mrg typedef InternalMmapVector<uptr> Frontier;
122 1.1 mrg
123 1.1 mrg // Platform-specific functions.
124 1.1 mrg void InitializePlatformSpecificModules();
125 1.1 mrg void ProcessGlobalRegions(Frontier *frontier);
126 1.1 mrg void ProcessPlatformSpecificAllocations(Frontier *frontier);
127 1.4 mrg
128 1.4 mrg struct RootRegion {
129 1.4 mrg uptr begin;
130 1.4 mrg uptr size;
131 1.4 mrg };
132 1.4 mrg
133 1.6 mrg // LockStuffAndStopTheWorld can start to use Scan* calls to collect into
134 1.6 mrg // this Frontier vector before the StopTheWorldCallback actually runs.
135 1.6 mrg // This is used when the OS has a unified callback API for suspending
136 1.6 mrg // threads and enumerating roots.
137 1.6 mrg struct CheckForLeaksParam {
138 1.6 mrg Frontier frontier;
139 1.6 mrg LeakReport leak_report;
140 1.6 mrg bool success = false;
141 1.6 mrg };
142 1.6 mrg
143 1.6 mrg InternalMmapVectorNoCtor<RootRegion> const *GetRootRegions();
144 1.4 mrg void ScanRootRegion(Frontier *frontier, RootRegion const ®ion,
145 1.4 mrg uptr region_begin, uptr region_end, bool is_readable);
146 1.6 mrg void ForEachExtraStackRangeCb(uptr begin, uptr end, void* arg);
147 1.6 mrg void GetAdditionalThreadContextPtrs(ThreadContextBase *tctx, void *ptrs);
148 1.6 mrg // Run stoptheworld while holding any platform-specific locks, as well as the
149 1.6 mrg // allocator and thread registry locks.
150 1.6 mrg void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
151 1.6 mrg CheckForLeaksParam* argument);
152 1.1 mrg
153 1.1 mrg void ScanRangeForPointers(uptr begin, uptr end,
154 1.1 mrg Frontier *frontier,
155 1.1 mrg const char *region_type, ChunkTag tag);
156 1.4 mrg void ScanGlobalRange(uptr begin, uptr end, Frontier *frontier);
157 1.1 mrg
158 1.1 mrg enum IgnoreObjectResult {
159 1.1 mrg kIgnoreObjectSuccess,
160 1.1 mrg kIgnoreObjectAlreadyIgnored,
161 1.1 mrg kIgnoreObjectInvalid
162 1.1 mrg };
163 1.1 mrg
164 1.1 mrg // Functions called from the parent tool.
165 1.4 mrg const char *MaybeCallLsanDefaultOptions();
166 1.3 mrg void InitCommonLsan();
167 1.1 mrg void DoLeakCheck();
168 1.4 mrg void DoRecoverableLeakCheckVoid();
169 1.4 mrg void DisableCounterUnderflow();
170 1.1 mrg bool DisabledInThisThread();
171 1.1 mrg
172 1.3 mrg // Used to implement __lsan::ScopedDisabler.
173 1.3 mrg void DisableInThisThread();
174 1.3 mrg void EnableInThisThread();
175 1.3 mrg // Can be used to ignore memory allocated by an intercepted
176 1.3 mrg // function.
177 1.3 mrg struct ScopedInterceptorDisabler {
178 1.3 mrg ScopedInterceptorDisabler() { DisableInThisThread(); }
179 1.3 mrg ~ScopedInterceptorDisabler() { EnableInThisThread(); }
180 1.3 mrg };
181 1.3 mrg
182 1.4 mrg // According to Itanium C++ ABI array cookie is a one word containing
183 1.4 mrg // size of allocated array.
184 1.4 mrg static inline bool IsItaniumABIArrayCookie(uptr chunk_beg, uptr chunk_size,
185 1.4 mrg uptr addr) {
186 1.4 mrg return chunk_size == sizeof(uptr) && chunk_beg + chunk_size == addr &&
187 1.4 mrg *reinterpret_cast<uptr *>(chunk_beg) == 0;
188 1.4 mrg }
189 1.4 mrg
190 1.4 mrg // According to ARM C++ ABI array cookie consists of two words:
191 1.4 mrg // struct array_cookie {
192 1.4 mrg // std::size_t element_size; // element_size != 0
193 1.4 mrg // std::size_t element_count;
194 1.4 mrg // };
195 1.4 mrg static inline bool IsARMABIArrayCookie(uptr chunk_beg, uptr chunk_size,
196 1.4 mrg uptr addr) {
197 1.4 mrg return chunk_size == 2 * sizeof(uptr) && chunk_beg + chunk_size == addr &&
198 1.4 mrg *reinterpret_cast<uptr *>(chunk_beg + sizeof(uptr)) == 0;
199 1.4 mrg }
200 1.4 mrg
201 1.1 mrg // Special case for "new T[0]" where T is a type with DTOR.
202 1.4 mrg // new T[0] will allocate a cookie (one or two words) for the array size (0)
203 1.4 mrg // and store a pointer to the end of allocated chunk. The actual cookie layout
204 1.4 mrg // varies between platforms according to their C++ ABI implementation.
205 1.1 mrg inline bool IsSpecialCaseOfOperatorNew0(uptr chunk_beg, uptr chunk_size,
206 1.1 mrg uptr addr) {
207 1.4 mrg #if defined(__arm__)
208 1.4 mrg return IsARMABIArrayCookie(chunk_beg, chunk_size, addr);
209 1.4 mrg #else
210 1.4 mrg return IsItaniumABIArrayCookie(chunk_beg, chunk_size, addr);
211 1.4 mrg #endif
212 1.1 mrg }
213 1.1 mrg
214 1.1 mrg // The following must be implemented in the parent tool.
215 1.1 mrg
216 1.1 mrg void ForEachChunk(ForEachChunkCallback callback, void *arg);
217 1.1 mrg // Returns the address range occupied by the global allocator object.
218 1.1 mrg void GetAllocatorGlobalRange(uptr *begin, uptr *end);
219 1.1 mrg // Wrappers for allocator's ForceLock()/ForceUnlock().
220 1.1 mrg void LockAllocator();
221 1.1 mrg void UnlockAllocator();
222 1.1 mrg // Returns true if [addr, addr + sizeof(void *)) is poisoned.
223 1.1 mrg bool WordIsPoisoned(uptr addr);
224 1.1 mrg // Wrappers for ThreadRegistry access.
225 1.6 mrg void LockThreadRegistry() NO_THREAD_SAFETY_ANALYSIS;
226 1.6 mrg void UnlockThreadRegistry() NO_THREAD_SAFETY_ANALYSIS;
227 1.5 mrg ThreadRegistry *GetThreadRegistryLocked();
228 1.4 mrg bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end,
229 1.3 mrg uptr *tls_begin, uptr *tls_end, uptr *cache_begin,
230 1.3 mrg uptr *cache_end, DTLS **dtls);
231 1.6 mrg void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches);
232 1.4 mrg void ForEachExtraStackRange(tid_t os_id, RangeIteratorCallback callback,
233 1.1 mrg void *arg);
234 1.1 mrg // If called from the main thread, updates the main thread's TID in the thread
235 1.1 mrg // registry. We need this to handle processes that fork() without a subsequent
236 1.1 mrg // exec(), which invalidates the recorded TID. To update it, we must call
237 1.1 mrg // gettid() from the main thread. Our solution is to call this function before
238 1.1 mrg // leak checking and also before every call to pthread_create() (to handle cases
239 1.1 mrg // where leak checking is initiated from a non-main thread).
240 1.1 mrg void EnsureMainThreadIDIsCorrect();
241 1.1 mrg // If p points into a chunk that has been allocated to the user, returns its
242 1.1 mrg // user-visible address. Otherwise, returns 0.
243 1.1 mrg uptr PointsIntoChunk(void *p);
244 1.1 mrg // Returns address of user-visible chunk contained in this allocator chunk.
245 1.1 mrg uptr GetUserBegin(uptr chunk);
246 1.1 mrg // Helper for __lsan_ignore_object().
247 1.1 mrg IgnoreObjectResult IgnoreObjectLocked(const void *p);
248 1.4 mrg
249 1.4 mrg // Return the linker module, if valid for the platform.
250 1.4 mrg LoadedModule *GetLinker();
251 1.4 mrg
252 1.4 mrg // Return true if LSan has finished leak checking and reported leaks.
253 1.4 mrg bool HasReportedLeaks();
254 1.4 mrg
255 1.4 mrg // Run platform-specific leak handlers.
256 1.4 mrg void HandleLeaks();
257 1.4 mrg
258 1.1 mrg // Wrapper for chunk metadata operations.
259 1.1 mrg class LsanMetadata {
260 1.1 mrg public:
261 1.1 mrg // Constructor accepts address of user-visible chunk.
262 1.1 mrg explicit LsanMetadata(uptr chunk);
263 1.1 mrg bool allocated() const;
264 1.1 mrg ChunkTag tag() const;
265 1.1 mrg void set_tag(ChunkTag value);
266 1.1 mrg uptr requested_size() const;
267 1.1 mrg u32 stack_trace_id() const;
268 1.1 mrg private:
269 1.1 mrg void *metadata_;
270 1.1 mrg };
271 1.1 mrg
272 1.1 mrg } // namespace __lsan
273 1.1 mrg
274 1.1 mrg extern "C" {
275 1.1 mrg SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
276 1.4 mrg const char *__lsan_default_options();
277 1.4 mrg
278 1.4 mrg SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
279 1.1 mrg int __lsan_is_turned_off();
280 1.1 mrg
281 1.1 mrg SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
282 1.1 mrg const char *__lsan_default_suppressions();
283 1.6 mrg
284 1.6 mrg SANITIZER_INTERFACE_ATTRIBUTE
285 1.6 mrg void __lsan_register_root_region(const void *p, __lsan::uptr size);
286 1.6 mrg
287 1.6 mrg SANITIZER_INTERFACE_ATTRIBUTE
288 1.6 mrg void __lsan_unregister_root_region(const void *p, __lsan::uptr size);
289 1.6 mrg
290 1.1 mrg } // extern "C"
291 1.1 mrg
292 1.1 mrg #endif // LSAN_COMMON_H
293