Home | History | Annotate | Download | only in lsan
      1 //=-- lsan_common.h -------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of LeakSanitizer.
     11 // Private LSan header.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LSAN_COMMON_H
     16 #define LSAN_COMMON_H
     17 
     18 #include "sanitizer_common/sanitizer_allocator.h"
     19 #include "sanitizer_common/sanitizer_common.h"
     20 #include "sanitizer_common/sanitizer_internal_defs.h"
     21 #include "sanitizer_common/sanitizer_platform.h"
     22 #include "sanitizer_common/sanitizer_symbolizer.h"
     23 
     24 #if SANITIZER_LINUX && defined(__x86_64__)
     25 #define CAN_SANITIZE_LEAKS 1
     26 #else
     27 #define CAN_SANITIZE_LEAKS 0
     28 #endif
     29 
     30 namespace __lsan {
     31 
     32 // Chunk tags.
     33 enum ChunkTag {
     34   kDirectlyLeaked = 0,  // default
     35   kIndirectlyLeaked = 1,
     36   kReachable = 2,
     37   kIgnored = 3
     38 };
     39 
     40 struct Flags {
     41   uptr pointer_alignment() const {
     42     return use_unaligned ? 1 : sizeof(uptr);
     43   }
     44 
     45   // Print addresses of leaked objects after main leak report.
     46   bool report_objects;
     47   // Aggregate two objects into one leak if this many stack frames match. If
     48   // zero, the entire stack trace must match.
     49   int resolution;
     50   // The number of leaks reported.
     51   int max_leaks;
     52   // If nonzero kill the process with this exit code upon finding leaks.
     53   int exitcode;
     54   // Suppressions file name.
     55   const char* suppressions;
     56 
     57   // Flags controlling the root set of reachable memory.
     58   // Global variables (.data and .bss).
     59   bool use_globals;
     60   // Thread stacks.
     61   bool use_stacks;
     62   // Thread registers.
     63   bool use_registers;
     64   // TLS and thread-specific storage.
     65   bool use_tls;
     66 
     67   // Consider unaligned pointers valid.
     68   bool use_unaligned;
     69 
     70   // User-visible verbosity.
     71   int verbosity;
     72 
     73   // Debug logging.
     74   bool log_pointers;
     75   bool log_threads;
     76 };
     77 
     78 extern Flags lsan_flags;
     79 inline Flags *flags() { return &lsan_flags; }
     80 
     81 struct Leak {
     82   uptr hit_count;
     83   uptr total_size;
     84   u32 stack_trace_id;
     85   bool is_directly_leaked;
     86   bool is_suppressed;
     87 };
     88 
     89 // Aggregates leaks by stack trace prefix.
     90 class LeakReport {
     91  public:
     92   LeakReport() : leaks_(1) {}
     93   void Add(u32 stack_trace_id, uptr leaked_size, ChunkTag tag);
     94   void PrintLargest(uptr max_leaks);
     95   void PrintSummary();
     96   bool IsEmpty() { return leaks_.size() == 0; }
     97   uptr ApplySuppressions();
     98  private:
     99   InternalMmapVector<Leak> leaks_;
    100 };
    101 
    102 typedef InternalMmapVector<uptr> Frontier;
    103 
    104 // Platform-specific functions.
    105 void InitializePlatformSpecificModules();
    106 void ProcessGlobalRegions(Frontier *frontier);
    107 void ProcessPlatformSpecificAllocations(Frontier *frontier);
    108 
    109 void ScanRangeForPointers(uptr begin, uptr end,
    110                           Frontier *frontier,
    111                           const char *region_type, ChunkTag tag);
    112 
    113 enum IgnoreObjectResult {
    114   kIgnoreObjectSuccess,
    115   kIgnoreObjectAlreadyIgnored,
    116   kIgnoreObjectInvalid
    117 };
    118 
    119 // Functions called from the parent tool.
    120 void InitCommonLsan();
    121 void DoLeakCheck();
    122 bool DisabledInThisThread();
    123 
    124 // The following must be implemented in the parent tool.
    125 
    126 void ForEachChunk(ForEachChunkCallback callback, void *arg);
    127 // Returns the address range occupied by the global allocator object.
    128 void GetAllocatorGlobalRange(uptr *begin, uptr *end);
    129 // Wrappers for allocator's ForceLock()/ForceUnlock().
    130 void LockAllocator();
    131 void UnlockAllocator();
    132 // Wrappers for ThreadRegistry access.
    133 void LockThreadRegistry();
    134 void UnlockThreadRegistry();
    135 bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,
    136                            uptr *tls_begin, uptr *tls_end,
    137                            uptr *cache_begin, uptr *cache_end);
    138 // If called from the main thread, updates the main thread's TID in the thread
    139 // registry. We need this to handle processes that fork() without a subsequent
    140 // exec(), which invalidates the recorded TID. To update it, we must call
    141 // gettid() from the main thread. Our solution is to call this function before
    142 // leak checking and also before every call to pthread_create() (to handle cases
    143 // where leak checking is initiated from a non-main thread).
    144 void EnsureMainThreadIDIsCorrect();
    145 // If p points into a chunk that has been allocated to the user, returns its
    146 // user-visible address. Otherwise, returns 0.
    147 uptr PointsIntoChunk(void *p);
    148 // Returns address of user-visible chunk contained in this allocator chunk.
    149 uptr GetUserBegin(uptr chunk);
    150 // Helper for __lsan_ignore_object().
    151 IgnoreObjectResult IgnoreObjectLocked(const void *p);
    152 // Wrapper for chunk metadata operations.
    153 class LsanMetadata {
    154  public:
    155   // Constructor accepts address of user-visible chunk.
    156   explicit LsanMetadata(uptr chunk);
    157   bool allocated() const;
    158   ChunkTag tag() const;
    159   void set_tag(ChunkTag value);
    160   uptr requested_size() const;
    161   u32 stack_trace_id() const;
    162  private:
    163   void *metadata_;
    164 };
    165 
    166 }  // namespace __lsan
    167 
    168 extern "C" {
    169 int __lsan_is_turned_off() SANITIZER_WEAK_ATTRIBUTE
    170     SANITIZER_INTERFACE_ATTRIBUTE;
    171 const char *__lsan_default_suppressions() SANITIZER_WEAK_ATTRIBUTE
    172     SANITIZER_INTERFACE_ATTRIBUTE;
    173 }  // extern "C"
    174 
    175 #endif  // LSAN_COMMON_H
    176