Problem
AdoptExpectedChildProcessAsync (GameProcessManager.cs) terminates the launcher when a launch is
cancelled, but not when the discovery deadline expires. On the timeout path it returns
Launcher did not start {name} within {n}s and falls into:
finally
{
// Releases our handle only; the launcher keeps running and owns its own lifetime.
launcher.Dispose();
}
That disposes the only handle while the process is still alive, so a bootstrapper that never
produces a child survives the failed launch untracked, with no way for the caller to reach it. This
is the same defect class as the cancellation leak fixed in #343, on the path that fix deliberately
left alone.
The comment describes intent for the success path, where the launcher legitimately outlives
adoption. It is carried over to the failure path without that justification.
Approach
Decide whether a launcher that failed to produce a child should be terminated, then make the three
exit paths consistent. Currently:
- cancellation — terminates the tree
- non-zero launcher exit — nothing to terminate, already exited
- discovery timeout — leaves it running
TerminateAbandonedLauncher already exists and is the obvious reuse. The open question is whether
a live bootstrapper past the timeout is a hung launch to clean up, or a slow one that may still
succeed — worth checking against real Easy Anti-Cheat behaviour before changing it.
Present in release/alpha-4 as of #343.
Problem
AdoptExpectedChildProcessAsync(GameProcessManager.cs) terminates the launcher when a launch iscancelled, but not when the discovery deadline expires. On the timeout path it returns
Launcher did not start {name} within {n}sand falls into:That disposes the only handle while the process is still alive, so a bootstrapper that never
produces a child survives the failed launch untracked, with no way for the caller to reach it. This
is the same defect class as the cancellation leak fixed in #343, on the path that fix deliberately
left alone.
The comment describes intent for the success path, where the launcher legitimately outlives
adoption. It is carried over to the failure path without that justification.
Approach
Decide whether a launcher that failed to produce a child should be terminated, then make the three
exit paths consistent. Currently:
TerminateAbandonedLauncheralready exists and is the obvious reuse. The open question is whethera live bootstrapper past the timeout is a hung launch to clean up, or a slow one that may still
succeed — worth checking against real Easy Anti-Cheat behaviour before changing it.
Present in
release/alpha-4as of #343.