From e4868bf236ccd0a6616b164f15987eb30294442c Mon Sep 17 00:00:00 2001 From: "Moe Charm (CI)" Date: Thu, 27 Nov 2025 05:57:22 +0900 Subject: [PATCH] Larson crash investigation: Add freelist header write + abort() on duplicate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes 1. **TLS SLL duplicate detection** (core/box/tls_sll_box.h:381) - Changed 'return true' to 'abort()' to get backtrace on double-free - Enables precise root cause identification 2. **Freelist header write fix** (core/tiny_superslab_alloc.inc.h:159-169) - Added tiny_region_id_write_header() call in freelist allocation path - Previously only linear carve wrote headers → stale headers on reuse - Now both paths write headers consistently ## Root Cause Analysis Backtrace revealed true double-free pattern: - last_push_from=hak_tiny_free_fast_v2 (freed once) - last_pop_from=(null) (never allocated) - where=hak_tiny_free_fast_v2 (freed again!) Same pointer freed twice WITHOUT reallocation in between. ## Status - Freelist header fix: ✅ Implemented (necessary but not sufficient) - Double-free still occurs: ❌ Deeper investigation needed - Possible causes: User code bug, TLS drain race, remote free issue Next: Investigate allocation/free flow with enhanced tracing --- core/box/tls_sll_box.h | 4 ++-- core/tiny_superslab_alloc.inc.h | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/core/box/tls_sll_box.h b/core/box/tls_sll_box.h index 58f0167d..8537723d 100644 --- a/core/box/tls_sll_box.h +++ b/core/box/tls_sll_box.h @@ -377,8 +377,8 @@ static inline bool tls_sll_push_impl(int class_idx, void* ptr, uint32_t capacity g_tls_sll_last_writer[class_idx] ? g_tls_sll_last_writer[class_idx] : "(null)", where ? where : "(null)"); ptr_trace_dump_now("tls_sll_dup"); - // Treat as already free; do not push again. - return true; + // ABORT to get backtrace showing exact double-free location + abort(); } void* next; PTR_NEXT_READ("tls_sll_scan", class_idx, scan, 0, next); diff --git a/core/tiny_superslab_alloc.inc.h b/core/tiny_superslab_alloc.inc.h index 9a9ec60c..d5f37e1e 100644 --- a/core/tiny_superslab_alloc.inc.h +++ b/core/tiny_superslab_alloc.inc.h @@ -155,7 +155,18 @@ static inline void* superslab_alloc_from_slab(SuperSlab* ss, int slab_idx) { tiny_remote_track_on_alloc(ss, slab_idx, block, "freelist_alloc", 0); tiny_remote_assert_not_remote(ss, slab_idx, block, "freelist_alloc_ret", 0); } - return block; + + // CRITICAL FIX (Larson double-free): Write header for freelist allocations + // Problem: Freelist path was returning BASE without writing header + // Result: Stale headers from previous allocations → double-free on next free + // Solution: Always write header before returning (same as linear carve path) + void* user = +#if HAKMEM_TINY_HEADER_CLASSIDX + tiny_region_id_write_header(block, meta->class_idx); +#else + block; +#endif + return user; } return NULL;