diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-01-07 19:55:37 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-01-07 19:55:37 +0000 |
commit | ca9211ecdede9bdedb812b2243a4abdb8dacd1b9 (patch) | |
tree | 9b19e801150082c33e9152275829a6ce90614b55 /lib/lsan/lsan_common.h | |
parent | 8ef50bf3d1c287b5013c3168de77a462dfce3495 (diff) |
Import compiler-rt trunk r224034.vendor/compiler-rt/compiler-rt-r224034
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=276789
svn path=/vendor/compiler-rt/compiler-rt-r224034/; revision=276790; tag=vendor/compiler-rt/compiler-rt-r224034
Diffstat (limited to 'lib/lsan/lsan_common.h')
-rw-r--r-- | lib/lsan/lsan_common.h | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/lib/lsan/lsan_common.h b/lib/lsan/lsan_common.h index d490f8bafd9e..86ff12da6e0f 100644 --- a/lib/lsan/lsan_common.h +++ b/lib/lsan/lsan_common.h @@ -21,7 +21,7 @@ #include "sanitizer_common/sanitizer_platform.h" #include "sanitizer_common/sanitizer_symbolizer.h" -#if SANITIZER_LINUX && defined(__x86_64__) +#if SANITIZER_LINUX && defined(__x86_64__) && (SANITIZER_WORDSIZE == 64) #define CAN_SANITIZE_LEAKS 1 #else #define CAN_SANITIZE_LEAKS 0 @@ -51,8 +51,6 @@ struct Flags { int max_leaks; // If nonzero kill the process with this exit code upon finding leaks. int exitcode; - // Suppressions file name. - const char* suppressions; // Flags controlling the root set of reachable memory. // Global variables (.data and .bss). @@ -63,12 +61,13 @@ struct Flags { bool use_registers; // TLS and thread-specific storage. bool use_tls; + // Regions added via __lsan_register_root_region(). + bool use_root_regions; // Consider unaligned pointers valid. bool use_unaligned; - - // User-visible verbosity. - int verbosity; + // Consider pointers found in poisoned memory to be valid. + bool use_poisoned; // Debug logging. bool log_pointers; @@ -79,6 +78,7 @@ extern Flags lsan_flags; inline Flags *flags() { return &lsan_flags; } struct Leak { + u32 id; uptr hit_count; uptr total_size; u32 stack_trace_id; @@ -86,17 +86,31 @@ struct Leak { bool is_suppressed; }; +struct LeakedObject { + u32 leak_id; + uptr addr; + uptr size; +}; + // Aggregates leaks by stack trace prefix. class LeakReport { public: - LeakReport() : leaks_(1) {} - void Add(u32 stack_trace_id, uptr leaked_size, ChunkTag tag); - void PrintLargest(uptr max_leaks); + LeakReport() : next_id_(0), leaks_(1), leaked_objects_(1) {} + void AddLeakedChunk(uptr chunk, u32 stack_trace_id, uptr leaked_size, + ChunkTag tag); + void ReportTopLeaks(uptr max_leaks); void PrintSummary(); - bool IsEmpty() { return leaks_.size() == 0; } - uptr ApplySuppressions(); + void ApplySuppressions(); + uptr UnsuppressedLeakCount(); + + private: + void PrintReportForLeak(uptr index); + void PrintLeakedObjectsForLeak(uptr index); + + u32 next_id_; InternalMmapVector<Leak> leaks_; + InternalMmapVector<LeakedObject> leaked_objects_; }; typedef InternalMmapVector<uptr> Frontier; @@ -117,10 +131,19 @@ enum IgnoreObjectResult { }; // Functions called from the parent tool. -void InitCommonLsan(); +void InitCommonLsan(bool standalone); void DoLeakCheck(); bool DisabledInThisThread(); +// Special case for "new T[0]" where T is a type with DTOR. +// new T[0] will allocate one word for the array size (0) and store a pointer +// to the end of allocated chunk. +inline bool IsSpecialCaseOfOperatorNew0(uptr chunk_beg, uptr chunk_size, + uptr addr) { + return chunk_size == sizeof(uptr) && chunk_beg + chunk_size == addr && + *reinterpret_cast<uptr *>(chunk_beg) == 0; +} + // The following must be implemented in the parent tool. void ForEachChunk(ForEachChunkCallback callback, void *arg); @@ -129,6 +152,8 @@ void GetAllocatorGlobalRange(uptr *begin, uptr *end); // Wrappers for allocator's ForceLock()/ForceUnlock(). void LockAllocator(); void UnlockAllocator(); +// Returns true if [addr, addr + sizeof(void *)) is poisoned. +bool WordIsPoisoned(uptr addr); // Wrappers for ThreadRegistry access. void LockThreadRegistry(); void UnlockThreadRegistry(); |