From a98f76104c2116d4bdf79022bd00fe23ba0161ea Mon Sep 17 00:00:00 2001 From: Elfgo Date: Sat, 22 Mar 2025 02:47:23 +0000 Subject: [PATCH] [Compiler-RT][GWP_ASan] Enhance maintenance and monitoring features to GWP_ASan. Enhance maintenance and monitoring features to GWP_ASan. (1) When GWP_ASan init, print GWP_ASan Slotlength and SampleRate on Hilog. (2) Every PRINT_COUNTER(default 100k) memory allocations, print the average dwell time in the slot and the current FreeSlotLength on Hilog. Change-Id: Ic4347d931b756b488bf0f7a2a58de4885719cd49 Signed-off-by: Elfgo --- compiler-rt/lib/gwp_asan/CMakeLists.txt | 4 ++ .../lib/gwp_asan/guarded_pool_allocator.cpp | 48 ++++++++++++++++++- .../lib/gwp_asan/guarded_pool_allocator.h | 32 +++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/compiler-rt/lib/gwp_asan/CMakeLists.txt b/compiler-rt/lib/gwp_asan/CMakeLists.txt index c79ea4427b0c..da6a08d5bde8 100644 --- a/compiler-rt/lib/gwp_asan/CMakeLists.txt +++ b/compiler-rt/lib/gwp_asan/CMakeLists.txt @@ -98,6 +98,10 @@ if (COMPILER_RT_HAS_GWP_ASAN) ADDITIONAL_HEADERS ${GWP_ASAN_HEADERS} CFLAGS ${GWP_ASAN_CFLAGS} OBJECT_LIBS ${GWP_ASAN_OBJECT_LIBS} + # OHOS_LOCAL begin + RTSanitizerCommon + RTSanitizerCommonLibc + # OHOS_LOCAL end PARENT_TARGET gwp_asan ) endforeach() diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp index 6c06f10ab34e..47160942daca 100644 --- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp +++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp @@ -10,6 +10,9 @@ #include "gwp_asan/options.h" #include "gwp_asan/utilities.h" +// OHOS_LOCAL begin +#include "sanitizer_common/sanitizer_common.h" +// OHOS_LOCAL end #include #include @@ -71,6 +74,11 @@ void GuardedPoolAllocator::init(const options::Options &Opts) { 0}; State.MaxSimultaneousAllocations = Opts.MaxSimultaneousAllocations; + // OHOS_LOCAL begin + #if defined (__OHOS__) + MUSL_LOG("[gwp_asan]: SlotLength %{public}d, SampleRate %{public}d", Opts.MaxSimultaneousAllocations, Opts.SampleRate); + #endif + // OHOS_LOCAL end const size_t PageSize = getPlatformPageSize(); // getPageAddr() and roundUpTo() assume the page size to be a power of 2. @@ -352,21 +360,42 @@ AllocationMetadata *GuardedPoolAllocator::addrToMetadata(uintptr_t Ptr) const { } size_t GuardedPoolAllocator::reserveSlot() { + // OHOS_LOCAL begin + #if defined (__OHOS__) + accumulatePersistInterval(NumSampledAllocations - FreeSlotsLength); + #endif + // OHOS_LOCAL end // Avoid potential reuse of a slot before we have made at least a single // allocation in each slot. Helps with our use-after-free detection. - if (NumSampledAllocations < State.MaxSimultaneousAllocations) + if (NumSampledAllocations < State.MaxSimultaneousAllocations) { + // OHOS_LOCAL begin + #if defined (__OHOS__) + ++ReserveCounter; + #endif + // OHOS_LOCAL end return NumSampledAllocations++; + } if (FreeSlotsLength == 0) return kInvalidSlotID; size_t ReservedIndex = getRandomUnsigned32() % FreeSlotsLength; size_t SlotIndex = FreeSlots[ReservedIndex]; + // OHOS_LOCAL begin + #if defined (__OHOS__) + ++ReserveCounter; + #endif + // OHOS_LOCAL end FreeSlots[ReservedIndex] = FreeSlots[--FreeSlotsLength]; return SlotIndex; } void GuardedPoolAllocator::freeSlot(size_t SlotIndex) { + // OHOS_LOCAL begin + #if defined (__OHOS__) + accumulatePersistInterval(NumSampledAllocations - FreeSlotsLength); + #endif + // OHOS_LOCAL end assert(FreeSlotsLength < State.MaxSimultaneousAllocations); FreeSlots[FreeSlotsLength++] = SlotIndex; } @@ -379,4 +408,21 @@ uint32_t GuardedPoolAllocator::getRandomUnsigned32() { getThreadLocals()->RandomState = RandomState; return RandomState; } + +// OHOS_LOCAL begin +// The reservedSlotsLength represents the number of slots currently in use by GWP_ASan, +// while PersistInterval denotes the total accumulated duration of persistent allocations, +// when NumSampledAllocations == 0, it indicates that timing has not yet been initiated, +// requiring us to initialize the timestamp to mark the starting point. +void GuardedPoolAllocator::accumulatePersistInterval(size_t reservedSlotsLength) { + assert(reservedSlotsLength >= 0); + size_t curTime = __sanitizer::NanoTime() / 1000; + if (NumSampledAllocations == 0) { + PreTime = curTime; + return; + } + PersistInterval += (curTime - PreTime) * reservedSlotsLength; + PreTime = curTime; +}; +// OHOS_LOCAL end } // namespace gwp_asan diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h index 59686070ab06..9f4f6c1d2024 100644 --- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h +++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h @@ -21,6 +21,18 @@ #include // IWYU pragma: no_include <__stddef_max_align_t.h> +// OHOS_LOCAL begin +#if defined (__OHOS__) +#define PRINT_COUNTER 100000 +#define MUSL_LOG(fmt,...) \ + if(&musl_log) { \ + musl_log(fmt, __VA_ARGS__); \ + }; \ + +extern "C" GWP_ASAN_WEAK int musl_log(const char *fmt, ...); +#endif +// OHOS_LOCAL end + namespace gwp_asan { // This class is the primary implementation of the allocator portion of GWP- // ASan. It is the sole owner of the pool of sequentially allocated guarded @@ -77,6 +89,16 @@ public: // Return whether the allocation should be randomly chosen for sampling. GWP_ASAN_ALWAYS_INLINE bool shouldSample() { + // OHOS_LOCAL begin + #if defined (__OHOS__) + Nmalloc++; + if( Nmalloc % PRINT_COUNTER == 0 ) { + MUSL_LOG("[gwp_asan]: AvgDuration %{public}u us, FreeSlotsLength %{public}d\n", + PersistInterval / ReserveCounter, FreeSlotsLength); + Nmalloc = 0; + } + #endif + // OHOS_LOCAL end // NextSampleCounter == 0 means we "should regenerate the counter". // == 1 means we "should sample this allocation". // AdjustedSampleRatePlusOne is designed to intentionally underflow. This @@ -195,6 +217,10 @@ private: // Install a pthread_atfork handler. void installAtFork(); + // OHOS_LOCAL begin + void accumulatePersistInterval(size_t reservedSlotsLength); + // OHOS_LOCAL end + gwp_asan::AllocatorState State; // OHOS_LOCAL begin @@ -235,6 +261,12 @@ private: // GWP-ASan is disabled, we wish to never spend wasted cycles recalculating // the sample rate. uint32_t AdjustedSampleRatePlusOne = 0; + // OHOS_LOCAL begin + size_t Nmalloc{0}; + size_t PersistInterval{0}; + size_t PreTime{0}; + size_t ReserveCounter{0}; + // OHOS_LOCAL end // Additional platform specific data structure for the guarded pool mapping. PlatformSpecificMapData GuardedPagePoolPlatformData = {}; -- Gitee