diff --git a/src/core/SkASAN.h b/src/core/SkASAN.h index 84b0f0c633..40870a4879 100644 --- a/src/core/SkASAN.h +++ b/src/core/SkASAN.h @@ -22,7 +22,7 @@ #endif // Typically declared in LLVM's asan_interface.h. -#if SK_SANITIZE_ADDRESS +#ifdef SK_SANITIZE_ADDRESS extern "C" { void __asan_poison_memory_region(void const volatile *addr, size_t size); void __asan_unpoison_memory_region(void const volatile *addr, size_t size); @@ -33,13 +33,13 @@ extern "C" { // unpoison chunks of arena memory as they are parceled out. Consider leaving gaps between blocks // to detect buffer overrun. static inline void sk_asan_poison_memory_region(void const volatile *addr, size_t size) { -#if SK_SANITIZE_ADDRESS +#ifdef SK_SANITIZE_ADDRESS __asan_poison_memory_region(addr, size); #endif } static inline void sk_asan_unpoison_memory_region(void const volatile *addr, size_t size) { -#if SK_SANITIZE_ADDRESS +#ifdef SK_SANITIZE_ADDRESS __asan_unpoison_memory_region(addr, size); #endif } diff --git a/src/gpu/GrMemoryPool.cpp b/src/gpu/GrMemoryPool.cpp index 2686cbf7b0..0a20527591 100644 --- a/src/gpu/GrMemoryPool.cpp +++ b/src/gpu/GrMemoryPool.cpp @@ -8,6 +8,7 @@ #include "src/gpu/GrMemoryPool.h" #include "include/private/SkTPin.h" +#include "src/core/SkASAN.h" #include "src/gpu/ops/GrOp.h" #ifdef SK_DEBUG @@ -69,8 +70,13 @@ void* GrMemoryPool::allocate(size_t size) { // Update live count within the block alloc.fBlock->setMetadata(alloc.fBlock->metadata() + 1); -#ifdef SK_DEBUG +#if defined(SK_SANITIZE_ADDRESS) + sk_asan_poison_memory_region(&header->fSentinel, sizeof(header->fSentinel)); +#elif defined(SK_DEBUG) header->fSentinel = GrBlockAllocator::kAssignedMarker; +#endif + +#if defined(SK_DEBUG) header->fID = []{ static std::atomic nextID{1}; return nextID++; @@ -89,16 +95,20 @@ void GrMemoryPool::release(void* p) { // NOTE: if we needed it, (p - block) would equal the original alignedOffset value returned by // GrBlockAllocator::allocate() Header* header = reinterpret_cast(reinterpret_cast(p) - sizeof(Header)); + +#if defined(SK_SANITIZE_ADDRESS) + sk_asan_unpoison_memory_region(&header->fSentinel, sizeof(header->fSentinel)); +#elif defined(SK_DEBUG) SkASSERT(GrBlockAllocator::kAssignedMarker == header->fSentinel); - - GrBlockAllocator::Block* block = fAllocator.owningBlock(header, header->fStart); - -#ifdef SK_DEBUG header->fSentinel = GrBlockAllocator::kFreedMarker; +#endif + +#if defined(SK_DEBUG) fAllocatedIDs.remove(header->fID); fAllocationCount--; #endif + GrBlockAllocator::Block* block = fAllocator.owningBlock(header, header->fStart); int alive = block->metadata(); if (alive == 1) { // This was last allocation in the block, so remove it diff --git a/src/gpu/GrMemoryPool.h b/src/gpu/GrMemoryPool.h index 5c612ea790..9ce408f787 100644 --- a/src/gpu/GrMemoryPool.h +++ b/src/gpu/GrMemoryPool.h @@ -106,12 +106,14 @@ private: // Per-allocation overhead so that GrMemoryPool can always identify the block owning each and // release all occupied bytes, including any resulting from alignment padding. struct Header { -#ifdef SK_DEBUG - int fSentinel; // known value to check for memory stomping (e.g., (CD)*) - int fID; // ID that can be used to track down leaks by clients. -#endif int fStart; int fEnd; +#if defined(SK_DEBUG) + int fID; // ID that can be used to track down leaks by clients. +#endif +#if defined(SK_DEBUG) || defined(SK_SANITIZE_ADDRESS) + int fSentinel; // set to a known value to check for memory stomping; poisoned in ASAN mode +#endif }; GrMemoryPool(size_t preallocSize, size_t minAllocSize);