Treat a process that exits during Identify as gone, not unreadable - #2061
Merged
Merged
Conversation
Identify reads /proc/<pid>/stat and then asks the runtime for the
process. A process that exits between the two is refused by the runtime
rather than the kernel: Process.GetProcessById throws ArgumentException
("not running") and Process.StartTime throws Win32Exception ("may have
exited or may be privileged"). The previous change mapped the
IOException from the stat read to the "Cannot identify a terminated
native process." refusal but left these two to escape as raw
exceptions, so a plainly gone process still read as one that could not
be identified. A Linux harness calling Identify from 4-16 threads
against a process exiting underneath them saw 649-1258 of them per run.
TreatsAsGone now accepts both alongside IOException, on the same
evidence: kill(pid, 0) answering ESRCH. The Win32Exception message names
the ambiguity itself (privileged), so the same exception about a pid
that still exists keeps propagating; unknowable stays unknowable.
Identify wraps the GetProcessById/StartTime pair in that decision and
throws the refusal the Z/X state, the stat read and the macOS branch
already give.
IsRunning, IsAlive and KillSession are unchanged: they reach
TreatsAsGone only from catch (IOException) clauses, which never hand it
the two new types, and each already swallows ArgumentException and
guards Win32Exception with its own absence probe.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
NativeProcess.Identifystill escaped raw exceptions for a process that exits after its/proc/<pid>/statread:Process.GetProcessByIdthrowsArgumentException("not running") andProcess.StartTimethrowsWin32Exception("may have exited or may be privileged"). Treat a process that vanishes mid-read as gone, not unreadable #2053 mapped theIOExceptionfrom the stat read only. Whenkill(pid, 0)answers ESRCH, both now become the sameIOException("Cannot identify a terminated native process.", inner)the stat read, theZ/Xstates and the macOS branch already give; otherwise they propagate, so unknowable stays unknowable.TreatsAsGone(internal) acceptsArgumentExceptionandWin32ExceptionalongsideIOException, on the same evidence and never the exception's type or message.IsRunning,IsAliveandKillSessionreachTreatsAsGoneonly fromcatch (IOException)clauses, so the filter is never handed the two new types there; each already swallowsArgumentExceptionunconditionally and guardsWin32Exceptionwith its ownIsAbsentprobe. Only the newcatch (Exception)inIdentifysees them.Test plan
NativeProcessGoneTests10 -> 17 tests, all green (macOS). New:ArgumentExceptionandWin32Exceptionwith an absent pid read as gone; all ofIOException,ArgumentExceptionandWin32Exceptionwith a live pid do not;InvalidDataExceptionandUnauthorizedAccessExceptionstill do not. Two more feed the runtime's own exceptions rather than built ones: theArgumentExceptiona realGetProcessByIdof a reaped pid raises, and (Linux only) theWin32Exceptiona realStartTimeraises for a process that exited after it was opened.failure is IOException && IsAbsent(pid)) turns 3 tests red on macOS (the two new rows and the realGetProcessByIdexception) and 4 on Linux (plus the realStartTimeexception); restored by copy andcmp-verified.Identifyfrom 4-16 threads while the target process exits and is reaped saw 649-1258 escapes per run over six runs onmain(onlyArgumentExceptionandWin32Exception) and none over five runs with this change (8x800 three times, 16x400, 4x1500; 200k-490k identities and 200k-440k typed refusals per run).LocalProcessDurableRunnerTests154/154,NativeLaunchRegistryTests91/91,ProcessLivenessDriftTests36/36 (integration project, it regex-parsesNativeProcess.cs).