PowerShell / PowerShell/PowerShell

SDK causes occasional .NET crash on WSManCloseCommand

Open
#25,582 1 comment 10 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Needs-Triage WG-Remoting
Dominant language
C#
Stars
55.5k
Forks
8.5k
Avg merge
1d 2h
Merged PRs (30d)
88

Description

Prerequisites
Steps to reproduce

We have a .Net Windows Service that uses the Powershell SDK to connect to many remote machines and maintain connections for long periods of time.

We experience in some environments a crash every couple of days, and as such, the exact steps to reproduce are not exactly clear, but there is a strong lead to the exact issue in the code, to be described below.

It is not possible for us at this point to use the latest major SDK version, as the required .Net version is not yet supported in the production environment, and it does not reproduce in our smaller test environments. However, we will show below that the suspected issue in the codebase exists on the latest version as well.

The dump stack trace:

CoreCLR Version: 8.0.1325.6609
.NET Version: 8.0.13
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Stack:
   at System.Management.Automation.Remoting.Client.WSManNativeApi.WSManCloseCommand(IntPtr, Int32, IntPtr)
   at System.Management.Automation.Remoting.Client.WSManNativeApi.WSManCloseCommand(IntPtr, Int32, IntPtr)
   at System.Management.Automation.Remoting.Client.WSManClientCommandTransportManager.CloseAsync()
   at System.Management.Automation.Runspaces.Internal.ClientRemotePowerShell.HandleInvocationStateInfoReceived(System.Object, System.Management.Automation.RemoteDataEventArgs`1<System.Management.Automation.PSInvocationStateInfo>)
   at System.Management.Automation.Remoting.Client.WSManClientCommandTransportManager.RaiseErrorHandler(System.Management.Automation.Remoting.TransportErrorOccuredEventArgs)
   at System.Management.Automation.Remoting.Client.BaseClientTransportManager.ServicePendingCallbacks(System.Object)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()

Code analysis -
We have a strong suspicion that the crash is caused by a race condition in WSManClientCommandTransportManager between Dispose and CloseAsync methods:
WSManClientCommandTransportManager.CloseAsync may be called internally by the SDK when the runspace pool state becomes broken, for example. Before invoking WSManCloseCommand, it initializes the _closeCmdCompleted member.

However, calling RunspacePool.Dispose from the application code ends up in WSManClientCommandTransportManager.Dispose, which disposes the _closeCmdCompleted. This means that the WSManCloseCommand, which may hang for a long time, would end up invoking a callback that has already been freed, resulting in access violation.

Expected behavior
Invoking WSManCloseCommand does not result in .Net crash
Actual behavior
Invoking WSManCloseCommand may result in .Net crash
Error details

Environment data
Powershell SDK 7.4.10 on .NET 8
Visuals

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading WSManClientCommandTransportManager.CloseAsync and Dispose, focusing on their handling of _closeCmdCompleted and the WSManCloseCommand callback. Use the provided stack trace and race-condition description to investigate concurrent runspace-pool shutdown. Done means invoking WSManCloseCommand during disposal no longer produces the reported .NET access violation.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, powershell
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.