From 2286a32bd0d8b823217c67955a4bfda331386edc Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 21 Apr 2025 17:29:03 +0800 Subject: [PATCH] [Compiler-RT][HWASAN] Add quarantine average stay time. Signed-off-by: Eric --- compiler-rt/lib/hwasan/hwasan.cpp | 4 ++++ compiler-rt/lib/hwasan/hwasan_allocator.cpp | 10 +++++++++ compiler-rt/lib/hwasan/hwasan_allocator.h | 12 ++++++++++ compiler-rt/lib/hwasan/hwasan_flags.inc | 3 +++ compiler-rt/lib/hwasan/hwasan_quarantine.cpp | 18 ++++++++++++++- compiler-rt/lib/hwasan/hwasan_quarantine.h | 5 +++++ compiler-rt/lib/hwasan/hwasan_thread.cpp | 6 +++++ compiler-rt/lib/hwasan/hwasan_thread.h | 2 ++ compiler-rt/lib/hwasan/hwasan_thread_list.h | 23 ++++++++++++++++++++ 9 files changed, 82 insertions(+), 1 deletion(-) diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp index 1075785be64a..652ed075150a 100644 --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -199,6 +199,10 @@ void UpdateMemoryUsage() {} #endif void HwasanAtExit() { + // OHOS_LOCAL begin + if (__hwasan::ShouldPrintQuarantineDwillTime()) + hwasanThreadList().PrintfAverageQuarantineTime(); + // OHOS_LOCAL end if (common_flags()->print_module_map) DumpProcessMap(); if (flags()->print_stats && (flags()->atexit || hwasan_report_count > 0)) diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp index 5f34e021356a..46422d02cec7 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp @@ -28,6 +28,7 @@ namespace __hwasan { static Allocator allocator; static AllocatorCache fallback_allocator_cache; static SpinMutex fallback_mutex; +static SpinMutex count_mutex; static atomic_uint8_t hwasan_allocator_tagging_enabled; static constexpr tag_t kFallbackAllocTag = 0xBB & kTagMask; @@ -320,6 +321,15 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { } // OHOS_LOCAL begin + { + if (__hwasan::ShouldPrintQuarantineDwillTime()) { + SpinMutexLock l(&count_mutex); + if (hwasanThreadList().AddCount() % PRINT_COUNTER == 0) { + hwasanThreadList().PrintfAverageQuarantineTime(); + } + } + } + int aid = meta->thread_id; if (t) { if (!t->TryPutInQuarantineWithDealloc(reinterpret_cast(aligned_ptr), diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.h b/compiler-rt/lib/hwasan/hwasan_allocator.h index 28f4f74bdb93..7514e2735a6c 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.h +++ b/compiler-rt/lib/hwasan/hwasan_allocator.h @@ -28,6 +28,11 @@ #error Unsupported platform #endif +// OHOS_LOCAL begin +// The current setting is temporarily configured to 100,000 and will be adjusted in subsequent updates. +#define PRINT_COUNTER 100000 +// OHOS_LOCAL end + namespace __hwasan { struct Metadata { @@ -125,6 +130,13 @@ inline bool InTaggableRegion(uptr addr) { #endif return true; } +// OHOS_LOCAL begin +__attribute__((always_inline)) static bool ShouldPrintQuarantineDwillTime() { + return flags()->heap_quarantine_max > 0 && + flags()->enable_heap_quarantine_debug && + flags()->heap_quarantine_thread_max_count > 0; +} +// OHOS_LOCAL end } // namespace __hwasan diff --git a/compiler-rt/lib/hwasan/hwasan_flags.inc b/compiler-rt/lib/hwasan/hwasan_flags.inc index 2dd11b455b9e..2853e870bd84 100644 --- a/compiler-rt/lib/hwasan/hwasan_flags.inc +++ b/compiler-rt/lib/hwasan/hwasan_flags.inc @@ -128,6 +128,9 @@ HWASAN_FLAG( "The freed heap size should be smaller than the maximum size before " "it is placed into the heap quarantine.") +HWASAN_FLAG(bool, enable_heap_quarantine_debug, false, + "Enable Hwasan Quarantine Debug Mode.") + // Default minimum configuration HWASAN_FLAG(bool, allow_user_segv_handler, true, "Deprecated. True has no effect, use handle_sigbus=1. If false, " diff --git a/compiler-rt/lib/hwasan/hwasan_quarantine.cpp b/compiler-rt/lib/hwasan/hwasan_quarantine.cpp index c7679cf2436d..4ca56b030f1d 100644 --- a/compiler-rt/lib/hwasan/hwasan_quarantine.cpp +++ b/compiler-rt/lib/hwasan/hwasan_quarantine.cpp @@ -16,6 +16,7 @@ #include "hwasan_quarantine.h" #include "hwasan_allocator.h" +#include "hwasan_thread.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_stackdepot.h" namespace __hwasan { @@ -60,6 +61,13 @@ bool HeapQuarantineController::TryPutInQuarantineWithDealloc( void HeapQuarantineController::PutInQuarantineWithDealloc( uptr ptr, size_t s, u32 aid, u32 fid, AllocatorCache *cache) { + if (flags()->enable_heap_quarantine_debug) { + size_t current_time_point = NanoTime() / 1000; + count++; + persist_interval += + heap_quarantine_tail_ * (current_time_point - pre_time_point); + pre_time_point = current_time_point; + } if (UNLIKELY(heap_quarantine_tail_ >= flags()->heap_quarantine_thread_max_count)) { // free 1/3 heap_quarantine_list @@ -115,4 +123,12 @@ void HeapQuarantineController::DeallocateWithHeapQuarantcheck( } } -} // namespace __hwasan \ No newline at end of file +void HeapQuarantineController::consumeQuarantineStayTimeAndCount( + size_t &staytime, size_t &staycount) { + staytime += persist_interval; + staycount += count; + persist_interval = 0; + count = 0; +} + +} // namespace __hwasan diff --git a/compiler-rt/lib/hwasan/hwasan_quarantine.h b/compiler-rt/lib/hwasan/hwasan_quarantine.h index 1c4c86a26168..6cf3b077c7f9 100644 --- a/compiler-rt/lib/hwasan/hwasan_quarantine.h +++ b/compiler-rt/lib/hwasan/hwasan_quarantine.h @@ -28,6 +28,9 @@ class HeapQuarantineController { private: u32 heap_quarantine_tail_; HeapQuarantine *heap_quarantine_list_; + size_t count{0}; + size_t persist_interval{0}; + size_t pre_time_point{0}; void PutInQuarantineWithDealloc(uptr ptr, size_t s, u32 aid, u32 fid, AllocatorCache *cache); void DeallocateWithHeapQuarantcheck(u32 free_count, AllocatorCache *cache); @@ -42,6 +45,8 @@ class HeapQuarantineController { bool TryPutInQuarantineWithDealloc(uptr ptr, size_t s, u32 aid, u32 fid, AllocatorCache *cache); + + void consumeQuarantineStayTimeAndCount(size_t &staytime, size_t &staycount); }; } // namespace __hwasan diff --git a/compiler-rt/lib/hwasan/hwasan_thread.cpp b/compiler-rt/lib/hwasan/hwasan_thread.cpp index 4be4929284d9..d1c6a03a8ec9 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.cpp +++ b/compiler-rt/lib/hwasan/hwasan_thread.cpp @@ -168,6 +168,12 @@ bool Thread::TryPutInQuarantineWithDealloc(uptr ptr, size_t s, u32 aid, return heap_quarantine_controller()->TryPutInQuarantineWithDealloc( ptr, s, aid, fid, allocator_cache()); } + +void Thread::GetQuarantineStayTimeAndCount(size_t &staytime, + size_t &staycount) { + heap_quarantine_controller()->consumeQuarantineStayTimeAndCount(staytime, + staycount); +} // OHOS_LOCAL end } // namespace __hwasan diff --git a/compiler-rt/lib/hwasan/hwasan_thread.h b/compiler-rt/lib/hwasan/hwasan_thread.h index 8f1126877aa9..0845266fe77d 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.h +++ b/compiler-rt/lib/hwasan/hwasan_thread.h @@ -92,6 +92,8 @@ class Thread { } bool TryPutInQuarantineWithDealloc(uptr ptr, size_t s, u32 aid, u32 fid); + + void GetQuarantineStayTimeAndCount(size_t &staytime, size_t &staycount); // OHOS_LOCAL end private: diff --git a/compiler-rt/lib/hwasan/hwasan_thread_list.h b/compiler-rt/lib/hwasan/hwasan_thread_list.h index d8edde1e4cde..3c297525a677 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread_list.h +++ b/compiler-rt/lib/hwasan/hwasan_thread_list.h @@ -48,6 +48,7 @@ #include "hwasan_flags.h" #include "hwasan_thread.h" +#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_placement_new.h" namespace __hwasan { @@ -194,6 +195,11 @@ class HwasanThreadList { void ReleaseThread(Thread *t) { AddFreedRingBuffer(t); // OHOS_LOCAL RemoveThreadStats(t); + // OHOS_LOCAL begin + if (__hwasan::ShouldPrintQuarantineDwillTime()) + t->GetQuarantineStayTimeAndCount(quarantine_stay_time_, + quarantine_stay_count_); + // OHOS_LOCAL end t->Destroy(); DontNeedThread(t); RemoveThreadFromLiveList(t); @@ -272,6 +278,20 @@ class HwasanThreadList { bool AllowTracingHeapAllocation() { return trace_heap_allocation_; } // OHOS_LOCAL end + // OHOS_LOCAL begin + size_t AddCount() { return ++deallocate_count_; } + void PrintfAverageQuarantineTime() { + if (!SafeToCallPrintf()) + return; + VisitAllLiveThreads([&](Thread *t) { + t->GetQuarantineStayTimeAndCount(quarantine_stay_time_, + quarantine_stay_count_); + }); + Printf("[hwasan]: AvgDuration %d us\n", + quarantine_stay_time_ / quarantine_stay_count_); + } + // OHOS_LOCAL end + private: Thread *AllocThread() { SpinMutexLock l(&free_space_mutex_); @@ -302,6 +322,9 @@ class HwasanThreadList { u64 freed_rb_count_; u64 freed_rb_count_overflow_; bool trace_heap_allocation_; + size_t deallocate_count_{0}; + size_t quarantine_stay_count_{0}; + size_t quarantine_stay_time_{0}; // OHOS_LOCAL end ThreadStats stats_; -- Gitee