fix(crash-reporting): pin the empty-ceiling-file term and correct the uptime claim

An empty memory.max reads as Number('') = 0 without the empty-string term, so a
sandbox that stubs /sys/fs/cgroup with zero-length files would ship a 0 MB
ceiling and a false mem-available-cgroup-capped label. No test held that term.

The doc said the main process started 'hours earlier' in all three reports;
2ea53f9c is 42 m 55 s. Replaced with the measured per-report uptimes.
This commit is contained in:
Claude
2026-09-21 16:10:23 -07:00
committed by m4air
parent fc1e8a2beb
commit 3facce3b2e
2 changed files with 34 additions and 3 deletions
@@ -18,9 +18,10 @@ The kernel OOM killer does not fire with that much headroom. `181e8e36` is two
single-process kills, not one whole-cgroup kill: the `process_gone_suppressed`
GPU crumb is at `22:29:32.397Z` and the renderer report at `22:38:37.276Z`, so
they are not co-timed and nothing links them beyond the host. And in all three
Orca's **main** process survived and stayed the reporter — `mainProcessStartedAt`
hours earlier, `processMetricsBrowserCount: 1` in the post-death sample — which
is not what a whole-cgroup kill leaves behind.
Orca's **main** process survived and stayed the reporter — already up 43 m
(`2ea53f9c`), 11 h (`ad185d76`) and 3 h 11 m (`181e8e36`) by
`mainProcessStartedAt`, and `processMetricsBrowserCount: 1` in the post-death
sample — which is not what a whole-cgroup kill leaves behind.
That last point is why `systemd-oomd` is a candidate here and not a conclusion:
it kills the whole cgroup, and the surviving main process argues against it for
@@ -106,6 +106,36 @@ describe('cgroup v2 memory directory resolution', () => {
})
})
it('does not turn a zero-length ceiling file into a 0 MB cap', () => {
// A sandbox that stubs /sys/fs/cgroup with empty files: `Number('')` is 0, so
// dropping the empty-string term ships a 0 MB ceiling and labels the report
// cgroup-capped — a killer named off a file that measured nothing.
setSystemMemoryInfoReaderForTest(() => NO_HOST_PRESSURE)
setLinuxMemoryPressureStallReaderForTest(() => undefined)
fakeLinuxPseudoFiles({
'/proc/self/cgroup': SANDBOX_CGROUP_PATH,
'/sys/fs/cgroup/user.slice/user-1000.slice/app.slice/orca.scope/memory.current': '4200000000',
'/sys/fs/cgroup/user.slice/user-1000.slice/app.slice/orca.scope/memory.max': '',
'/sys/fs/cgroup/user.slice/user-1000.slice/app.slice/orca.scope/memory.high': ''
})
expect(readLinuxCgroupMemoryLimit('linux')).toEqual({
maxBytes: undefined,
highBytes: undefined,
currentBytes: 4_200_000_000,
oomKillCount: undefined,
maxEventCount: undefined,
highEventCount: undefined
})
const details = getSystemMemoryDetails('linux')
expect(details.systemMemoryCgroupMaxMB).toBeUndefined()
expect(details.systemMemoryCgroupHighMB).toBeUndefined()
expect(details.systemMemoryCgroupCurrentMB).toBe(4_005)
expect(details.systemMemoryPressureSignal).toBe('mem-available')
})
it('says nothing rather than a row of undefineds when the files are garbage', () => {
fakeLinuxPseudoFiles({
'/proc/self/cgroup': SANDBOX_CGROUP_PATH,