From 846daa3edf9da1ab4fd1d2bdfa4ad4ad8a1302af Mon Sep 17 00:00:00 2001 From: "Moe Charm (CI)" Date: Sat, 29 Nov 2025 08:12:08 +0900 Subject: [PATCH] Cleanup: Fix 2 additional Class 0/7 header bugs (correctness fix) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task Agent Investigation: - Found 2 more instances of hardcoded `class_idx != 7` checks - These are real bugs (C0 also uses offset=0, not just C7) - However, NOT the root cause of 12% crash rate Bug Fixes (2 locations): 1. tls_sll_drain_box.h:190 - Path: TLS SLL drain → tiny_free_local_box() - Fix: Use tiny_header_write_for_alloc() (ALL classes) - Reason: tiny_free_local_box() reads header for class_idx 2. hakmem_tiny_refill.inc.h:384 - Path: SuperSlab refill → TLS SLL push - Fix: Use tiny_header_write_if_preserved() (C1-C6 only) - Reason: TLS SLL push needs header for validation Test Results: - Before: 12% crash rate (88/100 runs successful) - After: 12% crash rate (44/50 runs successful) - Conclusion: Correctness fix, but not primary crash cause Analysis: - Bugs are real (incorrect Class 0 handling) - Fixes don't reduce crash rate → different root cause exists - Heisenbug characteristics (disappears under gdb) - Likely: Race condition, uninitialized memory, or use-after-free Remaining Work: - 12% crash rate persists (requires different investigation) - Next: Focus on TLS initialization, race conditions, allocation paths Design Note: - tls_sll_drain_box.h uses tiny_header_write_for_alloc() because tiny_free_local_box() needs header to read class_idx - hakmem_tiny_refill.inc.h uses tiny_header_write_if_preserved() because TLS SLL push validates header (C1-C6 only) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- core/box/tls_sll_drain_box.h | 10 +++++----- core/hakmem_tiny_refill.inc.h | 10 ++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/core/box/tls_sll_drain_box.h b/core/box/tls_sll_drain_box.h index 243ca119..b8903ddc 100644 --- a/core/box/tls_sll_drain_box.h +++ b/core/box/tls_sll_drain_box.h @@ -26,8 +26,10 @@ #include #include #include "tls_sll_box.h" // TLS SLL operations (tls_sll_pop) +#include "tiny_header_box.h" // Header Box: Single Source of Truth for header operations #include "../hakmem_tiny_config.h" // TINY_NUM_CLASSES #include "../hakmem_super_registry.h" // SuperSlab lookup +#include "../tiny_region_id.h" // HEADER_MAGIC, HEADER_CLASS_MASK #include "free_local_box.h" // tiny_free_local_box (decrements meta->used) // ========== ENV Configuration ========== @@ -182,12 +184,10 @@ static inline uint32_t tiny_tls_sll_drain(int class_idx, uint32_t batch_size) { // Get slab metadata TinySlabMeta* meta = &ss->slabs[slab_idx]; - // CRITICAL FIX: Restore header for C0-C6 BEFORE calling tiny_free_local_box() + // CRITICAL FIX: Restore header BEFORE calling tiny_free_local_box() // This ensures tiny_free_local_box() can read class_idx from header - // C7: skip (offset=0 - header overwritten by next) - if (class_idx != 7) { - *(uint8_t*)base = HEADER_MAGIC | (class_idx & HEADER_CLASS_MASK); - } + // Uses Header Box API (ALL classes - tiny_free_local_box needs header) + tiny_header_write_for_alloc(base, class_idx); // Convert BASE → USER pointer (add 1 byte header offset) // Phase E1: ALL classes (C0-C7) have 1-byte header diff --git a/core/hakmem_tiny_refill.inc.h b/core/hakmem_tiny_refill.inc.h index fc98457f..5caf1a64 100644 --- a/core/hakmem_tiny_refill.inc.h +++ b/core/hakmem_tiny_refill.inc.h @@ -18,6 +18,7 @@ #include "tiny_box_geometry.h" #include "superslab/superslab_inline.h" #include "box/tls_sll_box.h" +#include "box/tiny_header_box.h" // Header Box: Single Source of Truth for header operations #include "hakmem_tiny_integrity.h" #include "box/tiny_next_ptr_box.h" #include "tiny_region_id.h" // For HEADER_MAGIC/HEADER_CLASS_MASK (prepare header before SLL push) @@ -379,12 +380,9 @@ int sll_refill_small_from_ss(int class_idx, int max_take) tiny_debug_validate_node_base(class_idx, p, "sll_refill_small_from_ss"); // Prepare header for header-classes so that safeheader mode accepts the push - // C0-C6: Restore header (offset=1 layout). C7: skip (offset=0 - header overwritten by next). -#if HAKMEM_TINY_HEADER_CLASSIDX - if (class_idx != 7) { - *(uint8_t*)p = HEADER_MAGIC | (class_idx & HEADER_CLASS_MASK); - } -#endif + // Uses Header Box API (C1-C6 only; C0/C7 skip - offset=0 overwrites header) + tiny_header_write_if_preserved(p, class_idx); + // SLL push 失敗時はそれ以上積まない(p はTLS slab管理下なので破棄でOK) if (!tls_sll_push(class_idx, p, cap)) { break;