mem-check: best of 3 on a baseline overrun; baseline 176 MB (#96) #111
No reviewers
Labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
schaefera/utStudyBIble!111
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/mem-check-noise"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #96.
What
tools/mem-check/run.shno longer fails on one noisy sample. An attempt over a baseline (PSS or start-up) is measured again in a fresh app and sandbox, up toATTEMPTS(3) times, and the profile passes if any attempt is within both baselines. A real regression still fails all three. Other failures (the app exited, too few chapters, SKIP) aren't retried. The PSS baseline moves from 165000 to 176000 kB, 10% over CI's median since #82. CI's growth is real feature cost (#71 +~10 MB, #82 +~5 MB), not drift.Blast radius
Tier: trunk
Trunk paths touched:
tools/mem-check/(run.sh, budget-kb)Testing tier: maximum (CI gate tooling) (also: ship on sight, docs/01 and docs/09)
Gate / rollback:
ATTEMPTS=1gives the old single sample, andBUDGET_KB=165000the old baseline, with no code change. Full undo: revert this merge.Proof
ut-app-ci:24.04-2.x-1throughout). Normal peak was 136–145 MB up to #37. It was 147–157 MB from #71's first CI (run 112,dff31c6) on, and 155–166 MB since #82 (run 150). Since #82: normal median 160 MB (n=20, 154.6–166.4), slow median 163 MB (n=17, 156.3–164.7).ut-app-ci, interleaved, 5 runs each, normal profile). WithInstaller.start(): median 168.7 MB, range 168.4–173.3. Without it: median 169.2 MB, range 166.5–172.2. No difference beyond noise, so there's no cheap start-up saving to take instead of raising the baseline.fix/mem-check-noise@b1ae64d, from the journal's build line). Start-up PSS is 60,153 kB (54–55 MB on 10-20, so +~6 MB, consistent with the desktop's +15 MB at ~2.5×). Peak over 40 flings Matt 4→14 is 60,889 kB, against the 80 MB device budget. The app is unchanged by this PR; it's left installed.cargo make app-dockeronb1ae64d, local). The normal profile passed attempt 1 at 163,909 kB. The slow profile ran 177,041, then 167,264, then 173,308 kB, each over the then-165000 baseline, and printedmem-check: FAIL: over a baseline in all 3 attempts(exit 1). A desktop under load runs higher than CI, as #96 says, so this shows the mechanics, not the CI numbers.appon single samples 92–1436 kB over 165000, on trees that passed elsewhere (#96 comments). With this change each of those would have been measured again.df978f0, local):ATTEMPTS=abcandATTEMPTS=0give rc 2 with a message. A child failing early (missing paths) gives rc 1 after one attempt, with no retry.df978f0(run 195): changes, rust, audit, app, e2e and click all passed. Theappjob (1907) passed on attempt 1 in both profiles: normal 158,671 kB, slow 164,577 kB, against 176000.Review
Reviewer: fresh-context
code-reviewat high (review 302 onb1ae64d): 5 findings, all low; 4 fixed indf978f0, 1 declined (no parent TERM trap: CI cancels by container teardown, and a group kill reaches the child; comment 2283). No re-review (lows only).Review-Confidence: 85/100. The review was sound and no defect was missed. −15 because df978f0's fixes to low findings were never re-reviewed.
Confidence by part
🤖 Generated with Claude Code
Level: high (trunk: tools/mem-check/). Commit
b1ae64d8a9. Range: origin/main...HEAD.Files reviewed: tools/mem-check/run.sh, tools/mem-check/budget-kb, docs/09-quality-gates.md; read for context: tools/e2e/lib.sh (e2e_setup, e2e_cleanup, e2e_fail, exit 77 SKIP path), tools/ci/app.sh, Makefile.toml.
No high or medium findings. The retry loop is sound: exit 77 and 1 pass through, only 3 is retried, each attempt gets a fresh mktemp sandbox and EXIT-trap cleanup, and ATTEMPTS=1 keeps the old single-sample behaviour.
Low, outside the diff lines:
Inline comments cover the other low items.
@ -34,0 +43,4 @@n=1while :; dorc=0MEM_CHECK_ATTEMPT=$n sh "$0" "$@" || rc=$?low: the parent shell has no TERM/INT trap, whereas the child (lib.sh) has
trap 'exit 143' TERM INT. If CI cancels by signalling only the parent sh, the child keeps running (Xvfb, app, busy-loop) until it finishes, and nothing waits for it. Process-group kills are fine; a lone kill ofleaks. Addtrap 'kill $child' TERM INTwith the child run in the background and waited on, or document.@ -34,0 +45,4 @@rc=0MEM_CHECK_ATTEMPT=$n sh "$0" "$@" || rc=$?[ "$rc" = 0 ] && exit 0if [ "$rc" != 3 ]; then exit "$rc"; filow: exit 3 is the in-band 'retry' signal, but the child runs under
set -eand sources lib.sh, so any helper or tool that happens to exit with status 3 (xdotool, timeout wrapper, taskset, a failing command in e2e_*) is read as 'over a baseline' and retried instead of failing at once. Unlikely today, but a distinct marker (a file in a dir the parent owns, or a rarely used code like 79) would be safer.@ -34,0 +46,4 @@MEM_CHECK_ATTEMPT=$n sh "$0" "$@" || rc=$?[ "$rc" = 0 ] && exit 0if [ "$rc" != 3 ]; then exit "$rc"; fiif [ "$n" -ge "$attempts" ]; thenlow: ATTEMPTS=abc (or empty-but-set to a non-number) makes
[ "$n" -ge "$attempts" ]return 2 insideif, which is false, so a persistently over-baseline attempt (rc 3) loops forever instead of failing. Validate ATTEMPTS as a positive integer, or test with[ "$n" -lt "$attempts" ] || fail-style logic that errors out.@ -34,0 +47,4 @@[ "$rc" = 0 ] && exit 0if [ "$rc" != 3 ]; then exit "$rc"; fiif [ "$n" -ge "$attempts" ]; thenecho "mem-check: FAIL: over a baseline in all $attempts attempts" >&2low: the final FAIL line no longer says which baseline (PSS or start-up) or the numbers; they are only in the earlier per-attempt stderr lines, which are not prefixed FAIL and are not repeated, so a log tail or grep for FAIL shows no cause. Consider remembering the last attempt's reasons and repeating them here.
Answers to review 302 (all low), fixed in
df978f0unless noted:ATTEMPTS=abcandATTEMPTS=0→ rc 2).EX_TEMPFAIL, "try again"), which no tool in the path returns.exit 143trap and cleans up). Only a signal sent to the parent's pid alone would leave the child running, and nothing does that.No re-review: only low findings (owner rule, features-via-workflow).
WIP: mem-check: best of 3 on a baseline overrun; baseline 176 MB (#96)to mem-check: best of 3 on a baseline overrun; baseline 176 MB (#96)Gate approval at
df978f0(medium).df978f0(the only commit afterb1ae64d) reads clean: ATTEMPTS validated (rc 2), retry on exit 75 only, e2e_fail still exits 1 so real failures are not retried, 75 is used nowhere else in tools/mem-check or tools/e2e/lib.sh, docs note matches the 176 MB baseline.Owner's call on the open question (2026-10-29): keep the baseline at 176000 under best-of-3; no change to 170000.