This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 8f3749bbd3 ASAN: Fix leak with the Stripe raw-dirs allocation (#12750)
8f3749bbd3 is described below
commit 8f3749bbd34a137b5d3e3d37a6ea9ab6cfb0c515
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.
---
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 6f46118ef9..9e0895c675 100644
--- a/src/iocore/cache/P_CacheDir.h
+++ b/src/iocore/cache/P_CacheDir.h
@@ -277,6 +277,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 825efe4c53..417e2e2f47 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 7cf6f02482..4bffbe7334 100644
--- a/src/iocore/cache/Stripe.h
+++ b/src/iocore/cache/Stripe.h
@@ -95,6 +95,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);
}