Fix: LIBC/HAKMEM mixed allocation crashes (0% → 80% success)
**Problem**: 4T Larson crashed 100% due to "free(): invalid pointer" **Root Causes** (6 bugs found via Task Agent ultrathink): 1. **Invalid magic fallback** (`hak_free_api.inc.h:87`) - When `hdr->magic != HAKMEM_MAGIC`, ptr came from LIBC (no header) - Was calling `free(raw)` where `raw = ptr - HEADER_SIZE` (garbage!) - Fixed: Use `__libc_free(ptr)` instead 2. **BigCache eviction** (`hakmem.c:230`) - Same issue: invalid magic means LIBC allocation - Fixed: Use `__libc_free(ptr)` directly 3. **Malloc wrapper recursion** (`hakmem_internal.h:209`) - `hak_alloc_malloc_impl()` called `malloc()` → wrapper recursion - Fixed: Use `__libc_malloc()` directly 4. **ALLOC_METHOD_MALLOC free** (`hak_free_api.inc.h:106`) - Was calling `free(raw)` → wrapper recursion - Fixed: Use `__libc_free(raw)` directly 5. **fopen/fclose crash** (`hakmem_tiny_superslab.c:131`) - `log_superslab_oom_once()` used `fopen()` → FILE buffer via wrapper - `fclose()` calls `__libc_free()` on HAKMEM-allocated buffer → crash - Fixed: Wrap with `g_hakmem_lock_depth++/--` to force LIBC path 6. **g_hakmem_lock_depth visibility** (`hakmem.c:163`) - Was `static`, needed by hakmem_tiny_superslab.c - Fixed: Remove `static` keyword **Result**: 4T Larson success rate improved 0% → 80% (8/10 runs) ✅ **Remaining**: 20% crash rate still needs investigation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -159,7 +159,8 @@ static inline int hak_ld_block_jemalloc(void) {
|
||||
// Box Theory - Layer 1 (API Layer):
|
||||
// This guard protects against LD_PRELOAD recursion (Box 1 → Box 1)
|
||||
// Box 2 (Core) → Box 3 (Syscall) uses hkm_libc_malloc() (dlsym, no guard needed!)
|
||||
static __thread int g_hakmem_lock_depth = 0; // 0 = outermost call
|
||||
// NOTE: Removed 'static' to allow access from hakmem_tiny_superslab.c (fopen fix)
|
||||
__thread int g_hakmem_lock_depth = 0; // 0 = outermost call
|
||||
|
||||
int hak_in_wrapper(void) {
|
||||
return g_hakmem_lock_depth > 0; // Simple and correct!
|
||||
@ -223,7 +224,11 @@ static void bigcache_free_callback(void* ptr, size_t size) {
|
||||
// Verify magic before accessing method field
|
||||
if (hdr->magic != HAKMEM_MAGIC) {
|
||||
fprintf(stderr, "[hakmem] BigCache eviction: invalid magic, fallback to free()\n");
|
||||
free(raw);
|
||||
// CRITICAL FIX: When magic is invalid, allocation came from LIBC (NO header)
|
||||
// Therefore ptr IS the allocated address, not raw (ptr - HEADER_SIZE)
|
||||
// MUST use __libc_free to avoid infinite recursion through free() wrapper
|
||||
extern void __libc_free(void*);
|
||||
__libc_free(ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user