Skip to content
DebugAllocator

DebugAllocator

Description

DebugAllocator struct. Owns its heap / meta / page backing allocators inline; no external parent / meta to pass at init. Init-by-value via DebugAllocatorInit().

Usage example (Cross-references)

Usage examples (Cross-references)
        typedef struct SlabAllocator   SlabAllocator;
        typedef struct BudgetAllocator BudgetAllocator;
        typedef struct DebugAllocator  DebugAllocator;
    
        // `zeroed` uses `i8` (signed char) directly instead of `bool` to
        size  budget_allocator_deallocate(BudgetAllocator *self, void *ptr);
    
        void *debug_allocator_allocate(DebugAllocator *self, size bytes, i8 zeroed);
        i8    debug_allocator_resize(DebugAllocator *self, void *ptr, size new_size);
        void *debug_allocator_remap(DebugAllocator *self, void *ptr, size new_size);
    
        void *debug_allocator_allocate(DebugAllocator *self, size bytes, i8 zeroed);
        i8    debug_allocator_resize(DebugAllocator *self, void *ptr, size new_size);
        void *debug_allocator_remap(DebugAllocator *self, void *ptr, size new_size);
        size  debug_allocator_deallocate(DebugAllocator *self, void *ptr);
        void *debug_allocator_allocate(DebugAllocator *self, size bytes, i8 zeroed);
        i8    debug_allocator_resize(DebugAllocator *self, void *ptr, size new_size);
        void *debug_allocator_remap(DebugAllocator *self, void *ptr, size new_size);
        size  debug_allocator_deallocate(DebugAllocator *self, void *ptr);
        i8    debug_allocator_resize(DebugAllocator *self, void *ptr, size new_size);
        void *debug_allocator_remap(DebugAllocator *self, void *ptr, size new_size);
        size  debug_allocator_deallocate(DebugAllocator *self, void *ptr);
    
        ///
            SlabAllocator *: (Allocator *)(allocator_ptr),                                                                 \
            BudgetAllocator *: (Allocator *)(allocator_ptr),                                                               \
            DebugAllocator *: (Allocator *)(allocator_ptr)                                                                 \
        )
    ///
    #define AllocatorAlloc(self, bytes, zeroed)                                                                                                                                                                                                                                                                                \
        _Generic((self), HeapAllocator *: heap_allocator_allocate, PageAllocator *: page_allocator_allocate, ArenaAllocator *: arena_allocator_allocate, SlabAllocator *: slab_allocator_allocate, BudgetAllocator *: budget_allocator_allocate, DebugAllocator *: debug_allocator_allocate, Allocator *: AllocatorAlloc_dyn)( \
            (self),                                                                                                                                                                                                                                                                                                            \
            (bytes),                                                                                                                                                                                                                                                                                                           \
    ///
    #define AllocatorResize(self, ptr, new_size)                                                                                                                                                                                                                                                                    \
        _Generic((self), HeapAllocator *: heap_allocator_resize, PageAllocator *: page_allocator_resize, ArenaAllocator *: arena_allocator_resize, SlabAllocator *: slab_allocator_resize, BudgetAllocator *: budget_allocator_resize, DebugAllocator *: debug_allocator_resize, Allocator *: AllocatorResize_dyn)( \
            (self),                                                                                                                                                                                                                                                                                                 \
            (ptr),                                                                                                                                                                                                                                                                                                  \
    ///
    #define AllocatorRemap(self, ptr, new_size)                                                                                                                                                                                                                                                              \
        _Generic((self), HeapAllocator *: heap_allocator_remap, PageAllocator *: page_allocator_remap, ArenaAllocator *: arena_allocator_remap, SlabAllocator *: slab_allocator_remap, BudgetAllocator *: budget_allocator_remap, DebugAllocator *: debug_allocator_remap, Allocator *: AllocatorRemap_dyn)( \
            (self),                                                                                                                                                                                                                                                                                          \
            (ptr),                                                                                                                                                                                                                                                                                           \
    ///
    #define AllocatorFree(self, ptr)                                                                                                                                                                                                                                                                                                      \
        _Generic((self), HeapAllocator *: heap_allocator_deallocate, PageAllocator *: page_allocator_deallocate, ArenaAllocator *: arena_allocator_deallocate, SlabAllocator *: slab_allocator_deallocate, BudgetAllocator *: budget_allocator_deallocate, DebugAllocator *: debug_allocator_deallocate, Allocator *: AllocatorFree_dyn)( \
            (self),                                                                                                                                                                                                                                                                                                                       \
            (ptr)                                                                                                                                                                                                                                                                                                                         \
    
    #if FEATURE_DEFAULT_ALLOC_DEBUG
        typedef DebugAllocator DefaultAllocator;
    #else
    typedef HeapAllocator DefaultAllocator;
            u64                  bytes_in_use;
            u64                  creator_tid;
        } DebugAllocator;
    
        // Vtable functions, exposed because the Init macro stamps them
        /// TAGS: Allocator, Debug, Memory, Allocation
        ///
        void *debug_allocator_allocate(DebugAllocator *self, size bytes, i8 zeroed);
    
        ///
        /// TAGS: Allocator, Debug, Memory, InPlace
        ///
        i8 debug_allocator_resize(DebugAllocator *self, void *ptr, size new_size);
    
        ///
        /// TAGS: Allocator, Debug, Memory, Reallocation
        ///
        void *debug_allocator_remap(DebugAllocator *self, void *ptr, size new_size);
    
        ///
        /// TAGS: Allocator, Debug, Memory, Deallocation
        ///
        size debug_allocator_deallocate(DebugAllocator *self, void *ptr);
    
        ///
        /// TAGS: Allocator, Debug, Cleanup
        ///
        void DebugAllocatorDeinit(DebugAllocator *self);
    
        ///
        /// TAGS: Allocator, Debug, Observability
        ///
        size DebugAllocatorLiveCount(const DebugAllocator *self);
    
        ///
        /// TAGS: Allocator, Debug, Observability
        ///
        size DebugAllocatorLiveBytes(const DebugAllocator *self);
    
        ///
        /// TAGS: Allocator, Debug, Observability
        ///
        size DebugAllocatorOverflows(const DebugAllocator *self);
    
        ///
        /// TAGS: Allocator, Debug, Observability
        ///
        size DebugAllocatorFreedCount(const DebugAllocator *self);
    
        ///
        /// TAGS: Allocator, Debug, Reporting
        ///
        void DebugAllocatorReportLeaks(DebugAllocator *self, Str *out);
    
    #ifdef __cplusplus
    ///
    #define DebugAllocatorInitWith(_cfg)                                                                                   \
        ((DebugAllocator) {                                                                                                \
            .base =                                                                                                        \
                {.allocate        = (AllocatorAllocateFn)debug_allocator_allocate,                                         \
    // ---------------------------------------------------------------------------
    
    static void debug_validate_self_structural(const DebugAllocator *self) {
        if (!self->base.allocate || !self->base.resize || !self->base.remap || !self->base.deallocate) {
            LOG_FATAL("DebugAllocator: vtable function pointer is NULL");
    static void debug_validate_self_structural(const DebugAllocator *self) {
        if (!self->base.allocate || !self->base.resize || !self->base.remap || !self->base.deallocate) {
            LOG_FATAL("DebugAllocator: vtable function pointer is NULL");
        }
        if (self->base.alignment == 0 || (self->base.alignment & (self->base.alignment - 1)) != 0) {
        }
        if (self->base.alignment == 0 || (self->base.alignment & (self->base.alignment - 1)) != 0) {
            LOG_FATAL("DebugAllocator: alignment {} is not a positive power of two", (u64)self->base.alignment);
        }
        // Embedded backing allocators must themselves be sane. We don't
        // masks the memo bit so neither memoized state breaks the check.
        if (!MAGIC_MATCHES(self->heap.base.__magic, HEAP_ALLOCATOR_MAGIC)) {
            LOG_FATAL("DebugAllocator: embedded heap has bad magic");
        }
        if (!MAGIC_MATCHES(self->meta.base.__magic, HEAP_ALLOCATOR_MAGIC)) {
        }
        if (!MAGIC_MATCHES(self->meta.base.__magic, HEAP_ALLOCATOR_MAGIC)) {
            LOG_FATAL("DebugAllocator: embedded meta has bad magic");
        }
        if (!MAGIC_MATCHES(self->page.base.__magic, PAGE_ALLOCATOR_MAGIC)) {
        }
        if (!MAGIC_MATCHES(self->page.base.__magic, PAGE_ALLOCATOR_MAGIC)) {
            LOG_FATAL("DebugAllocator: embedded page has bad magic");
        }
        if (!MAGIC_MATCHES(self->live.__magic, MAP_MAGIC)) {
        }
        if (!MAGIC_MATCHES(self->live.__magic, MAP_MAGIC)) {
            LOG_FATAL("DebugAllocator: live map has bad magic");
        }
        if (!MAGIC_MATCHES(self->freed.__magic, VEC_MAGIC)) {
        }
        if (!MAGIC_MATCHES(self->freed.__magic, VEC_MAGIC)) {
            LOG_FATAL("DebugAllocator: freed vec has bad magic");
        }
        // bytes_in_use must be consistent with live: if live is non-empty
        // every byte has been returned.
        if (MapPairCount(&self->live) == 0 && self->bytes_in_use != 0) {
            LOG_FATAL("DebugAllocator: bytes_in_use {} with no live records", (u64)self->bytes_in_use);
        }
        u64 cur_tid = debug_current_tid();
        if (self->creator_tid != cur_tid) {
            LOG_FATAL(
                "DebugAllocator: cross-thread use detected (created on {x}, called from {x}). "
                "Each thread must use its own DebugAllocator instance.",
                self->creator_tid,
            LOG_FATAL(
                "DebugAllocator: cross-thread use detected (created on {x}, called from {x}). "
                "Each thread must use its own DebugAllocator instance.",
                self->creator_tid,
                cur_tid
    }
    
    static void debug_validate_self(const DebugAllocator *self) {
        if (!self) {
            LOG_FATAL("DebugAllocator: NULL self");
    static void debug_validate_self(const DebugAllocator *self) {
        if (!self) {
            LOG_FATAL("DebugAllocator: NULL self");
        }
        if (!MAGIC_MATCHES(self->base.__magic, DEBUG_ALLOCATOR_MAGIC)) {
        }
        if (!MAGIC_MATCHES(self->base.__magic, DEBUG_ALLOCATOR_MAGIC)) {
            LOG_FATAL("type-confusion: allocator passed to debug_allocator_* is not a DebugAllocator");
        }
        // Lazy-bind the embedded Map/Vec's `.allocator` pointer. The
        // intentional bypass: Debug allocator swap; no public MapSetAllocator mutator.
        if (!self->live.allocator) {
            ((DebugAllocator *)(void *)self)->live.allocator = ALLOCATOR_OF(&((DebugAllocator *)(void *)self)->meta);
        }
        if (!self->freed.allocator) {
        }
        if (!self->freed.allocator) {
            ((DebugAllocator *)(void *)self)->freed.allocator = ALLOCATOR_OF(&((DebugAllocator *)(void *)self)->meta);
        }
        if (!(self->base.__magic & MAGIC_VALIDATED_BIT)) {
        }
        debug_validate_self_structural(self);
        ((DebugAllocator *)(void *)self)->base.__magic &= ~MAGIC_VALIDATED_BIT;
    }
    // want the bookkeeping cost.
    
    static const DebugFreedEntry *debug_freed_find(const DebugAllocator *dbg, void *ptr) {
        for (u32 i = 0; i < VecLen(&dbg->freed); i++) {
            if (VecPtrAt(&dbg->freed, i)->ptr == ptr)
    // ---------------------------------------------------------------------------
    
    void *debug_allocator_allocate(DebugAllocator *self, size bytes, i8 zeroed) {
        debug_validate_self(self);
        if (!bytes)
            else
                AllocatorFree(&self->heap, user_p);
            LOG_ERROR("DebugAllocator: failed to record allocation in live map");
    #if FEATURE_ALLOC_STATS
            self->base.stats.failed_allocations += 1u;
    // underlying HeapAllocator (which LOG_FATALs with its bitmap-state
    // diagnostic for the cases freed history can't recognize).
    size debug_allocator_deallocate(DebugAllocator *self, void *ptr) {
        debug_validate_self(self);
        if (!ptr)
            if (fe) {
                LOG_ERROR(
                    "DebugAllocator: DOUBLE FREE of {x} (originally {} bytes); original alloc + first-free traces:",
                    (u64)ptr,
                    (u64)fe->requested_size
                debug_emit_trace(fe->alloc_trace, fe->alloc_trace_n, "alloc", ALLOCATOR_OF(&self->meta));
                debug_emit_trace(fe->free_trace, fe->free_trace_n, "first-free", ALLOCATOR_OF(&self->meta));
                LOG_FATAL("DebugAllocator: double-free of {x}", (u64)ptr);
                return 0;
            }
                self->overflows += 1;
                LOG_ERROR(
                    "DebugAllocator: BUFFER OVERFLOW past {x} ({} bytes requested)",
                    (u64)ptr,
                    (u64)live_rec->requested_size
            size rounded   = (padded + page_size - 1) & ~(page_size - 1);
            if (!PageProtect(ptr, rounded, PAGE_PROT_NONE)) {
                LOG_ERROR("DebugAllocator: PageProtect(PROT_NONE) failed on {x}", (u64)ptr);
            }
        } else {
    // does the clean alloc-fresh + copy + free dance with full canary +
    // live-map maintenance.
    i8 debug_allocator_resize(DebugAllocator *self, void *ptr, size new_size) {
        debug_validate_self(self);
        (void)ptr;
    }
    
    void *debug_allocator_remap(DebugAllocator *self, void *ptr, size new_size) {
        debug_validate_self(self);
        if (new_size == 0) {
    // ---------------------------------------------------------------------------
    
    void DebugAllocatorDeinit(DebugAllocator *self) {
        if (!self || !MAGIC_MATCHES(self->base.__magic, DEBUG_ALLOCATOR_MAGIC))
            return;
        if (self->creator_tid != cur_tid) {
            LOG_FATAL(
                "DebugAllocator: Deinit called from a different thread (created on {x}, called from {x}).",
                self->creator_tid,
                cur_tid
        // Report leaks for anything still in `live`.
        if (MapAllocator(&self->live) && MapPairCount(&self->live) > 0) {
            LOG_ERROR("DebugAllocator: {} live allocation(s) at deinit time:", (u64)MapPairCount(&self->live));
            MapForeachPairPtr(&self->live, key_ptr, val_ptr) {
                LOG_ERROR("  leaked {x} ({} bytes)", (u64)*key_ptr, (u64)val_ptr->requested_size);
    // ---------------------------------------------------------------------------
    
    size DebugAllocatorLiveCount(const DebugAllocator *self) {
        if (!self)
            return 0;
    }
    
    size DebugAllocatorLiveBytes(const DebugAllocator *self) {
        if (!self)
            return 0;
    }
    
    size DebugAllocatorOverflows(const DebugAllocator *self) {
        if (!self)
            return 0;
    }
    
    size DebugAllocatorFreedCount(const DebugAllocator *self) {
        if (!self)
            return 0;
    }
    
    void DebugAllocatorReportLeaks(DebugAllocator *self, Str *out) {
        if (!self || !out)
            return;
            return;
    
        StrAppendFmt(out, "DebugAllocator: {} live allocation(s):\n", (u64)MapPairCount(&self->live));
        MapForeachPairPtr(&self->live, key_ptr, val_ptr) {
            StrAppendFmt(out, "  leak: {x} ({} bytes)\n", (u64)*key_ptr, (u64)val_ptr->requested_size);
    // ===========================================================================
    static bool test_multiblock_directory_no_overrun(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // ===========================================================================
    static bool test_many_sections_no_overrun(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
            return false;
    
        DebugAllocator alloc    = DebugAllocatorInit();
        size           baseline = DebugAllocatorLiveCount(&alloc);
    
    bool test_hl_headers_vec_deinit_releases_values(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_hl_request_deinit_releases_url(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_hl_respond_with_html_releases_old_body(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_hl_respond_with_file_releases_old_body(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // re-opens the module -> live count rises.
    bool test_sr_cache_hit_same_module(void) {
        DebugAllocator alloc = DebugAllocatorInit();
        SymbolResolver res;
        if (!SymbolResolverInit(&res, ALLOCATOR_OF(&alloc))) {
    // re-open. A mutant breaking `ZstrCompare(...) == 0` misses and re-opens.
    bool test_sr_cache_zstrcompare_fallback(void) {
        DebugAllocator alloc = DebugAllocatorInit();
        SymbolResolver res;
        if (!SymbolResolverInit(&res, ALLOCATOR_OF(&alloc))) {
    // address -> wrong module_path and no second open.
    bool test_sr_cache_cross_module_distinct(void) {
        DebugAllocator alloc = DebugAllocatorInit();
        SymbolResolver res;
        if (!SymbolResolverInit(&res, ALLOCATOR_OF(&alloc))) {
    // loop must walk PAST entry[0]; nothing re-opens.
    bool test_sr_cache_other_module_rehit(void) {
        DebugAllocator alloc = DebugAllocatorInit();
        SymbolResolver res;
        if (!SymbolResolverInit(&res, ALLOCATOR_OF(&alloc))) {
    // frees everything and the live count returns to the pre-Init baseline.
    bool test_sr_deinit_frees_everything(void) {
        DebugAllocator alloc    = DebugAllocatorInit();
        size           baseline = DebugAllocatorLiveCount(&alloc);
    // elevated.
    static bool test_sd4_deinit_no_leak(void) {
        DebugAllocator alloc    = DebugAllocatorInit();
        Allocator     *a        = ALLOCATOR_OF(&alloc);
        size           baseline = DebugAllocatorLiveCount(&alloc);
    
    bool test_from_f64_negative_binexp_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v = FloatFrom(0.5, &dbg.base); // binexp < 0 -> 5^|binexp| path
    
    bool test_from_f32_negative_binexp_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v = FloatFrom(1.5f, &dbg.base); // binexp < 0 -> 5^|binexp| path
    
    bool test_normalize_trailing_zeros_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v = FloatFrom(1000u, &dbg.base); // 1000 -> significand 1, exp 3
    
    bool test_pow10_success_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v = FloatFromStr("1e3", &dbg.base); // exponent 3 > 0 -> pow10
    
    bool test_to_int_positive_exponent_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v = FloatFromStr("12e4", &dbg.base); // significand 12, exp 4
    
    bool test_to_int_negative_exponent_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v = FloatFromStr("150e-1", &dbg.base); // 15.0, exact integer 15
    
    bool test_to_int_zero_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v = FloatFrom(0u, &dbg.base);
    
    bool test_add_scaling_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float a = FloatFromStr("1.5", &dbg.base);   // exp -1
    
    bool test_add_replace_prepopulated_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float a = FloatFromStr("2.5", &dbg.base);
    
    bool test_add_cancel_to_zero_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float a = FloatFromStr("7.25", &dbg.base);
    
    bool test_compare_abs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float a = FloatFromStr("1.5", &dbg.base);
    
    bool test_to_str_fractional_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v   = FloatFromStr("12.5", &dbg.base);
    
    bool test_to_str_integer_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v   = FloatFromStr("1200", &dbg.base); // exponent >= 0 arm
    
    bool test_from_str_prepopulated_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v = FloatFromStr("99999", &dbg.base); // pre-populated target
    
    bool test_div_success_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float a = FloatFromStr("1", &dbg.base);
    
    bool test_div_zero_dividend_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float a = FloatFrom(0u, &dbg.base);
    
    bool test_mul_replace_prepopulated_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float a = FloatFromStr("2.5", &dbg.base);
    // float_add_int  [970:5]
    bool test_add_int_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_add_u64  [981:5]
    bool test_add_u64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_add_i64  [992:5]
    bool test_add_i64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_add_f32  [1003:5]
    bool test_add_f32_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_add_f64  [1014:5]
    bool test_add_f64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_sub (Float*Float): FloatDeinit(&rhs) negated clone  [1030:5]
    bool test_sub_float_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("5.5", &dbg.base);
        Float          b   = FloatFromStr("1.25", &dbg.base);
    // float_sub_int  [1041:5]
    bool test_sub_int_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("5.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_sub_u64  [1052:5]
    bool test_sub_u64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("5.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_sub_i64  [1063:5]
    bool test_sub_i64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("5.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_sub_f32  [1074:5]
    bool test_sub_f32_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("5.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_sub_f64  [1085:5]
    bool test_sub_f64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("5.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_mul_int  [1115:5]
    bool test_mul_int_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_mul_u64  [1126:5]
    bool test_mul_u64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_mul_i64  [1137:5]
    bool test_mul_i64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_mul_f32  [1148:5]
    bool test_mul_f32_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_mul_f64  [1159:5]
    bool test_mul_f64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1.5", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_div_int  [1216:5]
    bool test_div_int_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_div_u64  [1228:5]
    bool test_div_u64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_div_i64  [1240:5]
    bool test_div_i64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_div_f32  [1252:5]
    bool test_div_f32_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_div_f64  [1264:5]
    bool test_div_f64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("1", &dbg.base);
        Float          r   = FloatInit(&dbg.base);
    // float_compare_int_with_error  [773:5]
    bool test_compare_int_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("3.5", &dbg.base);
        Int            b   = IntFrom(3, &dbg.base);
    // float_compare_u64_with_error  [798:5]
    bool test_compare_u64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("3.5", &dbg.base);
    // float_compare_i64_with_error  [823:5]
    bool test_compare_i64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("-3.5", &dbg.base);
    // float_compare_f32_with_error  [848:5]
    bool test_compare_f32_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("3.5", &dbg.base);
    // float_compare_f64_with_error  [873:5]
    bool test_compare_f64_rhs_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          a   = FloatFromStr("3.5", &dbg.base);
    
    bool test_to_int_negative_exponent_factor_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        Float v = FloatFromStr("1.5", &dbg.base); // significand 15, exponent -1
    // ---------------------------------------------------------------------------
    bool test_pm_find_by_addr_no_overrun(void) {
        DebugAllocator alloc = DebugAllocatorInit();
        ProcMaps       pm;
        MemSet(&pm, 0, sizeof(pm));
    // =============================================================================
    
    static DebugAllocator blind_debug_alloc(void) {
        DebugAllocatorConfig cfg = {.capture_traces = false, .detect_overflow = false, .track_freed_history = false};
        return DebugAllocatorInitWith(cfg);
    // Lean DebugAllocator config used by the leak-detecting tests: no trace
    // capture / overflow / freed-history bookkeeping, just live-count tracking.
    static DebugAllocator make_lean_debug_allocator(void) {
        DebugAllocatorConfig cfg = {.capture_traces = false, .detect_overflow = false, .track_freed_history = false};
        return DebugAllocatorInitWith(cfg);
        WriteFmt("Testing grow-path copy failure frees the node-data buffer (no leak)\n");
    
        DebugAllocator dbg = make_lean_debug_allocator();
    
        typedef Graph(int) IntGraph;
        WriteFmt("Testing reuse-path copy failure frees the node-data buffer (no leak)\n");
    
        DebugAllocator dbg = make_lean_debug_allocator();
    
        typedef Graph(int) IntGraph;
    // ---------------------------------------------------------------------------
    bool test_leak_record_target_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_leak_authority_list_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_leak_additional_list_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // torn down.
    #define DBG_BEGIN(dbg, out)                                                                                            \
        DebugAllocator dbg = DebugAllocatorInit();                                                                         \
        Str            out = StrInit(&dbg)
    
    // Tear down `out`, then assert no scratch leaked, then deinit the allocator.
    static bool dbg_no_leak(DebugAllocator *dbg, Str *out) {
        StrDeinit(out);
        bool ok = (DebugAllocatorLiveCount(dbg) == 0);
    // ===========================================================================
    static bool test_read_zstr_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        char          *s   = NULL;
        Zstr           in  = "hello world";
    // dtor leak.
    static bool test_read_bitvec_hex(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        BitVec         bv  = BitVecInit(&dbg.base);
        Zstr           z   = "0x1";
    // 3145/3154 scratch leak, 3150:21 lt_to_le `bit_len < 3` (octal min width).
    static bool test_read_bitvec_octal(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        BitVec         bv  = BitVecInit(&dbg.base);
        Zstr           z   = "0o1";
    // 3178 scratch leak for the binary path.
    static bool test_read_bitvec_binary(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        BitVec         bv  = BitVecInit(&dbg.base);
        Zstr           z   = "10110";
    // scratch leak, value round-trip.
    static bool test_read_int_plain(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        Int            v   = IntInit(&dbg.base);
        Zstr           z   = "12345";
    // ===========================================================================
    static bool test_read_float_value(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        Float          f   = FloatInit(&dbg.base);
        Zstr           z   = "3.14159";
    // the sentinel and frees scratch.
    static bool test_read_float_reject_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        Float          f   = FloatInit(&dbg.base);
        (void)FloatTryFromStr(&f, "42");
    
    bool test_debug_normal_alloc_free(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_debug_zero_byte_alloc(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_debug_null_free_is_noop(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_debug_catches_overflow(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_debug_leak_count(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_debug_report_leaks_emits_traces(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_debug_alloc_trace_captured(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_debug_freed_history_grows_on_free(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
        DebugAllocatorConfig cfg = DEBUG_ALLOCATOR_DEFAULTS;
        cfg.track_freed_history  = false;
        DebugAllocator dbg       = DebugAllocatorInitWith(cfg);
        Allocator     *adbg      = ALLOCATOR_OF(&dbg);
    
    bool test_debug_remap_grows(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_debug_remap_to_zero_frees(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_debug_remap_from_null_allocates(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
        DebugAllocatorConfig cfg = DEBUG_ALLOCATOR_DEFAULTS;
        cfg.force_page_backing   = true;
        DebugAllocator dbg       = DebugAllocatorInitWith(cfg);
        Allocator     *adbg      = ALLOCATOR_OF(&dbg);
    
    bool test_debug_double_free_aborts(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
        // live map -> forwarded to underlying Heap, which LOG_FATALs as
        // foreign pointer.
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad1_canary_detects_non_first_byte(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad1_freed_alloc_trace_n_copied(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad1_freed_alloc_trace_bytes_copied(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
        DebugAllocatorConfig cfg = DEBUG_ALLOCATOR_DEFAULTS;
        cfg.capture_traces       = false;
        DebugAllocator dbg       = DebugAllocatorInitWith(cfg);
        Allocator     *adbg      = ALLOCATOR_OF(&dbg);
        DebugAllocatorConfig cfg = DEBUG_ALLOCATOR_DEFAULTS;
        cfg.trace_depth          = 2;
        DebugAllocator dbg       = DebugAllocatorInitWith(cfg);
        Allocator     *adbg      = ALLOCATOR_OF(&dbg);
        DebugAllocatorConfig cfg = DEBUG_ALLOCATOR_DEFAULTS;
        cfg.trace_depth          = 20;
        DebugAllocator dbg       = DebugAllocatorInitWith(cfg);
        Allocator     *adbg      = ALLOCATOR_OF(&dbg);
    
    bool test_ad1_stats_deallocations_increment(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad1_stats_bytes_in_use_partial_free(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad1_clean_roundtrip_no_false_overflow(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad1_double_free_aborts(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad1_foreign_free_aborts(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad2_alloc_bumps_live_bytes(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad2_alloc_increments_allocations(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad2_alloc_accumulates_bytes_requested(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad2_alloc_bumps_stats_bytes_in_use(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad2_alloc_tracks_peak_value(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad2_peak_advances_on_first_alloc(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad2_peak_holds_historical_max(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad2_failed_alloc_counter(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // [1, MAX_TRACE]; a const 42 is out of range.
    bool test_ad2_trace_count_within_bounds(void) {
        DebugAllocator dbg  = DebugAllocatorInit(); // capture_traces, trace_depth=8
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
        DebugAllocatorConfig cfg = DEBUG_ALLOCATOR_DEFAULTS;
        cfg.trace_depth          = 4; // below MAX_TRACE
        DebugAllocator dbg       = DebugAllocatorInitWith(cfg);
        Allocator     *adbg      = ALLOCATOR_OF(&dbg);
        DebugAllocatorConfig cfg = DEBUG_ALLOCATOR_DEFAULTS;
        cfg.trace_depth          = 32; // above MAX_TRACE -> must clamp to 16
        DebugAllocator dbg       = DebugAllocatorInitWith(cfg);
        Allocator     *adbg      = ALLOCATOR_OF(&dbg);
    // inside [0, N)).
    bool test_ad2_full_width_write_is_clean(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // allocate returns a usable, correctly sized, zeroed region when asked.
    bool test_ad2_zeroed_region_is_zero_and_sized(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // broken hash would surface here as a spurious FATAL or a leak).
    bool test_ad2_hash_tracks_many_allocations(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // point shape; the validate gate is exercised by the deadend below.
    bool test_ad2_resize_refuses_in_place(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // Canary write side: alloc N, write N+1 -> overflow detected (counter).
    bool test_ad2_overflow_one_past_detected(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // would silently return 0 instead of aborting.
    bool test_ad2_resize_validates_self(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_ad3_remap_grow_preserves_full_old_width(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // canary (overflows stays 0); the mutant corrupts it.
    bool test_ad3_remap_shrink_copy_is_min_not_max(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // aborts; deadend captures it.
    bool test_ad3_remap_unknown_ptr_aborts(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // summary line and no frame markers.
    bool test_ad3_report_leaks_includes_trace_frames(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // Deadend: real code aborts here.
    bool test_ad3_structural_runs_on_first_entry(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        // Corrupt the embedded heap magic before the first validating entry
        // point; the validated bit is still set, so structural runs.
    // on) by the mutant. Normal test: real returns true; the mutant aborts.
    bool test_ad3_structural_skipped_after_first_op(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // trigger structural validation; real code accepts, the mutant aborts.
    bool test_ad3_structural_accepts_pow2_alignment(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        // Valid power-of-two alignment; validated bit still set so the first
        // entry runs structural and exercises the pow2 check.
    // `bytes!=0`) LOG_FATALs. Normal test: real returns true.
    bool test_ad3_structural_allows_live_allocation(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // Deadend: real code aborts here.
    bool test_af_structural_checks_page_magic(void) {
        DebugAllocator dbg = DebugAllocatorInit();
        // Corrupt the embedded page allocator's magic before the first
        // validating entry. The validated bit is still set, so structural
        cfg.capture_traces       = true;
        cfg.trace_depth          = 32; // above DEBUG_ALLOCATOR_MAX_TRACE (16)
        DebugAllocator dbg       = DebugAllocatorInitWith(cfg);
        Allocator     *adbg      = ALLOCATOR_OF(&dbg);
    // per-stream arrays / taken Buf leak.
    bool test_pd4_failed_open_frees_all(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // name-pool buffer leaks.
    bool test_pd4_deinit_frees_name_pool(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // live-allocation count returning to its pre-split baseline (Str.Mutants4).
    static bool test_str_deinit_releases_split_elements(void) {
        DebugAllocator dbg = DebugAllocatorInit();
    
        // Each piece is long enough to force its own heap buffer.
    static bool test_deinit_frees_buffer(void) {
        WriteFmt("Testing StrDeinit releases the backing allocation\n");
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // Lean DebugAllocator config used by leak round-trip tests: no trace
    // capture, no overflow canaries, no freed history -- just the live count.
    static DebugAllocator make_lean_dbg(void) {
        return DebugAllocatorInitWith(((DebugAllocatorConfig) {
            .capture_traces      = false,
    // holds a backing allocation.
    static bool test_blind_question_name_fail_no_leak(void) {
        DebugAllocator dbg = make_lean_dbg();
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    // hold backing allocations at that point.
    static bool test_blind_record_decode_fail_no_leak(void) {
        DebugAllocator dbg = make_lean_dbg();
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    static bool test_blind_pointer_truncated_rejected(void) {
        DebugAllocator dbg = make_lean_dbg();
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    // resolve to "zz" kills it.
    static bool test_blind_hops_max_boundary(void) {
        DebugAllocator dbg = make_lean_dbg();
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_deinit_frees_pending_edge_removals_backing_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInit();
    
        IntGraph graph = GraphInit(&dbg);
    
    bool test_mul_nonzero_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mul_zero_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_add_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_sub_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_add_u64_in_place_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mul_u64_in_place_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_sub_u64_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_div_mod_ge_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_div_mod_lt_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_div_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_div_exact_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_div_scalar_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_div_mod_scalar_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_int_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_to_str_radix_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_pow_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_gcd_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_lcm_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_root_rem_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_root_rem_inexact_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_root_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_is_perfect_square_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_is_perfect_power_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_jacobi_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_add_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sub_ge_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sub_lt_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sub_zero_diff_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_mul_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_square_mod_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_div_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_pow_u64_mod_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_pow_mod_integer_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_inv_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_inv_negative_t_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_inv_no_solution_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sqrt_p3mod4_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sqrt_tonelli_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sqrt_tonelli_larger_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sqrt_zero_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sqrt_mod2_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sqrt_no_solution_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sqrt_composite_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_mod_sqrt_even_modulus_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_is_probable_prime_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_is_probable_prime_witness_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_next_prime_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_next_prime_small_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    
    bool test_from_bytes_be_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
    
        u8  bytes[] = {0x01, 0x02, 0x03, 0x04};
    // out leaks its old buffer if the deinit is removed.
    bool test_from_str_nonempty_out_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    // result leaks its old buffer if the deinit is removed.
    bool test_mul_nonzero_nonempty_result_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    // but never int_div_exact_i64, so this divisor_value free went untested.
    bool test_div_exact_i64_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
    // across moduli with deep 2-adic valuation of (p-1) so the inner loop executes.
    bool test_mod_sqrt_tonelli_inner_loop_no_leak(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *a   = ALLOCATOR_OF(&dbg);
        WriteFmt("Testing BitVecRotateRight frees its temp clone (1157:5)\n");
    
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // find_pdb wrongly bail out -> false. We assert it returns true.
    static bool test_pc_find_pdb_basename_fallback(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // non-empty basename + sidecar present -> true; sidecar absent -> false.
    static bool test_pc_find_pdb_missing_sidecar_rejected(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // open succeeds, then removed.
    static bool test_pc_find_pdb_no_dirname_boundary(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // leaves `pdb_path` allocated -> live count > baseline.
    static bool test_pc_entry_open_failure_no_leak(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // pdb_open stays false.
    static bool test_pc_entry_open_bad_pdb_fails(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // matches, so a duplicate entry is appended -> VecLen grows to 2.
    static bool test_pc_cache_hit_no_duplicate_entry(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // exits), never matches B, and appends a duplicate -> VecLen grows to 3.
    static bool test_pc_cache_hit_with_second_module(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // loop body (0 >= 1 false) -> entries never freed -> leak.
    static bool test_pc_deinit_frees_all_entries(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // resolve as a guard but does not by itself kill 147.
    static bool test_pc_resolve_correct_symbol(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // We assert the resolve at ip == module_base SUCCEEDS (real `<`).
    static bool test_pc_resolve_at_module_base_boundary(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // We assert the resolve at rva64 == 0xFFFFFFFF SUCCEEDS (real `>`).
    static bool test_pc_resolve_max_rva_boundary(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // as the Zstr overload, AND that a rejected case returns false.
    static bool test_pc_resolve_str_matches_zstr(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    
    bool test_blind_stats_bytes_in_use_underflow_clamps_zero(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_blind_report_leaks_emits_all_frames(void) {
        DebugAllocator dbg  = DebugAllocatorInit(); // capture_traces on, depth 8
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_blind_report_leaks_no_extra_frame(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // removed-Deinit mutation observably.
    bool test_pm2_deinit_releases_all(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    static bool test_map_deep_copy_deinit_on_remove(void) {
        typedef Map(Zstr, Zstr) ZstrMap;
        DebugAllocator dbg = DebugAllocatorInit();
        // Deep-copy callbacks for both key and value, plus a value comparator
        // so the pair-level removal API is usable. The map owns Zstr clones it
        WriteFmt("Testing BitVecRotateLeft frees its temp clone (1131:5)\n");
    
        DebugAllocator dbg  = DebugAllocatorInitWith(lean_dbg_cfg());
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
        WriteFmt("Testing bitvec_regex_match_zstr frees its rendered Str (1866:5)\n");
    
        DebugAllocator dbg  = DebugAllocatorInitWith(lean_dbg_cfg());
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
        WriteFmt("Testing bitvec_regex_match_str frees its rendered Str (1883:5)\n");
    
        DebugAllocator dbg  = DebugAllocatorInitWith(lean_dbg_cfg());
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
        WriteFmt("Testing int_pow_mod frees internal temporaries\n");
    
        DebugAllocator dbg = DebugAllocatorInit();
    
        Int base         = IntFrom(123456789u, &dbg.base);
    // pins the build's success/failure result to an observable.
    bool test_bl_dwarf_resolves_no_leak(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // per-entry StrDeinit (54/141) and MachoDeinit (140) cleanups.
    bool test_mc_main_symtab_no_leak(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // compare (42 ZstrCompare->42).
    bool test_mc_cache_hit_and_distinct(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // count returns to baseline after deinit.
    bool test_mc_dsym_symtab_no_leak(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // path must not leak: the post-deinit live count returns to baseline.
    bool test_mc_dsym_uuid_mismatch_no_leak(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // Also drives DwarfFunctionsDeinit (136) on deinit; verified leak-free.
    bool test_mc_dwarf_resolves_and_no_leak(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // Modular inverse computes the right value and balances all allocations.
    bool test_blind_mod_inv_correct(void) {
        DebugAllocator dbg   = DebugAllocatorInitWith(blind_cfg());
        Allocator     *alloc = ALLOCATOR_OF(&dbg);
    // Tonelli-Shanks square root (modulus % 4 == 1) round-trips and balances.
    bool test_blind_mod_sqrt_tonelli(void) {
        DebugAllocator dbg   = DebugAllocatorInitWith(blind_cfg());
        Allocator     *alloc = ALLOCATOR_OF(&dbg);
    // Square root mod p with p % 4 == 3 (the fast-exponent branch).
    bool test_blind_mod_sqrt_fast_branch(void) {
        DebugAllocator dbg   = DebugAllocatorInitWith(blind_cfg());
        Allocator     *alloc = ALLOCATOR_OF(&dbg);
    // Modular subtraction across its three internal branches.
    bool test_blind_mod_sub_branches(void) {
        DebugAllocator dbg   = DebugAllocatorInitWith(blind_cfg());
        Allocator     *alloc = ALLOCATOR_OF(&dbg);
    // IntNextPrime returns the next prime and balances allocations.
    bool test_blind_next_prime(void) {
        DebugAllocator dbg   = DebugAllocatorInitWith(blind_cfg());
        Allocator     *alloc = ALLOCATOR_OF(&dbg);
    // Carmichael number 561 is composite; Miller-Rabin must not be fooled.
    bool test_blind_carmichael_is_composite(void) {
        DebugAllocator dbg   = DebugAllocatorInitWith(blind_cfg());
        Allocator     *alloc = ALLOCATOR_OF(&dbg);
    // the to_str_radix division loop that hosts several deleted-deinit mutants).
    bool test_blind_to_str_radix_big(void) {
        DebugAllocator dbg   = DebugAllocatorInitWith(blind_cfg());
        Allocator     *alloc = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    static bool test_sdm_resolv_buf_no_leak(void) {
        DebugAllocator alloc    = DebugAllocatorInit();
        Allocator     *a        = ALLOCATOR_OF(&alloc);
        size           baseline = DebugAllocatorLiveCount(&alloc);
    // remove-void-call shape; cheap to pin and keeps the parse buffers honest.
    static bool test_sdm_hosts_buf_no_leak(void) {
        DebugAllocator alloc    = DebugAllocatorInit();
        Allocator     *a        = ALLOCATOR_OF(&alloc);
        size           baseline = DebugAllocatorLiveCount(&alloc);
    // Asserting NULL kills the mutant.
    static bool test_pe_blind_find_empty_name_returns_null(void) {
        DebugAllocator alloc = DebugAllocatorInit();
        Allocator     *base  = ALLOCATOR_OF(&alloc);
    // ---------------------------------------------------------------------------
    bool test_leak_sci_nonzero_digits_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_leak_sci_zero_digits_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_leak_decimal_withdot_canonical_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_leak_decimal_nodot_canonical_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_leak_read_int_prior_value_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_leak_read_float_prior_value_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_leak_write_zstr_hex_per_byte_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_leak_write_i64_temp_freed(void) {
        DebugAllocator dbg  = DebugAllocatorInitWith(LEAK_CFG);
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    #define LEAK_WRITE_PRELUDE()                                                                                           \
        DebugAllocator dbg  = DebugAllocatorInitWith(LEAK_CFG);                                                            \
        Allocator     *adbg = ALLOCATOR_OF(&dbg);                                                                          \
        Str            out  = StrInit(adbg);                                                                               \
        for (int i = 0; i < 8; ++i)
            StrPushBackR(&s, (char)0xAB);
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Str            out = StrInit(ALLOCATOR_OF(&dbg));
        bool           ok  = StrAppendFmt(&out, "{x}", s) && (StrLen(&out) > 0);
    // closing quote -> unterminated-quote branch frees the destination Str.
    static bool leak_quoted_unterminated(Zstr input, Zstr fmt) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Str            s   = StrInit(ALLOCATOR_OF(&dbg));
        Zstr           p   = input;
    // 2439: unquoted invalid-escape error path frees the destination Str.
    bool test_leak_read_unquoted_bad_escape_freed(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Str            s   = StrInit(ALLOCATOR_OF(&dbg));
        Zstr           p   = "aaaaaaaaaaaaaaaaaaaaaaaa\\q"; // 24 'a' + invalid \q
    // scratch (allocated through the destination BitVec's allocator).
    static bool leak_bitvec_overflow(Zstr input) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        BitVec         bv  = BitVecInit(ALLOCATOR_OF(&dbg));
        Zstr           p   = input;
    // exponent overflow -> fail branch frees the internal `temp` scratch.
    bool test_leak_read_float_exp_overflow_freed(void) {
        DebugAllocator dbg = DebugAllocatorInitWith(LEAK_CFG);
        Float          fv  = FloatInit(ALLOCATOR_OF(&dbg));
        Zstr           p   = "1e99999999999999999999999999999999999999999999999999";
        WriteFmt("Testing print_help frees per-spec left-column Strs (414:9)\n");
    
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    // Lean leak-checking DebugAllocator config (no traces / overflow / history).
    static DebugAllocator leak_alloc(void) {
        DebugAllocatorConfig cfg = DEBUG_ALLOCATOR_DEFAULTS;
        cfg.capture_traces       = false;
    //         CU drives the build to failure; the dropped teardown leaks.
    bool test_dwm_build_failure_frees_lines(void) {
        DebugAllocator dbg  = leak_alloc();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    //          the CuStrings vectors leak.
    bool test_dwm_collect_failure_frees_cu_strings(void) {
        DebugAllocator dbg  = leak_alloc();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // buffer has been taken/allocated.
    bool test_mh2_fail_path_frees_buffer(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_dw4_build_frees_cu_strings(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // ---------------------------------------------------------------------------
    bool test_dw4_deinit_releases_string_pool(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *base = ALLOCATOR_OF(&dbg);
    // Lean DebugAllocator config: no trace capture / overflow guards / freed
    // history. We only need the live-allocation round-trip count.
    static DebugAllocator kv_lean_debug_allocator(void) {
        DebugAllocatorConfig cfg = {.capture_traces = false, .detect_overflow = false, .track_freed_history = false};
        return DebugAllocatorInitWith(cfg);
    // it, leaving DebugAllocatorLiveCount > 0.
    static bool kv_parse_is_leak_free(Zstr src) {
        DebugAllocator dbg  = kv_lean_debug_allocator();
        Allocator     *base = ALLOCATOR_OF(&dbg);
        bool           ok   = true;
    
    bool test_kv_leak_value_strip_frees_old_buffer(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_kv_leak_parse_frees_local_key(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_kv_leak_parse_frees_local_value(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
    
    bool test_kv_leak_get_ptr_zstr_frees_lookup(void) {
        DebugAllocator dbg  = DebugAllocatorInit();
        Allocator     *adbg = ALLOCATOR_OF(&dbg);
Last updated on