-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Close pipe client handles after creating the child ssh process #26491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Outdated
Show resolved
Hide resolved
…ted by the child process
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great!
One notice.
PlatformInvokes.STARTUPINFO lpStartupInfo is disposable too. It dispose the same handles but formally we should dispose it too.
|
Good point. Actually, disposing |
|
I believe we need to backport the commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
PR Summary
Fix #25203
Fix #26228
Symptom
Running the following commands on Windows will hang indefinitely today.
Invoke-Command -HostName "test" -UserName "test" -ScriptBlock { 1 }New-PSSession -HostName "test" -UserName "test"The reported hang happens on Windows only. On Linux and macOS, both commands return to the prompt with an error written out.
Root Cause
What happens on Windows is -- the
ssh.exeprocess already exited, but thestdinwriter andstdout/stderrreaders were not closed as expected. That led to the hang, as both the output and error reader threads were still blocked on thereader.ReadLinecall.This is because when creating the
ssh.exeusing the Win32 functionCreateProcess, we don't close the client handles of the pipes (stdInPipeClient,stdOutPipeClient, andstdErrPipeClient) after they get inherited by the child process (see code).When inherited by a child process, the parent side of those handles remain valid and unchanged. Windows duplicates that handle into the child process's handle table.
So, when the child process
ssh.exeexits, the pipe client handles in the child process are automatically closed. However, the pipe client handles in the parent processpowershellare still open, so the pipes will remain functional and thus the pipe server handles (i.e. the readers used in the stdout/stderr reading threads) are still open. Therefore, the hang happens.Fix Changes
To fix the issue, we need to close the parent side pipe client handles right after creating the
ssh.exeprocess, so, only thessh.exeprocess holds the handles of client side of the pipes. Then later, whenssh.exeexits, the client side of the pipe will be closed, which will, as expected, lead the server side of the pipes to be closed too.The main changes of the fix are:
lpStartupInfo.Dispose()in the finally block).System.Diagnostics.Process,System.IO.Path, etc.)PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright header