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
);
116 //// --------------------------------------------------------------------------
117 //// Allocator prototypes.
118 //// --------------------------------------------------------------------------
120 // Wrappers for allocator's ForceLock()/ForceUnlock().
121 void LockAllocator();
122 void UnlockAllocator();
124 // Lock/unlock global mutext.
128 // Returns the address range occupied by the global allocator object.
129 void GetAllocatorGlobalRange(uptr
*begin
, uptr
*end
);
130 // If p points into a chunk that has been allocated to the user, returns its
131 // user-visible address. Otherwise, returns 0.
132 uptr
PointsIntoChunk(void *p
);
133 // Returns address of user-visible chunk contained in this allocator chunk.
134 uptr
GetUserBegin(uptr chunk
);
135 // Returns user-visible address for chunk. If memory tagging is used this
136 // function will return the tagged address.
137 uptr
GetUserAddr(uptr chunk
);
139 // Wrapper for chunk metadata operations.
142 // Constructor accepts address of user-visible chunk.
143 explicit LsanMetadata(uptr chunk
);
144 bool allocated() const;
145 ChunkTag
tag() const;
146 void set_tag(ChunkTag value
);
147 uptr
requested_size() const;
148 u32
stack_trace_id() const;
154 // Iterate over all existing chunks. Allocator must be locked.
155 void ForEachChunk(ForEachChunkCallback callback
, void *arg
);
157 // Helper for __lsan_ignore_object().
158 IgnoreObjectResult
IgnoreObject(const void *p
);
160 // The rest of the LSan interface which is implemented by library.
162 struct ScopedStopTheWorldLock
{
163 ScopedStopTheWorldLock() {
168 ~ScopedStopTheWorldLock() {
173 ScopedStopTheWorldLock
&operator=(const ScopedStopTheWorldLock
&) = delete;
174 ScopedStopTheWorldLock(const ScopedStopTheWorldLock
&) = delete;
178 #define LSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;
179 #include "lsan_flags.inc"
183 uptr
pointer_alignment() const {
184 return use_unaligned
? 1 : sizeof(uptr
);
188 extern Flags lsan_flags
;
189 inline Flags
*flags() { return &lsan_flags
; }
190 void RegisterLsanFlags(FlagParser
*parser
, Flags
*f
);
199 using LeakedChunks
= InternalMmapVector
<LeakedChunk
>;
206 bool is_directly_leaked
;
210 struct LeakedObject
{
216 // Aggregates leaks by stack trace prefix.
220 void AddLeakedChunks(const LeakedChunks
&chunks
);
221 void ReportTopLeaks(uptr max_leaks
);
223 uptr
ApplySuppressions();
224 uptr
UnsuppressedLeakCount();
225 uptr
IndirectUnsuppressedLeakCount();
228 void PrintReportForLeak(uptr index
);
229 void PrintLeakedObjectsForLeak(uptr index
);
232 InternalMmapVector
<Leak
> leaks_
;
233 InternalMmapVector
<LeakedObject
> leaked_objects_
;
236 typedef InternalMmapVector
<uptr
> Frontier
;
238 // Platform-specific functions.
239 void InitializePlatformSpecificModules();
240 void ProcessGlobalRegions(Frontier
*frontier
);
241 void ProcessPlatformSpecificAllocations(Frontier
*frontier
);
243 // LockStuffAndStopTheWorld can start to use Scan* calls to collect into
244 // this Frontier vector before the StopTheWorldCallback actually runs.
245 // This is used when the OS has a unified callback API for suspending
246 // threads and enumerating roots.
247 struct CheckForLeaksParam
{
252 bool success
= false;
255 using Region
= Range
;
257 bool HasRootRegions();
258 void ScanRootRegions(Frontier
*frontier
,
259 const InternalMmapVectorNoCtor
<Region
> ®ion
);
260 // Run stoptheworld while holding any platform-specific locks, as well as the
261 // allocator and thread registry locks.
262 void LockStuffAndStopTheWorld(StopTheWorldCallback callback
,
263 CheckForLeaksParam
* argument
);
265 void ScanRangeForPointers(uptr begin
, uptr end
,
267 const char *region_type
, ChunkTag tag
);
268 void ScanGlobalRange(uptr begin
, uptr end
, Frontier
*frontier
);
269 void ScanExtraStackRanges(const InternalMmapVector
<Range
> &ranges
,
272 // Functions called from the parent tool.
273 const char *MaybeCallLsanDefaultOptions();
274 void InitCommonLsan();
276 void DoRecoverableLeakCheckVoid();
277 void DisableCounterUnderflow();
278 bool DisabledInThisThread();
280 // Used to implement __lsan::ScopedDisabler.
281 void DisableInThisThread();
282 void EnableInThisThread();
283 // Can be used to ignore memory allocated by an intercepted
285 struct ScopedInterceptorDisabler
{
286 ScopedInterceptorDisabler() { DisableInThisThread(); }
287 ~ScopedInterceptorDisabler() { EnableInThisThread(); }
290 // According to Itanium C++ ABI array cookie is a one word containing
291 // size of allocated array.
292 static inline bool IsItaniumABIArrayCookie(uptr chunk_beg
, uptr chunk_size
,
294 return chunk_size
== sizeof(uptr
) && chunk_beg
+ chunk_size
== addr
&&
295 *reinterpret_cast<uptr
*>(chunk_beg
) == 0;
298 // According to ARM C++ ABI array cookie consists of two words:
299 // struct array_cookie {
300 // std::size_t element_size; // element_size != 0
301 // std::size_t element_count;
303 static inline bool IsARMABIArrayCookie(uptr chunk_beg
, uptr chunk_size
,
305 return chunk_size
== 2 * sizeof(uptr
) && chunk_beg
+ chunk_size
== addr
&&
306 *reinterpret_cast<uptr
*>(chunk_beg
+ sizeof(uptr
)) == 0;
309 // Special case for "new T[0]" where T is a type with DTOR.
310 // new T[0] will allocate a cookie (one or two words) for the array size (0)
311 // and store a pointer to the end of allocated chunk. The actual cookie layout
312 // varies between platforms according to their C++ ABI implementation.
313 inline bool IsSpecialCaseOfOperatorNew0(uptr chunk_beg
, uptr chunk_size
,
316 return IsARMABIArrayCookie(chunk_beg
, chunk_size
, addr
);
318 return IsItaniumABIArrayCookie(chunk_beg
, chunk_size
, addr
);
322 // Return the linker module, if valid for the platform.
323 LoadedModule
*GetLinker();
325 // Return true if LSan has finished leak checking and reported leaks.
326 bool HasReportedLeaks();
328 // Run platform-specific leak handlers.
331 } // namespace __lsan
334 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
335 const char *__lsan_default_options();
337 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
338 int __lsan_is_turned_off();
340 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
341 const char *__lsan_default_suppressions();
343 SANITIZER_INTERFACE_ATTRIBUTE
344 void __lsan_register_root_region(const void *p
, __lsan::uptr size
);
346 SANITIZER_INTERFACE_ATTRIBUTE
347 void __lsan_unregister_root_region(const void *p
, __lsan::uptr size
);
351 #endif // LSAN_COMMON_H