diff --git a/docs/reference/linux-memory-kill-attribution.md b/docs/reference/linux-memory-kill-attribution.md index e389b4dc4bd..420ff2e9603 100644 --- a/docs/reference/linux-memory-kill-attribution.md +++ b/docs/reference/linux-memory-kill-attribution.md @@ -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 diff --git a/src/main/crash-reporting/linux-cgroup-memory-limit.test.ts b/src/main/crash-reporting/linux-cgroup-memory-limit.test.ts index 6b48375fe0a..0bd7cbce417 100644 --- a/src/main/crash-reporting/linux-cgroup-memory-limit.test.ts +++ b/src/main/crash-reporting/linux-cgroup-memory-limit.test.ts @@ -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,