This is an automated email from the ASF dual-hosted git repository. cmcfarlen pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit e449699488edd0683f8b1506a2cc236f5852d7a2 Author: Leif Hedstrom <[email protected]> AuthorDate: Wed Dec 10 12:41:39 2025 -0700 ASAN: Fix leak with the Stripe raw-dirs allocation (#12750) Since this can be allocated in two ways, we have to also keep track how it was allocated for when the destructor is called. (cherry picked from commit 8f3749bbd34a137b5d3e3d37a6ea9ab6cfb0c515) --- src/iocore/cache/P_CacheDir.h | 2 ++ src/iocore/cache/Stripe.cc | 23 ++++++++++++++++++++--- src/iocore/cache/Stripe.h | 1 + src/iocore/cache/unit_tests/test_Stripe.cc | 5 ----- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/iocore/cache/P_CacheDir.h b/src/iocore/cache/P_CacheDir.h index b6b484c948..af0502261d 100644 --- a/src/iocore/cache/P_CacheDir.h +++ b/src/iocore/cache/P_CacheDir.h @@ -279,6 +279,8 @@ struct Directory { StripteHeaderFooter *footer{}; int segments{}; off_t buckets{}; + size_t raw_dir_size{0}; // size of raw_dir allocation (for freeing hugepages) + bool raw_dir_huge{false}; // true if raw_dir was allocated with hugepages /* Total number of dir entries. */ diff --git a/src/iocore/cache/Stripe.cc b/src/iocore/cache/Stripe.cc index 8ae9c15767..2ff55439d8 100644 --- a/src/iocore/cache/Stripe.cc +++ b/src/iocore/cache/Stripe.cc @@ -154,16 +154,33 @@ Stripe::_init_directory(std::size_t directory_size, int header_size, int footer_ directory_size, (long long)this->len, percent(directory_size, this->len)); if (ats_hugepage_enabled()) { this->directory.raw_dir = static_cast<char *>(ats_alloc_hugepage(directory_size)); + if (this->directory.raw_dir != nullptr) { + this->directory.raw_dir_huge = true; + } } if (nullptr == this->directory.raw_dir) { - this->directory.raw_dir = static_cast<char *>(ats_memalign(ats_pagesize(), directory_size)); + this->directory.raw_dir = static_cast<char *>(ats_memalign(ats_pagesize(), directory_size)); + this->directory.raw_dir_huge = false; } - this->directory.dir = reinterpret_cast<Dir *>(this->directory.raw_dir + header_size); - this->directory.header = reinterpret_cast<StripteHeaderFooter *>(this->directory.raw_dir); + this->directory.raw_dir_size = directory_size; + this->directory.dir = reinterpret_cast<Dir *>(this->directory.raw_dir + header_size); + this->directory.header = reinterpret_cast<StripteHeaderFooter *>(this->directory.raw_dir); std::size_t const footer_offset{directory_size - static_cast<std::size_t>(footer_size)}; this->directory.footer = reinterpret_cast<StripteHeaderFooter *>(this->directory.raw_dir + footer_offset); } +Stripe::~Stripe() +{ + if (this->directory.raw_dir != nullptr) { + if (this->directory.raw_dir_huge) { + ats_free_hugepage(this->directory.raw_dir, this->directory.raw_dir_size); + } else { + ats_free(this->directory.raw_dir); + } + this->directory.raw_dir = nullptr; + } +} + int Stripe::dir_check() { diff --git a/src/iocore/cache/Stripe.h b/src/iocore/cache/Stripe.h index 84be1f95b0..253f8550b7 100644 --- a/src/iocore/cache/Stripe.h +++ b/src/iocore/cache/Stripe.h @@ -91,6 +91,7 @@ public: * @see START_POS */ Stripe(CacheDisk *disk, off_t blocks, off_t dir_skip, int avg_obj_size = -1, int fragment_size = -1); + virtual ~Stripe(); int dir_check(); diff --git a/src/iocore/cache/unit_tests/test_Stripe.cc b/src/iocore/cache/unit_tests/test_Stripe.cc index 87f332f775..a488590bc5 100644 --- a/src/iocore/cache/unit_tests/test_Stripe.cc +++ b/src/iocore/cache/unit_tests/test_Stripe.cc @@ -191,8 +191,6 @@ TEST_CASE("The behavior of StripeSM::add_writer.") CHECK(true == result); } } - - ats_free(stripe.directory.raw_dir); } // This test case demonstrates how to set up a StripeSM and make @@ -301,8 +299,6 @@ TEST_CASE("aggWrite behavior with f.evacuator unset") cache_config_enable_checksum = false; } - - ats_free(stripe.directory.raw_dir); } // When f.evacuator is set, vc.buf must contain a Doc object including headers @@ -400,5 +396,4 @@ TEST_CASE("aggWrite behavior with f.evacuator set") } delete[] source; - ats_free(stripe.directory.raw_dir); }
