fix(cua-driver): drain daemon state on shutdown - #3348
Conversation
|
Final CI verification: strict server E2E Memcheck is green with 0 definite bytes, 0 possible bytes, and 0 error contexts. All PR checks are terminal (24 passed, 1 intentional skip, 0 failed/cancelled/pending) on |
injaneity
left a comment
There was a problem hiding this comment.
shutdown ordering looks correct to me. connection tasks stop before sdk teardown, the tokio runtime is shut down, and process-global state is released afterward
3b9d23f to
ec3c4e9
Compare
c02ad42 to
0804c1d
Compare
ec3c4e9 to
aae2fcd
Compare
0804c1d to
81706c9
Compare
3f93008 to
1203e26
Compare
|
@copilot fix merge conflicts |
Resolved by merging |
1203e26 to
cd5042b
Compare
|
@copilot fix merge conflicts |
Fixed by merging |
aa84401 to
cdb6e44
Compare
842ce8f to
1118cca
Compare
(cherry picked from commit d20f57c)
(cherry picked from commit 81706c9)
The base branch replaced run-valgrind-e2e.sh with run-valgrind-e2e.py, so carry the harness changes from the shutdown-leak fixes over to the Python runner: - disable glibc's joined-thread stack cache via GLIBC_TUNABLES so retained stacks do not obscure ownership at exit - drop --gen-suppressions=all and --num-callers=40 from the Memcheck command; the gate stays strict with no suppressions - probe readiness through `sessions list --json` and require the empty-session contract from a fresh daemon - exercise `list_apps` instead of `check_permissions` for the smoke call - cover the command builders and environment setup in the unit tests Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CwPYqr5ukyx6JQGRLiATWq
The base branch was changed.
1118cca to
a2a4a71
Compare
Stacking
Originally stacked on the Memcheck harness PR #3346, which merged to
mainas 692a63c. This branch is now rebased onto that merge and targetsmaindirectly; the six product commits plus the harness port are unchanged apart from the rebase.Rebase onto current base (2026-09-04)
ci/cua-driver-valgrindtip, which pins the toolchain and runner, tracksstop_attempted, and validates throughexpect()instead of bareassert; the six product commits are cherry-picked unchanged and the Rust diff is byte-identical to the previous head apart from hunk offsetsrun-valgrind-e2e.shwithrun-valgrind-e2e.py, so the harness changes from this stack (glibc stack-cache tunable, focused Memcheck flags,sessions listreadiness,list_appssmoke call,NO_AT_BRIDGE=1) are ported to the Python runner in a dedicated commit with unit coverageBase findings
Base run https://github.com/trycua/cua/actions/runs/32673259741 exercised the real daemon and reported 29 possible-leak contexts / 16,184 bytes under strict Memcheck:
Root-cause fixes
JoinSet, abort and join them before SDK teardownNO_AT_BRIDGE=1before constructing the persistent AT-SPI listenerArcstate and clear it after daemon runtime shutdown--leak-check=full --show-leak-kinds=definite,possible --errors-for-leak-kinds=definite,possible --error-exitcode=99with no suppressionsRegression coverage
Validation and iterations
bash -n scripts/ci/linux/run-valgrind-e2e.shdbus-run-session -- xvfb-run -a scripts/ci/linux/run-valgrind-e2e.sh libs/cua-driver/rust/target/debug/cua-driverdefinitely lost: 0 bytes in 0 blocks,possibly lost: 0 bytes in 0 blocks, andERROR SUMMARY: 0 errors from 0 contextsFinal three-context diagnosis
The 804-byte state came from three exact lifecycle owners rather than user-request allocations:
SessionModeCeiling::processpermission-mode set retained by the process-global authorization registryDirect owned-runtime shutdown removed the 148/608-byte executor contexts. Releasing the configured authorization registry after daemon shutdown removed the final 48-byte context.
Current status
Strict end-to-end Memcheck and all relevant Linux, Windows, macOS, Nix, contract, formatting, docs, and metadata checks passed on the pre-rebase head
c02ad4209a81578e1b1256e8f86409141f80e639. The rebased head re-runs the same checks; #3346 has landed and this PR is rebased onto it; the only other change onmainsince the tested head is an unrelated fleet billing commit.