Skip to content

ci: run teardown probe under valgrind - #73

Merged
nitsuga merged 3 commits into
mainfrom
ci/valgrind-71
Aug 30, 2026
Merged

ci: run teardown probe under valgrind#73
nitsuga merged 3 commits into
mainfrom
ci/valgrind-71

Conversation

@nitsuga

@nitsuga nitsuga commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • add Valgrind to the shared CI image
  • pin standard jobs to the published immutable image tag
  • fail configuration if CTest does not register the teardown probe through Valgrind with error exit code 97

Validation

Closes #71

Author: Codex (model: openai/gpt-5.6-sol)

@nitsuga

nitsuga commented Aug 30, 2026

Copy link
Copy Markdown
Owner Author

Review: approve

No blocking findings. This is a well-scoped change: 14 additions, zero CMake changes because CMakeLists.txt:235-242 already had the machinery, and it adds a guard against exactly the silent-degradation failure mode that made #71 necessary.

Verified, not just read

I reproduced the mechanism locally rather than trusting the CI logs — this host has Valgrind 3.22.0, the same version as the image.

The guard works in all three states. This was my main concern, since the verify step runs before Build:

State ctest -N -V | grep -F 'valgrind "--error-exitcode=97"'
Valgrind present, post-build exit 0 (passes)
Valgrind present, pre-build, no executable exit 0 (passes)
Valgrind absent (-DVALGRIND_EXECUTABLE=NOTFOUND) exit 1 (correctly fails)

The pre-build case works for a non-obvious reason worth recording: CTest resolves the first command word, and here that is /usr/bin/valgrind, which exists. Tests whose program is the not-yet-built binary print an empty Test command: at that stage. So the guard is robust pre-build precisely because Valgrind wraps it — incidental rather than designed, but it holds.

Runtime — my earlier concern is retired. I had flagged that teardown_probe_uaf took 21.08s and might exceed the 600s timeout under Valgrind. Wrong premise: Valgrind is installed on this host, so that 21.08s measurement was already Valgrind-wrapped, inflated by parallel suite load. Run in isolation locally it is 8.99s; CI reports 12.18 sec, total suite 55.09s, against --timeout 600 and a 20-minute job cap. No iteration reduction needed.

The image is real. Tag bc5b33d81da… exists, the package is public, it pulls anonymously, and docker run … valgrind --version returns valgrind-3.22.0 — the PR's claim confirmed by execution, not only by the build log.

Sequencing resolved cleanly. ci-image.yml never runs on pull_request, so the image could not be published from the PR branch by push. It was published via workflow_dispatch on the branch, a permitted trigger under that file's own documented policy ("Publishing is a trusted-push (or manual) operation only"). The pin points at bc5b33d, the exact commit that defines the Dockerfile, which is good provenance.

No C/C++ or CMake files change, so the 28/28 release and 17/17 sanitize results verified on #72 still stand.

Findings (all minor)

1. context/log.md:7 names a job that does not exist. It reads "The release job verifies that CTest registered…", but ci.yml defines build-test, sanitizers, and generated-drift. "Release" is a CMake preset, not a job. The same slip is in the PR body, where "release, sanitizer, generated-drift, install, and consumer checks pass" mixes two jobs with three steps of build-test. The PR body is ephemeral; log.md is the durable record, so that one is worth correcting to build-test.

2. The grep is not anchored to the test. grep -F 'valgrind "--error-exitcode=97"' matches any test registered with those flags. Today only teardown_probe_uaf is, so it works — but the check would survive that test being deleted and a different one acquiring the flags. Adding teardown_probe_uaf to the pattern costs nothing.

3. (trivial) It is the only step in build-test that bypasses ci/with-capacity.sh. Defensible — ctest -N is a metadata read that does no compute and should not hold a slot — but it is a deliberate exception to the job's convention and is not commented as one.

One criterion taken partly on trust: acceptance says "A reported invalid access fails the test/job." This PR verifies the registration and flags, not an injected fault. --error-exitcode=97 is documented Valgrind behavior, so I would accept that rather than ask for fault injection — but it is the gap between what is checked and what is claimed.

Worth noting for after merge: ci/Dockerfile changing on main will fire ci-image.yml and publish a second tag (the merge SHA) that nothing references. Harmless, since the pin stays immutable and correct.


Author: Claude Code (model: claude/opus-5)

@nitsuga
nitsuga merged commit a0b9964 into main Aug 30, 2026
8 checks passed
@nitsuga
nitsuga deleted the ci/valgrind-71 branch August 30, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: run GStreamer teardown coverage under a memory checker

1 participant