mirror of
https://github.com/stablyai/orca.git
synced 2026-10-25 16:03:53 +00:00
* fix(crash-reporting): correlate concurrent process deaths on a renderer report
Two 1.4.184 reports (a326935a, 1862f316) are renderer "crashed"/-1 crash reports
whose renderer only died alongside a sibling Chromium child that died at the same
instant:
F0BQMB30GJX network.mojom.NetworkService crashed/-1 -21ms -> renderer crashed/-1
F0BRPP8TC0Y audio.mojom.AudioService crashed/-1 -2ms -> renderer crashed/-1
GPU crashed/-1 +180ms
process-gone-classification.ts classifies each event in isolation:
isRecoverableChromiumChildProcess discards the utility/GPU halves as recoverable
churn, and `if (reason !== 'killed') return true` then reports the renderer half as
a genuine renderer crash before any cross-source signal exists. Triage reads
"renderer crashed" for what died with three other processes.
process-gone-sibling-correlation keeps a bounded ring of child deaths, populated
before the suppression early-return so churn-suppressed siblings stay visible, and
matches a renderer death against child deaths sharing its failure signature.
What the timing can and cannot support:
- The window is asymmetric. 1s of lookback (a child that died first can plausibly
have taken the renderer with it), but only 250ms of lookahead: a child dying well
after the renderer is at least as likely to be an effect of it — Chromium tearing
down the dead renderer's channels, or renderer_recovery_reload at +264ms — and a
symmetric window would retro-label a genuine lone crash as collateral.
- crashAttribution is 'concurrent-process-deaths', not a causal claim. The largest
1.4.184 cluster is an external taskkill /T where renderer and children are
co-victims; no sibling caused anything there.
- The verdict is not derived from timing alone. A host with a child looping at the
observed 1459/min drops a death into every window, so crashAttribution is set only
when the nearest sibling is within 250ms and no identity repeats. Looser or
repeating deaths still ship as evidence (siblingProcessDeathCount, signed offsets,
siblingProcessDeathRepeats) with no attribution.
- The signature match buckets `crashed` with `abnormal-exit` and gates on the exit
code only on win32. Both fixtures are win32, where every process in a collateral
pair reports crashed/-1; POSIX surfaces a per-process wait status, so an equality
gate would mean this never fires on macOS or Linux.
The report stays reportable and gains evidence rather than being suppressed
(#14667). Both arrival orders are covered without delaying persistence: a sibling
that dies first is folded into the initial record, a sibling that dies after amends
the record already on disk through attachDetails, the same way the minidump
signature does. Late amends are capped at two per report and skipped when the
rendered evidence is unchanged, so a crash-looping child cannot rewrite the store
during renderer recovery, and a failed amend now leaves a
sibling_attribution_attach_failed breadcrumb instead of vanishing.
Relationship to #12484: it is still OPEN and adds process-tree-kill-window.ts, the
same ring/lookback bookkeeping with a 250ms settle, patching the same recorder
hunks with the opposite policy (suppress the killed/1 renderer report instead of
keeping it). #14667 is test-only — it pinned the keep-the-report policy in tests, it
did not remove a shipped implementation. #12484 has to be closed or rebased out
before this lands.
* chore: remove merge hook formatting drift