lsan_common.h 10 KB

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