This is an automated email from the ASF dual-hosted git repository.
bcall 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 f1435a2358 Add debug instrumentation to Stripe destructor (#12754)
f1435a2358 is described below
commit f1435a2358c3f437a8935561a25eda0edb77b730
Author: Bryan Call <[email protected]>
AuthorDate: Thu Jan 8 15:44:40 2026 -0800
Add debug instrumentation to Stripe destructor (#12754)
Add debug logging, validation assertions, and memory poisoning to help
track down intermittent heap corruption issues during cache cleanup.
- Add Dbg() logging with pointer address, size, and allocation type
- Add assertions to validate size is reasonable before freeing
- Add memory poisoning (0xDE pattern) in DEBUG builds before free
- Reset raw_dir_size to 0 after freeing
This helps diagnose issues like "free(): corrupted unsorted chunks"
that can occur intermittently during cache test cleanup.
---
src/iocore/cache/Stripe.cc | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/iocore/cache/Stripe.cc b/src/iocore/cache/Stripe.cc
index c0c0723657..ebd98d0642 100644
--- a/src/iocore/cache/Stripe.cc
+++ b/src/iocore/cache/Stripe.cc
@@ -40,6 +40,7 @@ namespace
{
DbgCtl dbg_ctl_cache_init{"cache_init"};
+DbgCtl dbg_ctl_cache_free{"cache_free"};
constexpr int
DIRECTORY_FOOTER_SIZE{ROUND_TO_STORE_BLOCK(sizeof(StripeHeaderFooter))};
@@ -172,12 +173,26 @@ Stripe::_init_directory(std::size_t directory_size, int
header_size, int footer_
Stripe::~Stripe()
{
if (this->directory.raw_dir != nullptr) {
+ // Debug logging to track cleanup - helps correlate with crash location
+ Dbg(dbg_ctl_cache_free, "Stripe %s: freeing raw_dir=%p size=%zu huge=%s",
hash_text.get() ? hash_text.get() : "(null)",
+ this->directory.raw_dir, this->directory.raw_dir_size,
this->directory.raw_dir_huge ? "true" : "false");
+
+ // Validate that size is reasonable (catches corruption before free)
+ ink_assert(this->directory.raw_dir_size > 0);
+ ink_assert(this->directory.raw_dir_size < MAX_STRIPE_SIZE);
+
+#ifdef DEBUG
+ // Poison memory before freeing to help detect use-after-free
+ memset(this->directory.raw_dir, 0xDE, this->directory.raw_dir_size);
+#endif
+
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;
+ this->directory.raw_dir = nullptr;
+ this->directory.raw_dir_size = 0;
}
}