lsan_common.h 12 KB

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