akgl_character_sprite_add leaks a reference when the same sprite is re-added #42

Open
opened 2026-08-02 18:33:26 -04:00 by tachikoma · 0 comments
Collaborator

Source: TODO.md, "Found while writing the manual" -> "Defects with no prior entry", item 7 (at bbb7b8f)

ref->refcount += 1;                                  /* unconditional */
...
if ( (displaced != NULL) && (displaced != ref) ) {   /* guarded */
    PASS(errctx, akgl_heap_release_sprite(displaced));
}

The reference is taken unconditionally but the matching release is guarded by
displaced != ref, so re-adding a sprite to a state it already occupies leaks a
pool slot per call.

That guard is deliberate for the case it was written for -- rebinding a state to
the sprite already there should not be treated as a displacement -- so the fix is
to not take the reference in that case either, rather than to release
unconditionally.

The displacement path itself is correct and tested (tests/character.c runs 200
alternating rebinds). This is the same-sprite path, which nothing covers.

Files: src/character.c:60-79


Filed by Tachikoma (Claude Code, Opus 5, 1M context)

**Source:** TODO.md, "Found while writing the manual" -> "Defects with no prior entry", item 7 (at bbb7b8f) ```c ref->refcount += 1; /* unconditional */ ... if ( (displaced != NULL) && (displaced != ref) ) { /* guarded */ PASS(errctx, akgl_heap_release_sprite(displaced)); } ``` The reference is taken unconditionally but the matching release is guarded by `displaced != ref`, so **re-adding a sprite to a state it already occupies leaks a pool slot per call.** That guard is deliberate for the case it was written for -- rebinding a state to the sprite already there should not be treated as a displacement -- so the fix is to not take the reference in that case either, rather than to release unconditionally. The displacement path itself is correct and tested (`tests/character.c` runs 200 alternating rebinds). This is the same-sprite path, which nothing covers. **Files:** `src/character.c:60-79` --- Filed by Tachikoma (Claude Code, Opus 5, 1M context)
tachikoma added this to the 0.9.x milestone 2026-08-02 18:33:26 -04:00
tachikoma added the defectblast-radius:medium labels 2026-08-02 18:33:26 -04:00
tachikoma added the status::grooming label 2026-08-02 18:49:20 -04:00
Sign in to join this conversation.