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_stackdepot.h"
  20. #include "sanitizer_common/sanitizer_stoptheworld.h"
  21. #include "sanitizer_common/sanitizer_symbolizer.h"
  22. #include "sanitizer_common/sanitizer_thread_registry.h"
  23. // LeakSanitizer relies on some Glibc's internals (e.g. TLS machinery) on Linux.
  24. // Also, LSan doesn't like 32 bit architectures
  25. // because of "small" (4 bytes) pointer size that leads to high false negative
  26. // ratio on large leaks. But we still want to have it for some 32 bit arches
  27. // (e.g. x86), see https://github.com/google/sanitizers/issues/403.
  28. // To enable LeakSanitizer on a new architecture, one needs to implement the
  29. // internal_clone function as well as (probably) adjust the TLS machinery for
  30. // the new architecture inside the sanitizer library.
  31. // Exclude leak-detection on arm32 for Android because `__aeabi_read_tp`
  32. // is missing. This caused a link error.
  33. #if SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__))
  34. # define CAN_SANITIZE_LEAKS 0
  35. #elif (SANITIZER_LINUX || SANITIZER_APPLE) && (SANITIZER_WORDSIZE == 64) && \
  36. (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \
  37. defined(__powerpc64__) || defined(__s390x__))
  38. # define CAN_SANITIZE_LEAKS 1
  39. #elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_APPLE)
  40. # define CAN_SANITIZE_LEAKS 1
  41. #elif defined(__arm__) && SANITIZER_LINUX
  42. # define CAN_SANITIZE_LEAKS 1
  43. #elif SANITIZER_LOONGARCH64 && SANITIZER_LINUX
  44. # define CAN_SANITIZE_LEAKS 1
  45. #elif SANITIZER_RISCV64 && SANITIZER_LINUX
  46. # define CAN_SANITIZE_LEAKS 1
  47. #elif SANITIZER_NETBSD || SANITIZER_FUCHSIA
  48. # define CAN_SANITIZE_LEAKS 1
  49. #else
  50. # define CAN_SANITIZE_LEAKS 0
  51. #endif
  52. namespace __sanitizer {
  53. class FlagParser;
  54. class ThreadRegistry;
  55. class ThreadContextBase;
  56. struct DTLS;
  57. }
  58. // This section defines function and class prototypes which must be implemented
  59. // by the parent tool linking in LSan. There are implementations provided by the
  60. // LSan library which will be linked in when LSan is used as a standalone tool.
  61. namespace __lsan {
  62. // Chunk tags.
  63. enum ChunkTag {
  64. kDirectlyLeaked = 0, // default
  65. kIndirectlyLeaked = 1,
  66. kReachable = 2,
  67. kIgnored = 3
  68. };
  69. enum IgnoreObjectResult {
  70. kIgnoreObjectSuccess,
  71. kIgnoreObjectAlreadyIgnored,
  72. kIgnoreObjectInvalid
  73. };
  74. struct Range {
  75. uptr begin;
  76. uptr end;
  77. };
  78. //// --------------------------------------------------------------------------
  79. //// Poisoning prototypes.
  80. //// --------------------------------------------------------------------------
  81. // Returns true if [addr, addr + sizeof(void *)) is poisoned.
  82. bool WordIsPoisoned(uptr addr);
  83. //// --------------------------------------------------------------------------
  84. //// Thread prototypes.
  85. //// --------------------------------------------------------------------------
  86. // Wrappers for ThreadRegistry access.
  87. void LockThreadRegistry() SANITIZER_NO_THREAD_SAFETY_ANALYSIS;
  88. void UnlockThreadRegistry() SANITIZER_NO_THREAD_SAFETY_ANALYSIS;
  89. // If called from the main thread, updates the main thread's TID in the thread
  90. // registry. We need this to handle processes that fork() without a subsequent
  91. // exec(), which invalidates the recorded TID. To update it, we must call
  92. // gettid() from the main thread. Our solution is to call this function before
  93. // leak checking and also before every call to pthread_create() (to handle cases
  94. // where leak checking is initiated from a non-main thread).
  95. void EnsureMainThreadIDIsCorrect();
  96. bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end,
  97. uptr *tls_begin, uptr *tls_end, uptr *cache_begin,
  98. uptr *cache_end, DTLS **dtls);
  99. void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches);
  100. void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges);
  101. void GetThreadExtraStackRangesLocked(tid_t os_id,
  102. InternalMmapVector<Range> *ranges);
  103. void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs);
  104. void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads);
  105. //// --------------------------------------------------------------------------
  106. //// Allocator prototypes.
  107. //// --------------------------------------------------------------------------
  108. // Wrappers for allocator's ForceLock()/ForceUnlock().
  109. void LockAllocator();
  110. void UnlockAllocator();
  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. // Wrapper for chunk metadata operations.
  119. class LsanMetadata {
  120. public:
  121. // Constructor accepts address of user-visible chunk.
  122. explicit LsanMetadata(uptr chunk);
  123. bool allocated() const;
  124. ChunkTag tag() const;
  125. void set_tag(ChunkTag value);
  126. uptr requested_size() const;
  127. u32 stack_trace_id() const;
  128. private:
  129. void *metadata_;
  130. };
  131. // Iterate over all existing chunks. Allocator must be locked.
  132. void ForEachChunk(ForEachChunkCallback callback, void *arg);
  133. // Helper for __lsan_ignore_object().
  134. IgnoreObjectResult IgnoreObjectLocked(const void *p);
  135. // The rest of the LSan interface which is implemented by library.
  136. struct ScopedStopTheWorldLock {
  137. ScopedStopTheWorldLock() {
  138. LockThreadRegistry();
  139. LockAllocator();
  140. }
  141. ~ScopedStopTheWorldLock() {
  142. UnlockAllocator();
  143. UnlockThreadRegistry();
  144. }
  145. ScopedStopTheWorldLock &operator=(const ScopedStopTheWorldLock &) = delete;
  146. ScopedStopTheWorldLock(const ScopedStopTheWorldLock &) = delete;
  147. };
  148. struct Flags {
  149. #define LSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;
  150. #include "lsan_flags.inc"
  151. #undef LSAN_FLAG
  152. void SetDefaults();
  153. uptr pointer_alignment() const {
  154. return use_unaligned ? 1 : sizeof(uptr);
  155. }
  156. };
  157. extern Flags lsan_flags;
  158. inline Flags *flags() { return &lsan_flags; }
  159. void RegisterLsanFlags(FlagParser *parser, Flags *f);
  160. struct LeakedChunk {
  161. uptr chunk;
  162. u32 stack_trace_id;
  163. uptr leaked_size;
  164. ChunkTag tag;
  165. };
  166. using LeakedChunks = InternalMmapVector<LeakedChunk>;
  167. struct Leak {
  168. u32 id;
  169. uptr hit_count;
  170. uptr total_size;
  171. u32 stack_trace_id;
  172. bool is_directly_leaked;
  173. bool is_suppressed;
  174. };
  175. struct LeakedObject {
  176. u32 leak_id;
  177. uptr addr;
  178. uptr size;
  179. };
  180. // Aggregates leaks by stack trace prefix.
  181. class LeakReport {
  182. public:
  183. LeakReport() {}
  184. void AddLeakedChunks(const LeakedChunks &chunks);
  185. void ReportTopLeaks(uptr max_leaks);
  186. void PrintSummary();
  187. uptr ApplySuppressions();
  188. uptr UnsuppressedLeakCount();
  189. uptr IndirectUnsuppressedLeakCount();
  190. private:
  191. void PrintReportForLeak(uptr index);
  192. void PrintLeakedObjectsForLeak(uptr index);
  193. u32 next_id_ = 0;
  194. InternalMmapVector<Leak> leaks_;
  195. InternalMmapVector<LeakedObject> leaked_objects_;
  196. };
  197. typedef InternalMmapVector<uptr> Frontier;
  198. // Platform-specific functions.
  199. void InitializePlatformSpecificModules();
  200. void ProcessGlobalRegions(Frontier *frontier);
  201. void ProcessPlatformSpecificAllocations(Frontier *frontier);
  202. struct RootRegion {
  203. uptr begin;
  204. uptr size;
  205. };
  206. // LockStuffAndStopTheWorld can start to use Scan* calls to collect into
  207. // this Frontier vector before the StopTheWorldCallback actually runs.
  208. // This is used when the OS has a unified callback API for suspending
  209. // threads and enumerating roots.
  210. struct CheckForLeaksParam {
  211. Frontier frontier;
  212. LeakedChunks leaks;
  213. tid_t caller_tid;
  214. uptr caller_sp;
  215. bool success = false;
  216. };
  217. InternalMmapVectorNoCtor<RootRegion> const *GetRootRegions();
  218. void ScanRootRegion(Frontier *frontier, RootRegion const &region,
  219. uptr region_begin, uptr region_end, bool is_readable);
  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