`cmake --build build --target memcheck` runs every registered CTest suite under valgrind. There are no new test programs, and there should not be any: tests/benchutil.h notices valgrind in LD_PRELOAD and drops the benchmark scale to 0.0005, which turns the perf suites into the broadest path coverage in the tree at a cost valgrind can survive. A benchmark walks one path a hundred thousand times; a leak check wants every path walked once. Same binaries, one flag apart, and the whole run is about thirty seconds. scripts/memcheck.sh wraps `ctest -T memcheck` because that command records defects and still exits 0, which cannot gate anything. It also forces the headless drivers, so the vendor GPU stack is never loaded -- that removes thousands of unfixable findings inside amdgpu_dri.so without suppressing anything, and it is what the suites are written for anyway. Only definite losses, invalid accesses and uninitialised reads count; "still reachable" is what SDL and FreeType keep for the process lifetime and says nothing about this library. The three suppressions in scripts/valgrind.supp are each a decision that a finding belongs to somebody else. Six defects, all filed in TODO.md under "Memory checking", the first of which is the one that matters: not one of the four json_load_file calls in src/ is ever matched by a json_decref, so every asset load abandons its parsed document -- 1.5 KB per sprite, 2.1 KB per character, 9 KB per load of the 2x2 fixture map, and on the order of a megabyte for a real one. A game that reloads a level on death leaks a level's worth of JSON every time. akgl_get_property also reads up to 4 KiB past the end of every property value it copies, and the savegame name tables read past the end of every registry key and write what they find into the file. tests/util.c zeroes three fixtures it used to leave as stack garbage. The library was never at fault there -- the tests handed it uninitialised floats and then made one real call with them -- but sixteen findings of noise in a new gate is how a gate gets ignored. The unit suites' TIMEOUT goes from 30 to 300 because CTest applies the same property to the checked run, where everything is twenty times slower. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
57 lines
2.3 KiB
Plaintext
57 lines
2.3 KiB
Plaintext
# Valgrind suppressions for the libakgl memory-check run.
|
|
#
|
|
# Used by `cmake --build build --target memcheck` and by any hand-run
|
|
# `ctest -T memcheck`; see AGENTS.md -> "Memory checking".
|
|
#
|
|
# Every entry here is a deliberate decision that a finding belongs to somebody
|
|
# else's code and cannot be fixed from this repository. Nothing that libakgl
|
|
# allocates is suppressed, and nothing is suppressed merely because it is noisy.
|
|
# If a suppression starts hiding a real finding, delete it -- a false negative in
|
|
# a leak check is worth more than a quiet log.
|
|
#
|
|
# The memcheck target runs the suite headless (SDL_VIDEO_DRIVER=dummy,
|
|
# SDL_RENDER_DRIVER=software, SDL_AUDIO_DRIVER=dummy) precisely so that the GPU
|
|
# stack is never loaded. That removes thousands of unfixable findings inside
|
|
# amdgpu_dri.so / Mesa / libGLX without suppressing anything, which is why there
|
|
# are no driver entries below. Run the suite against a real driver and you will
|
|
# need them; do not add them here on that account.
|
|
|
|
# SDL allocates its global state -- the hint table, the property registry, the
|
|
# log category array, the clipboard -- on first use and reclaims it in SDL_Quit.
|
|
# A test that fails before SDL_Quit, and every test that deliberately leaves SDL
|
|
# up so a later assertion can look at it, leaves those blocks behind. They are
|
|
# one-per-process, not per-call, so they cannot accumulate into a leak.
|
|
{
|
|
sdl3-global-state-still-reachable
|
|
Memcheck:Leak
|
|
match-leak-kinds: reachable
|
|
...
|
|
fun:SDL_InitSubSystem_REAL
|
|
}
|
|
|
|
# dlopen keeps the link map and the loaded objects' TLS blocks for the process
|
|
# lifetime; a dlclose does not return them. SDL loads its video, audio, and
|
|
# render backends this way, and SDL_image and SDL_mixer load their codecs the
|
|
# same way.
|
|
{
|
|
dl-open-keeps-its-link-map
|
|
Memcheck:Leak
|
|
match-leak-kinds: reachable,possible
|
|
...
|
|
fun:_dl_open
|
|
}
|
|
|
|
# FreeType, reached through SDL_ttf, caches per-face and per-size structures
|
|
# inside the library instance and frees them in FT_Done_FreeType, which SDL_ttf
|
|
# calls from TTF_Quit. A suite that opens a font and exits without TTF_Quit
|
|
# reports them; a font libakgl itself failed to close is a different finding and
|
|
# is NOT covered here -- it appears under akgl_text_loadfont, not under
|
|
# FT_Init_FreeType.
|
|
{
|
|
freetype-library-instance
|
|
Memcheck:Leak
|
|
match-leak-kinds: reachable
|
|
...
|
|
fun:FT_Init_FreeType
|
|
}
|