ckerr

#54861: test: use precise GC for utility process observer regression

Merged
Created: Oct 12, 2026, 3:00:04 PM
Merged: Oct 12, 2026, 8:31:35 PM
5 comments
Target: main

Description of Change

Make the utility-process stale-observer regression's collection check deterministic with respect to native stack scanning, while retaining the assertions that the first crashed process is collected and a subsequent crash is reported.

  • Await the existing precise asynchronous GC helper instead of synchronous GC, which conservatively scans the native stack and can retain an otherwise unreachable wrapper through stale pointers.
  • Retain only a WeakRef to the first child and keep the event-loop boundary before each collection attempt.
  • Use a unique service name per test attempt so unrelated processes and late notifications from prior attempts cannot satisfy its crash waits.
  • Defer removal of crash listeners so a failed or timed-out attempt does not leave them behind.
  • Keep the existing timeout and collection-attempt bound, and give collection failures an explicit assertion message.

Only spec/api-utility-process.spec.ts changes; there are no production-code or API changes.

Affected release branches: current upstream 45-x-y, 44-x-y, 43-x-y, and 42-x-y all contain the same synchronous collection loop, shared default service name, and crash-wait helper without teardown cleanup. All four already provide the precise asynchronous GC helper and its TypeScript overload. Backports to 42-x-y and 43-x-y must preserve their existing Windows 32-bit test skip. This assessment is based on source inspection, not release-branch execution.

42-x-y near-EOL scope: This target is retained only for a nearly-zero release/runtime-risk, test-only backport. The regression body and crash-wait helper match pre-fix main, and the precise GC helper, types, and deferred cleanup already exist on 42-x-y. Preserve its Windows 32-bit skip; do not add production changes, new helpers, or broader test cleanup to make this backport work. If those become necessary, drop the 42-x-y target. Release-branch CI is still required before merging a backport.

Validation (Linux, existing local Testing build):

  • Unchanged baseline: 11/11 isolated executions passed; the original Windows failure was not reproduced locally.
  • Updated exact regression: 100/100 independent executions passed through the normal Vitest/Electron runner, with retries disabled and exactly one passing test verified per repetition.
  • Combined neighboring utility-process lifecycle, app crash-notification, and native-heap tests: 31 passed across two spec files.
  • Targeted JavaScript lint, formatting, spec TypeScript check, and git diff --check passed. Commit hooks also passed.

Exact regression command, repeated 100 times from the repository root:

env -u CI ELECTRON_OUT_DIR=Testing node script/spec-runner.js \
  --skipYarnInstall --files spec/api-utility-process.spec.ts \
  -g 'does not keep stale observers for crashed processes without JS references'

Neighboring coverage:

env -u CI ELECTRON_OUT_DIR=Testing node script/spec-runner.js \
  --skipYarnInstall --files spec/api-utility-process.spec.ts spec/cpp-heap.spec.ts \
  -g 'utilityProcess module.*(lifecycle events|child-process-gone|should)'

Windows x64/ARM64 validation is still required; Linux success does not establish that the Windows timeout signature is resolved. Native-addon tests gated by --skipYarnInstall were not part of this validation. The full test suite was not run.

Checklist

Release Notes

Notes: none

Backports

42-x-y
Pending
Waiting for a manual backport
43-x-y
Pending
Waiting for a manual backport
44-x-y
Merged
PR Number
#54866
Merged At
Oct 12, 2026, 9:26:44 PM
Released In
Not yet
Release Date
Not yet
45-x-y
Merged
PR Number
#54867
Merged At
Oct 12, 2026, 9:29:11 PM
Released In
Not yet
Release Date
Not yet

Semver Impact

Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.

Semantic Versioning helps users understand the impact of updates:

  • Major (X.y.z): Breaking changes that may require code modifications
  • Minor (x.Y.z): New features that maintain backward compatibility
  • Patch (x.y.Z): Bug fixes that don't change the API
  • None: Changes that don't affect using facing parts of Electron