diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
commit | 3a1720af1d7f43edc5b214cde0be11bfb94d077e (patch) | |
tree | 029e0ff2d5e3c0eaf2405fd8e669555fdf5e1297 /lib/gwp_asan/guarded_pool_allocator.cpp | |
parent | 8f3cadc28cb2bb9e8f9d69eeaaea1f57f2f7b2ab (diff) | |
download | src-test2-3a1720af1d7f43edc5b214cde0be11bfb94d077e.tar.gz src-test2-3a1720af1d7f43edc5b214cde0be11bfb94d077e.zip |
Notes
Diffstat (limited to 'lib/gwp_asan/guarded_pool_allocator.cpp')
-rw-r--r-- | lib/gwp_asan/guarded_pool_allocator.cpp | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/lib/gwp_asan/guarded_pool_allocator.cpp b/lib/gwp_asan/guarded_pool_allocator.cpp index 7e3628eba6ff..ef497336025f 100644 --- a/lib/gwp_asan/guarded_pool_allocator.cpp +++ b/lib/gwp_asan/guarded_pool_allocator.cpp @@ -13,7 +13,7 @@ // RHEL creates the PRIu64 format macro (for printing uint64_t's) only when this // macro is defined before including <inttypes.h>. #ifndef __STDC_FORMAT_MACROS - #define __STDC_FORMAT_MACROS 1 +#define __STDC_FORMAT_MACROS 1 #endif #include <assert.h> @@ -44,11 +44,12 @@ private: bool &Bool; }; -void defaultPrintStackTrace(uintptr_t *Trace, options::Printf_t Printf) { - if (Trace[0] == 0) +void defaultPrintStackTrace(uintptr_t *Trace, size_t TraceLength, + options::Printf_t Printf) { + if (TraceLength == 0) Printf(" <unknown (does your allocator support backtracing?)>\n"); - for (size_t i = 0; Trace[i] != 0; ++i) { + for (size_t i = 0; i < TraceLength; ++i) { Printf(" #%zu 0x%zx in <unknown>\n", i, Trace[i]); } Printf("\n"); @@ -68,12 +69,18 @@ void GuardedPoolAllocator::AllocationMetadata::RecordAllocation( // TODO(hctim): Ask the caller to provide the thread ID, so we don't waste // other thread's time getting the thread ID under lock. AllocationTrace.ThreadID = getThreadID(); + AllocationTrace.TraceSize = 0; + DeallocationTrace.TraceSize = 0; DeallocationTrace.ThreadID = kInvalidThreadID; - if (Backtrace) - Backtrace(AllocationTrace.Trace, kMaximumStackFrames); - else - AllocationTrace.Trace[0] = 0; - DeallocationTrace.Trace[0] = 0; + + if (Backtrace) { + uintptr_t UncompressedBuffer[kMaxTraceLengthToCollect]; + size_t BacktraceLength = + Backtrace(UncompressedBuffer, kMaxTraceLengthToCollect); + AllocationTrace.TraceSize = compression::pack( + UncompressedBuffer, BacktraceLength, AllocationTrace.CompressedTrace, + kStackFrameStorageBytes); + } } void GuardedPoolAllocator::AllocationMetadata::RecordDeallocation( @@ -81,11 +88,16 @@ void GuardedPoolAllocator::AllocationMetadata::RecordDeallocation( IsDeallocated = true; // Ensure that the unwinder is not called if the recursive flag is set, // otherwise non-reentrant unwinders may deadlock. + DeallocationTrace.TraceSize = 0; if (Backtrace && !ThreadLocals.RecursiveGuard) { ScopedBoolean B(ThreadLocals.RecursiveGuard); - Backtrace(DeallocationTrace.Trace, kMaximumStackFrames); - } else { - DeallocationTrace.Trace[0] = 0; + + uintptr_t UncompressedBuffer[kMaxTraceLengthToCollect]; + size_t BacktraceLength = + Backtrace(UncompressedBuffer, kMaxTraceLengthToCollect); + DeallocationTrace.TraceSize = compression::pack( + UncompressedBuffer, BacktraceLength, DeallocationTrace.CompressedTrace, + kStackFrameStorageBytes); } DeallocationTrace.ThreadID = getThreadID(); } @@ -161,7 +173,7 @@ void GuardedPoolAllocator::init(const options::Options &Opts) { // Ensure that signal handlers are installed as late as possible, as the class // is not thread-safe until init() is finished, and thus a SIGSEGV may cause a - // race to members if recieved during init(). + // race to members if received during init(). if (Opts.InstallSignalHandlers) installSignalHandlers(); } @@ -373,7 +385,7 @@ void printErrorType(Error E, uintptr_t AccessPtr, AllocationMetadata *Meta, case Error::UNKNOWN: ErrorString = "GWP-ASan couldn't automatically determine the source of " "the memory error. It was likely caused by a wild memory " - "access into the GWP-ASan pool. The error occured"; + "access into the GWP-ASan pool. The error occurred"; break; case Error::USE_AFTER_FREE: ErrorString = "Use after free"; @@ -442,7 +454,13 @@ void printAllocDeallocTraces(uintptr_t AccessPtr, AllocationMetadata *Meta, Printf("0x%zx was deallocated by thread %zu here:\n", AccessPtr, Meta->DeallocationTrace.ThreadID); - PrintBacktrace(Meta->DeallocationTrace.Trace, Printf); + uintptr_t UncompressedTrace[AllocationMetadata::kMaxTraceLengthToCollect]; + size_t UncompressedLength = compression::unpack( + Meta->DeallocationTrace.CompressedTrace, + Meta->DeallocationTrace.TraceSize, UncompressedTrace, + AllocationMetadata::kMaxTraceLengthToCollect); + + PrintBacktrace(UncompressedTrace, UncompressedLength, Printf); } if (Meta->AllocationTrace.ThreadID == GuardedPoolAllocator::kInvalidThreadID) @@ -451,7 +469,12 @@ void printAllocDeallocTraces(uintptr_t AccessPtr, AllocationMetadata *Meta, Printf("0x%zx was allocated by thread %zu here:\n", Meta->Addr, Meta->AllocationTrace.ThreadID); - PrintBacktrace(Meta->AllocationTrace.Trace, Printf); + uintptr_t UncompressedTrace[AllocationMetadata::kMaxTraceLengthToCollect]; + size_t UncompressedLength = compression::unpack( + Meta->AllocationTrace.CompressedTrace, Meta->AllocationTrace.TraceSize, + UncompressedTrace, AllocationMetadata::kMaxTraceLengthToCollect); + + PrintBacktrace(UncompressedTrace, UncompressedLength, Printf); } struct ScopedEndOfReportDecorator { @@ -491,11 +514,11 @@ void GuardedPoolAllocator::reportErrorInternal(uintptr_t AccessPtr, Error E) { uint64_t ThreadID = getThreadID(); printErrorType(E, AccessPtr, Meta, Printf, ThreadID); if (Backtrace) { - static constexpr unsigned kMaximumStackFramesForCrashTrace = 128; + static constexpr unsigned kMaximumStackFramesForCrashTrace = 512; uintptr_t Trace[kMaximumStackFramesForCrashTrace]; - Backtrace(Trace, kMaximumStackFramesForCrashTrace); + size_t TraceLength = Backtrace(Trace, kMaximumStackFramesForCrashTrace); - PrintBacktrace(Trace, Printf); + PrintBacktrace(Trace, TraceLength, Printf); } else { Printf(" <unknown (does your allocator support backtracing?)>\n\n"); } |