Larson double-free investigation: Add full operation lifecycle logging
**Diagnostic Enhancement**: Complete malloc/free/pop operation tracing for debug **Problem**: Larson crashes with TLS_SLL_DUP at count=18, need to trace exact pointer lifecycle to identify if allocator returns duplicate addresses or if benchmark has double-free bug. **Implementation** (ChatGPT + Claude + Task collaboration): 1. **Global Operation Counter** (core/hakmem_tiny_config_box.inc:9): - Single atomic counter for all operations (malloc/free/pop) - Chronological ordering across all paths 2. **Allocation Logging** (core/hakmem_tiny_config_box.inc:148-161): - HAK_RET_ALLOC macro enhanced with operation logging - Logs first 50 class=1 allocations with ptr/base/tls_count 3. **Free Logging** (core/tiny_free_fast_v2.inc.h:222-235): - Added before tls_sll_push() call (line 221) - Logs first 50 class=1 frees with ptr/base/tls_count_before 4. **Pop Logging** (core/box/tls_sll_box.h:587-597): - Added in tls_sll_pop_impl() after successful pop - Logs first 50 class=1 pops with base/tls_count_after 5. **Drain Debug Logging** (core/box/tls_sll_drain_box.h:143-151): - Enhanced drain loop with detailed logging - Tracks pop failures and drained block counts **Initial Findings**: - First 19 operations: ALL frees, ZERO allocations, ZERO pops - OP#0006: First free of 0x...430 - OP#0018: Duplicate free of 0x...430 → TLS_SLL_DUP detected - Suggests either: (a) allocations before logging starts, or (b) Larson bug **Debug-only**: All logging gated by !HAKMEM_BUILD_RELEASE (zero cost in release) **Next Steps**: - Expand logging window to 200 operations - Log initialization phase allocations - Cross-check with Larson benchmark source **Status**: Ready for extended testing
This commit is contained in:
@ -2,6 +2,12 @@
|
||||
// Box: Tiny allocator configuration, debug counters, and return helpers.
|
||||
// Extracted from hakmem_tiny.c to reduce file size and isolate config logic.
|
||||
|
||||
// ============================================================================
|
||||
// Global Operation Counter (for debug logging)
|
||||
// ============================================================================
|
||||
#include <stdatomic.h>
|
||||
_Atomic uint64_t g_debug_op_count = 0;
|
||||
|
||||
// ============================================================================
|
||||
// Size class table (Box 3 dependency)
|
||||
// ============================================================================
|
||||
@ -138,8 +144,21 @@ static inline void tiny_debug_track_alloc_ret(int cls, void* ptr);
|
||||
return (void*)((uint8_t*)(base_ptr) + 1); \
|
||||
} while(0)
|
||||
#else
|
||||
// Debug: Keep full validation via tiny_region_id_write_header()
|
||||
#define HAK_RET_ALLOC(cls, ptr) return tiny_region_id_write_header((ptr), (cls))
|
||||
// Debug: Keep full validation via tiny_region_id_write_header() + operation logging
|
||||
#define HAK_RET_ALLOC(cls, ptr) do { \
|
||||
extern _Atomic uint64_t g_debug_op_count; \
|
||||
extern __thread TinyTLSSLL g_tls_sll[]; \
|
||||
void* base_ptr = (ptr); \
|
||||
void* user_ptr = tiny_region_id_write_header(base_ptr, (cls)); \
|
||||
uint64_t op = atomic_fetch_add(&g_debug_op_count, 1); \
|
||||
if (op < 50 && (cls) == 1) { \
|
||||
fprintf(stderr, "[OP#%04lu ALLOC] cls=%d ptr=%p base=%p from=alloc tls_count=%u\n", \
|
||||
(unsigned long)op, (cls), user_ptr, base_ptr, \
|
||||
g_tls_sll[(cls)].count); \
|
||||
fflush(stderr); \
|
||||
} \
|
||||
return user_ptr; \
|
||||
} while(0)
|
||||
#endif
|
||||
#else
|
||||
// Legacy: Stats and routing before return
|
||||
|
||||
Reference in New Issue
Block a user