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);
 }

Reply via email to