From c5c0f9b400e55553a0c3ff281b3d172ea488fc37 Mon Sep 17 00:00:00 2001 From: Chia-hung Duan Date: Wed, 19 Apr 2023 22:58:36 +0000 Subject: [PATCH] [scudo] Support printing the status of cached blocks The output looks like, Stats: SharedTSDs: 2 available; total 8 Shared TSD[0]: 00 ( 64): cached: 10 max: 26 32 ( 65552): cached: 1 max: 2 Shared TSD[1]: No block is cached. Differential Revision: https://reviews.llvm.org/D148755 --- compiler-rt/lib/scudo/standalone/combined.h | 1 + compiler-rt/lib/scudo/standalone/local_cache.h | 24 ++++++++++++++++++++++ .../lib/scudo/standalone/tests/combined_test.cpp | 2 ++ compiler-rt/lib/scudo/standalone/tsd_exclusive.h | 9 ++++++++ compiler-rt/lib/scudo/standalone/tsd_shared.h | 15 ++++++++++++++ 5 files changed, 51 insertions(+) diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h index 250eba0..d5365b6 100644 --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -1483,6 +1483,7 @@ private: Primary.getStats(Str); Secondary.getStats(Str); Quarantine.getStats(Str); + TSDRegistry.getStats(Str); return Str->length(); } diff --git a/compiler-rt/lib/scudo/standalone/local_cache.h b/compiler-rt/lib/scudo/standalone/local_cache.h index 92869ea..c97095d 100644 --- a/compiler-rt/lib/scudo/standalone/local_cache.h +++ b/compiler-rt/lib/scudo/standalone/local_cache.h @@ -14,6 +14,7 @@ #include "platform.h" #include "report.h" #include "stats.h" +#include "string_utils.h" namespace scudo { @@ -164,6 +165,29 @@ template struct SizeClassAllocatorLocalCache { LocalStats &getStats() { return Stats; } + void getStats(ScopedString *Str) { + bool EmptyCache = true; + for (uptr I = 0; I < NumClasses; ++I) { + if (PerClassArray[I].Count == 0) + continue; + + EmptyCache = false; + // The size of BatchClass is set to 0 intentionally. See the comment in + // initCache() for more details. + const uptr ClassSize = I == BatchClassId + ? SizeClassAllocator::getSizeByClassId(I) + : PerClassArray[I].ClassSize; + // Note that the string utils don't support printing u16 thus we cast it + // to a common use type uptr. + Str->append(" %02zu (%6zu): cached: %4zu max: %4zu\n", I, ClassSize, + static_cast(PerClassArray[I].Count), + static_cast(PerClassArray[I].MaxCount)); + } + + if (EmptyCache) + Str->append(" No block is cached.\n"); + } + private: static const uptr NumClasses = SizeClassMap::NumClasses; static const uptr BatchClassId = SizeClassMap::BatchClassId; diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp index 7bf580e..33a309e 100644 --- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp @@ -167,6 +167,8 @@ void ScudoCombinedTest::BasicTest(scudo::uptr SizeLog) { Allocator->deallocate(P, Origin, Size); } } + + Allocator->printStats(); } #define SCUDO_MAKE_BASIC_TEST(SizeLog) \ diff --git a/compiler-rt/lib/scudo/standalone/tsd_exclusive.h b/compiler-rt/lib/scudo/standalone/tsd_exclusive.h index 62da8ae..aca9fc9 100644 --- a/compiler-rt/lib/scudo/standalone/tsd_exclusive.h +++ b/compiler-rt/lib/scudo/standalone/tsd_exclusive.h @@ -11,6 +11,8 @@ #include "tsd.h" +#include "string_utils.h" + namespace scudo { struct ThreadState { @@ -104,6 +106,13 @@ template struct TSDRegistryExT { bool getDisableMemInit() { return State.DisableMemInit; } + void getStats(ScopedString *Str) { + // We don't have a way to iterate all thread local `ThreadTSD`s. Instead of + // printing only self `ThreadTSD` which may mislead the usage, we just skip + // it. + Str->append("Exclusive TSD don't support iterating each TSD\n"); + } + private: // Using minimal initialization allows for global initialization while keeping // the thread specific structure untouched. The fallback structure will be diff --git a/compiler-rt/lib/scudo/standalone/tsd_shared.h b/compiler-rt/lib/scudo/standalone/tsd_shared.h index 64b3bd8..e193281 100644 --- a/compiler-rt/lib/scudo/standalone/tsd_shared.h +++ b/compiler-rt/lib/scudo/standalone/tsd_shared.h @@ -11,6 +11,8 @@ #include "tsd.h" +#include "string_utils.h" + #if SCUDO_HAS_PLATFORM_TLS_SLOT // This is a platform-provided header that needs to be on the include path when // Scudo is compiled. It must declare a function with the prototype: @@ -102,6 +104,19 @@ struct TSDRegistrySharedT { bool getDisableMemInit() const { return *getTlsPtr() & 1; } + void getStats(ScopedString *Str) EXCLUDES(MutexTSDs) { + ScopedLock L(MutexTSDs); + + Str->append("Stats: SharedTSDs: %u available; total %u\n", NumberOfTSDs, + TSDsArraySize); + for (uptr I = 0; I < NumberOfTSDs; ++I) { + TSDs[I].lock(); + Str->append(" Shared TSD[%zu]:\n", I); + TSDs[I].getCache().getStats(Str); + TSDs[I].unlock(); + } + } + private: ALWAYS_INLINE uptr *getTlsPtr() const { #if SCUDO_HAS_PLATFORM_TLS_SLOT -- 2.7.4