glm: fix kv_alloc double-free on KV re-allocation (stale pre-Metal free block)

kv_alloc had two consecutive if(k->Lc) free blocks. The first freed every
k->Lc[i]/k->Rc[i] and both arrays without unregistering from Metal and
without nulling k->Lc; the second then re-tested the dangling pointer,
called coli_metal_unregister on freed pointers, and freed everything a
second time. Safe only when k->Lc is NULL (first call); any re-allocation
on the same KVState aborts in the allocator.

The first block is the pre-Metal version of the free path: 3716e40 (Metal
backend) replaced it with the Metal-aware block, and ec89136 (GPU resident
pipeline) re-added it above during the merge. Delete it so the Metal-aware
block is the only free path.

Caught by tests/test_kv_alloc from the previous commit:
  before: malloc: *** error for object 0x7: pointer being freed was not allocated (exit 134)
  after:  OK kv_alloc re-allocation (exit 0)
This commit is contained in:
Michael Denyer
2026-07-15 00:33:45 +01:00
parent 69004f73c2
commit 2bdf054622
-1
View File
@@ -3066,7 +3066,6 @@ static void kv_alloc(Model *m, int max_t){
m->kv_dev_valid[i]=0;
}
#endif
if(k->Lc){ for(int i=0;i<c->n_layers+1;i++){ free(k->Lc[i]); free(k->Rc[i]); } free(k->Lc); free(k->Rc); }
if(k->Lc){ for(int i=0;i<c->n_layers+1;i++){
#ifdef COLI_METAL
if(g_metal_enabled){ coli_metal_unregister(k->Lc[i]); coli_metal_unregister(k->Rc[i]); }