diff options
author | kcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-04 21:33:31 +0000 |
---|---|---|
committer | kcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-04 21:33:31 +0000 |
commit | 1e80ce4111e28463d870335befe7d99066b5971e (patch) | |
tree | 7cfc103c9b6b4ce7ca19d39f91509a1b68819a63 /libsanitizer/lsan/lsan_common.h | |
parent | 482026b63e8a488d6b7f0eab53fcbfe12c3309ae (diff) | |
download | gcc-1e80ce4111e28463d870335befe7d99066b5971e.tar.gz |
libsanitizer merge from upstream r191666
This may break gcc-asan on Mac, will follow up separately.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204368 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libsanitizer/lsan/lsan_common.h')
-rw-r--r-- | libsanitizer/lsan/lsan_common.h | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/libsanitizer/lsan/lsan_common.h b/libsanitizer/lsan/lsan_common.h new file mode 100644 index 00000000000..7906ecb9177 --- /dev/null +++ b/libsanitizer/lsan/lsan_common.h @@ -0,0 +1,174 @@ +//=-- lsan_common.h -------------------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of LeakSanitizer. +// Private LSan header. +// +//===----------------------------------------------------------------------===// + +#ifndef LSAN_COMMON_H +#define LSAN_COMMON_H + +#include "sanitizer_common/sanitizer_allocator.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_internal_defs.h" +#include "sanitizer_common/sanitizer_platform.h" +#include "sanitizer_common/sanitizer_symbolizer.h" + +#if SANITIZER_LINUX && defined(__x86_64__) +#define CAN_SANITIZE_LEAKS 1 +#else +#define CAN_SANITIZE_LEAKS 0 +#endif + +namespace __lsan { + +// Chunk tags. +enum ChunkTag { + kDirectlyLeaked = 0, // default + kIndirectlyLeaked = 1, + kReachable = 2, + kIgnored = 3 +}; + +struct Flags { + uptr pointer_alignment() const { + return use_unaligned ? 1 : sizeof(uptr); + } + + // Print addresses of leaked objects after main leak report. + bool report_objects; + // Aggregate two objects into one leak if this many stack frames match. If + // zero, the entire stack trace must match. + int resolution; + // The number of leaks reported. + 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). + bool use_globals; + // Thread stacks. + bool use_stacks; + // Thread registers. + bool use_registers; + // TLS and thread-specific storage. + bool use_tls; + + // Consider unaligned pointers valid. + bool use_unaligned; + + // User-visible verbosity. + int verbosity; + + // Debug logging. + bool log_pointers; + bool log_threads; +}; + +extern Flags lsan_flags; +inline Flags *flags() { return &lsan_flags; } + +struct Leak { + uptr hit_count; + uptr total_size; + u32 stack_trace_id; + bool is_directly_leaked; + bool is_suppressed; +}; + +// 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); + void PrintSummary(); + bool IsEmpty() { return leaks_.size() == 0; } + uptr ApplySuppressions(); + private: + InternalMmapVector<Leak> leaks_; +}; + +typedef InternalMmapVector<uptr> Frontier; + +// Platform-specific functions. +void InitializePlatformSpecificModules(); +void ProcessGlobalRegions(Frontier *frontier); +void ProcessPlatformSpecificAllocations(Frontier *frontier); + +void ScanRangeForPointers(uptr begin, uptr end, + Frontier *frontier, + const char *region_type, ChunkTag tag); + +enum IgnoreObjectResult { + kIgnoreObjectSuccess, + kIgnoreObjectAlreadyIgnored, + kIgnoreObjectInvalid +}; + +// Functions called from the parent tool. +void InitCommonLsan(); +void DoLeakCheck(); +bool DisabledInThisThread(); + +// The following must be implemented in the parent tool. + +void ForEachChunk(ForEachChunkCallback callback, void *arg); +// Returns the address range occupied by the global allocator object. +void GetAllocatorGlobalRange(uptr *begin, uptr *end); +// Wrappers for allocator's ForceLock()/ForceUnlock(). +void LockAllocator(); +void UnlockAllocator(); +// Wrappers for ThreadRegistry access. +void LockThreadRegistry(); +void UnlockThreadRegistry(); +bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end, + uptr *tls_begin, uptr *tls_end, + uptr *cache_begin, uptr *cache_end); +// If called from the main thread, updates the main thread's TID in the thread +// registry. We need this to handle processes that fork() without a subsequent +// exec(), which invalidates the recorded TID. To update it, we must call +// gettid() from the main thread. Our solution is to call this function before +// leak checking and also before every call to pthread_create() (to handle cases +// where leak checking is initiated from a non-main thread). +void EnsureMainThreadIDIsCorrect(); +// If p points into a chunk that has been allocated to the user, returns its +// user-visible address. Otherwise, returns 0. +uptr PointsIntoChunk(void *p); +// Returns address of user-visible chunk contained in this allocator chunk. +uptr GetUserBegin(uptr chunk); +// Helper for __lsan_ignore_object(). +IgnoreObjectResult IgnoreObjectLocked(const void *p); +// Wrapper for chunk metadata operations. +class LsanMetadata { + public: + // Constructor accepts address of user-visible chunk. + explicit LsanMetadata(uptr chunk); + bool allocated() const; + ChunkTag tag() const; + void set_tag(ChunkTag value); + uptr requested_size() const; + u32 stack_trace_id() const; + private: + void *metadata_; +}; + +} // namespace __lsan + +extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE +int __lsan_is_turned_off(); + +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE +const char *__lsan_default_suppressions(); +} // extern "C" + +#endif // LSAN_COMMON_H |