1 //=-- lsan_common.h -------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of LeakSanitizer.
10 // Private LSan header.
12 //===----------------------------------------------------------------------===//
17 #include "sanitizer_common/sanitizer_allocator.h"
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_range.h"
22 #include "sanitizer_common/sanitizer_stackdepot.h"
23 #include "sanitizer_common/sanitizer_stoptheworld.h"
24 #include "sanitizer_common/sanitizer_symbolizer.h"
25 #include "sanitizer_common/sanitizer_thread_registry.h"
27 // LeakSanitizer relies on some Glibc's internals (e.g. TLS machinery) on Linux.
28 // Also, LSan doesn't like 32 bit architectures
29 // because of "small" (4 bytes) pointer size that leads to high false negative
30 // ratio on large leaks. But we still want to have it for some 32 bit arches
31 // (e.g. x86), see https://github.com/google/sanitizers/issues/403.
32 // To enable LeakSanitizer on a new architecture, one needs to implement the
33 // internal_clone function as well as (probably) adjust the TLS machinery for
34 // the new architecture inside the sanitizer library.
35 // Exclude leak-detection on arm32 for Android because `__aeabi_read_tp`
36 // is missing. This caused a link error.
37 #if SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__))
38 # define CAN_SANITIZE_LEAKS 0
39 #elif (SANITIZER_LINUX || SANITIZER_APPLE) && (SANITIZER_WORDSIZE == 64) && \
40 (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \
41 defined(__powerpc64__) || defined(__s390x__))
42 # define CAN_SANITIZE_LEAKS 1
43 #elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_APPLE)
44 # define CAN_SANITIZE_LEAKS 1
45 #elif defined(__arm__) && SANITIZER_LINUX
46 # define CAN_SANITIZE_LEAKS 1
47 #elif SANITIZER_LOONGARCH64 && SANITIZER_LINUX
48 # define CAN_SANITIZE_LEAKS 1
49 #elif SANITIZER_RISCV64 && SANITIZER_LINUX
50 # define CAN_SANITIZE_LEAKS 1
51 #elif SANITIZER_NETBSD || SANITIZER_FUCHSIA
52 # define CAN_SANITIZE_LEAKS 1
54 # define CAN_SANITIZE_LEAKS 0
57 namespace __sanitizer
{
60 class ThreadContextBase
;
64 // This section defines function and class prototypes which must be implemented
65 // by the parent tool linking in LSan. There are implementations provided by the
66 // LSan library which will be linked in when LSan is used as a standalone tool.
71 kDirectlyLeaked
= 0, // default
72 kIndirectlyLeaked
= 1,
77 enum IgnoreObjectResult
{
79 kIgnoreObjectAlreadyIgnored
,
83 //// --------------------------------------------------------------------------
84 //// Poisoning prototypes.
85 //// --------------------------------------------------------------------------
87 // Returns true if [addr, addr + sizeof(void *)) is poisoned.
88 bool WordIsPoisoned(uptr addr
);
90 //// --------------------------------------------------------------------------
91 //// Thread prototypes.
92 //// --------------------------------------------------------------------------
94 // Wrappers for ThreadRegistry access.
95 void LockThreads() SANITIZER_NO_THREAD_SAFETY_ANALYSIS
;
96 void UnlockThreads() SANITIZER_NO_THREAD_SAFETY_ANALYSIS
;
97 // If called from the main thread, updates the main thread's TID in the thread
98 // registry. We need this to handle processes that fork() without a subsequent
99 // exec(), which invalidates the recorded TID. To update it, we must call
100 // gettid() from the main thread. Our solution is to call this function before
101 // leak checking and also before every call to pthread_create() (to handle cases
102 // where leak checking is initiated from a non-main thread).
103 void EnsureMainThreadIDIsCorrect();
105 bool GetThreadRangesLocked(tid_t os_id
, uptr
*stack_begin
, uptr
*stack_end
,
106 uptr
*tls_begin
, uptr
*tls_end
, uptr
*cache_begin
,
107 uptr
*cache_end
, DTLS
**dtls
);
108 void GetAllThreadAllocatorCachesLocked(InternalMmapVector
<uptr
> *caches
);
109 void GetThreadExtraStackRangesLocked(InternalMmapVector
<Range
> *ranges
);
110 void GetThreadExtraStackRangesLocked(tid_t os_id
,
111 InternalMmapVector
<Range
> *ranges
);
112 void GetAdditionalThreadContextPtrsLocked(InternalMmapVector
<uptr
> *ptrs
);
113 void GetRunningThreadsLocked(InternalMmapVector
<tid_t
> *threads
);
115 //// --------------------------------------------------------------------------
116 //// Allocator prototypes.
117 //// --------------------------------------------------------------------------
119 // Wrappers for allocator's ForceLock()/ForceUnlock().
120 void LockAllocator();
121 void UnlockAllocator();
123 // Returns the address range occupied by the global allocator object.
124 void GetAllocatorGlobalRange(uptr
*begin
, uptr
*end
);
125 // If p points into a chunk that has been allocated to the user, returns its
126 // user-visible address. Otherwise, returns 0.
127 uptr
PointsIntoChunk(void *p
);
128 // Returns address of user-visible chunk contained in this allocator chunk.
129 uptr
GetUserBegin(uptr chunk
);
130 // Returns user-visible address for chunk. If memory tagging is used this
131 // function will return the tagged address.
132 uptr
GetUserAddr(uptr chunk
);
134 // Wrapper for chunk metadata operations.
137 // Constructor accepts address of user-visible chunk.
138 explicit LsanMetadata(uptr chunk
);
139 bool allocated() const;
140 ChunkTag
tag() const;
141 void set_tag(ChunkTag value
);
142 uptr
requested_size() const;
143 u32
stack_trace_id() const;
149 // Iterate over all existing chunks. Allocator must be locked.
150 void ForEachChunk(ForEachChunkCallback callback
, void *arg
);
152 // Helper for __lsan_ignore_object().
153 IgnoreObjectResult
IgnoreObject(const void *p
);
155 // The rest of the LSan interface which is implemented by library.
157 struct ScopedStopTheWorldLock
{
158 ScopedStopTheWorldLock() {
163 ~ScopedStopTheWorldLock() {
168 ScopedStopTheWorldLock
&operator=(const ScopedStopTheWorldLock
&) = delete;
169 ScopedStopTheWorldLock(const ScopedStopTheWorldLock
&) = delete;
173 #define LSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;
174 #include "lsan_flags.inc"
178 uptr
pointer_alignment() const {
179 return use_unaligned
? 1 : sizeof(uptr
);
183 extern Flags lsan_flags
;
184 inline Flags
*flags() { return &lsan_flags
; }
185 void RegisterLsanFlags(FlagParser
*parser
, Flags
*f
);
194 using LeakedChunks
= InternalMmapVector
<LeakedChunk
>;
201 bool is_directly_leaked
;
205 struct LeakedObject
{
211 // Aggregates leaks by stack trace prefix.
215 void AddLeakedChunks(const LeakedChunks
&chunks
);
216 void ReportTopLeaks(uptr max_leaks
);
218 uptr
ApplySuppressions();
219 uptr
UnsuppressedLeakCount();
220 uptr
IndirectUnsuppressedLeakCount();
223 void PrintReportForLeak(uptr index
);
224 void PrintLeakedObjectsForLeak(uptr index
);
227 InternalMmapVector
<Leak
> leaks_
;
228 InternalMmapVector
<LeakedObject
> leaked_objects_
;
231 typedef InternalMmapVector
<uptr
> Frontier
;
233 // Platform-specific functions.
234 void InitializePlatformSpecificModules();
235 void ProcessGlobalRegions(Frontier
*frontier
);
236 void ProcessPlatformSpecificAllocations(Frontier
*frontier
);
238 // LockStuffAndStopTheWorld can start to use Scan* calls to collect into
239 // this Frontier vector before the StopTheWorldCallback actually runs.
240 // This is used when the OS has a unified callback API for suspending
241 // threads and enumerating roots.
242 struct CheckForLeaksParam
{
247 bool success
= false;
250 using Region
= Range
;
252 bool HasRootRegions();
253 void ScanRootRegions(Frontier
*frontier
,
254 const InternalMmapVectorNoCtor
<Region
> ®ion
);
255 // Run stoptheworld while holding any platform-specific locks, as well as the
256 // allocator and thread registry locks.
257 void LockStuffAndStopTheWorld(StopTheWorldCallback callback
,
258 CheckForLeaksParam
* argument
);
260 void ScanRangeForPointers(uptr begin
, uptr end
,
262 const char *region_type
, ChunkTag tag
);
263 void ScanGlobalRange(uptr begin
, uptr end
, Frontier
*frontier
);
264 void ScanExtraStackRanges(const InternalMmapVector
<Range
> &ranges
,
267 // Functions called from the parent tool.
268 const char *MaybeCallLsanDefaultOptions();
269 void InitCommonLsan();
271 void DoRecoverableLeakCheckVoid();
272 void DisableCounterUnderflow();
273 bool DisabledInThisThread();
275 // Used to implement __lsan::ScopedDisabler.
276 void DisableInThisThread();
277 void EnableInThisThread();
278 // Can be used to ignore memory allocated by an intercepted
280 struct ScopedInterceptorDisabler
{
281 ScopedInterceptorDisabler() { DisableInThisThread(); }
282 ~ScopedInterceptorDisabler() { EnableInThisThread(); }
285 // According to Itanium C++ ABI array cookie is a one word containing
286 // size of allocated array.
287 static inline bool IsItaniumABIArrayCookie(uptr chunk_beg
, uptr chunk_size
,
289 return chunk_size
== sizeof(uptr
) && chunk_beg
+ chunk_size
== addr
&&
290 *reinterpret_cast<uptr
*>(chunk_beg
) == 0;
293 // According to ARM C++ ABI array cookie consists of two words:
294 // struct array_cookie {
295 // std::size_t element_size; // element_size != 0
296 // std::size_t element_count;
298 static inline bool IsARMABIArrayCookie(uptr chunk_beg
, uptr chunk_size
,
300 return chunk_size
== 2 * sizeof(uptr
) && chunk_beg
+ chunk_size
== addr
&&
301 *reinterpret_cast<uptr
*>(chunk_beg
+ sizeof(uptr
)) == 0;
304 // Special case for "new T[0]" where T is a type with DTOR.
305 // new T[0] will allocate a cookie (one or two words) for the array size (0)
306 // and store a pointer to the end of allocated chunk. The actual cookie layout
307 // varies between platforms according to their C++ ABI implementation.
308 inline bool IsSpecialCaseOfOperatorNew0(uptr chunk_beg
, uptr chunk_size
,
311 return IsARMABIArrayCookie(chunk_beg
, chunk_size
, addr
);
313 return IsItaniumABIArrayCookie(chunk_beg
, chunk_size
, addr
);
317 // Return the linker module, if valid for the platform.
318 LoadedModule
*GetLinker();
320 // Return true if LSan has finished leak checking and reported leaks.
321 bool HasReportedLeaks();
323 // Run platform-specific leak handlers.
326 } // namespace __lsan
329 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
330 const char *__lsan_default_options();
332 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
333 int __lsan_is_turned_off();
335 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
336 const char *__lsan_default_suppressions();
338 SANITIZER_INTERFACE_ATTRIBUTE
339 void __lsan_register_root_region(const void *p
, __lsan::uptr size
);
341 SANITIZER_INTERFACE_ATTRIBUTE
342 void __lsan_unregister_root_region(const void *p
, __lsan::uptr size
);
346 #endif // LSAN_COMMON_H