Description
I've been looking at what PowerShell says is running every time I've hit a dead lock. Every time, it's Install-Package
generating dynamic parameters.
Repro
-
Install module
ImpliedReflection
(or other preferred reflection module) -
Wait for a dead lock after completion
-
Get the process ID of the integrated console with
Get-PSHostProcess
(Hint: it won't have a window title) -
Enter the process with
Enter-PSHostProcess
-
Get the main PSIC runspace with
$rs = Get-Runspace 2
-
Enable implied reflection with
Enable-ImpliedReflection
-
Navigate to
$rs.ExecutionContext.CurrentCommandProcessor
. Should look something like this:Click to expand output
FromScriptFile : False _cmdletParameterBinderController : System.Management.Automation.CmdletParameterBinderController u_obsoleteAttribute : _firstCallToRead : True _bailInNextCall : False RanBeginAlready : False _addedToPipelineAlready : False _fromScriptFile : False CommandRuntime : Install-Package _useLocalScope : True _context : System.Management.Automation.ExecutionContext arguments : {} CmdletParameterBinderController : System.Management.Automation.CmdletParameterBinderController ObsoleteAttribute : AddedToPipelineAlready : False CommandInfo : Install-Package RedirectShellErrorOutputPipe : False Command : Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage UseLocalScope : True Context : System.Management.Automation.ExecutionContext PipelineActivityId : 00000000-0000-0000-0000-000000000000 CommandSessionState : System.Management.Automation.SessionStateInternal CommandScope : System.Management.Automation.SessionStateScope
-
Navigate to
$rs.ExecutionContext.CurrentCommandProcessor.Command
. Should look something like this:Click to expand output
InputObject : Name : RequiredVersion : MinimumVersion : MaximumVersion : Source : Credential : Proxy : ProxyCredential : Sources : {} WebProxy : CredentialUsername : CredentialPassword : AllVersions : False ProviderName : MessageResolver : DynamicOptions : {} OptionKeys : {} IsInteractive : False CallCount : 2 WhatIf : False IsCanceled : False DynamicParameterDictionary : {} ParameterSetName : PackageBySearch MyInvocation : System.Management.Automation.InvocationInfo PagingParameters : InvokeCommand : System.Management.Automation.CommandInvocationIntrinsics Host : System.Management.Automation.Internal.Host.InternalHost SessionState : System.Management.Automation.SessionState Events : System.Management.Automation.PSLocalEventManager JobRepository : System.Management.Automation.JobRepository JobManager : System.Management.Automation.JobManager InvokeProvider : System.Management.Automation.ProviderIntrinsics Stopping : False CommandRuntime : Install-Package CurrentPSTransaction : CommandOrigin : Internal Force : False ForceBootstrap : False <InputObject>k__BackingField : <Name>k__BackingField : <RequiredVersion>k__BackingField : <MinimumVersion>k__BackingField : <MaximumVersion>k__BackingField : _resultsPerName : {} _providersNotFindingAnything : {} IsFailingEarly : False UserSpecifiedSourcesList : {} CmdletState : GenerateParameters CancellationEvent : System.Threading.CancellationTokenSource ErrorState : False currentObjectInPipeline : CommandOriginInternal : Internal ParameterSets : {PackageBySearch, PackageByInputObject} SpecifiedMinimumOrMaximum : False BootstrapNuGet : true SelectedProviders : {Programs, msu, msi, NuGet...} CachedSelectedProviders : {Programs, msu, msi, NuGet...} CachedDynamicOptions : {IncludeWindowsInstaller, IncludeSystemComponent, AdditionalArguments, ConfigFile...} CachedStaticParameters : IsDisplayCulture : False UseDefaultSourceFormat : True ShouldLogError : True ShouldSelectAllProviders : False IsPackageBySearch : True IsPackageByObject : False IsSourceByObject : False PackageManagementService : Microsoft.PackageManagement.Internal.Implementation.PackageManagementService TimeOut : 3600 Responsiveness : 900 PackageManagementHost : IHostApi_proxy_20 IsReentrantLocked : True Confirm : False IsInvocation : False HasErrors : False UnboundArguments : {} IsProcessing : False IsBeforeProcessing : True IsAfterProcessing : False HasDynamicParameters : True RunspaceRepository : System.Management.Automation.RunspaceRepository _ParameterSetName : PackageBySearch InvocationExtent : CurrentPipelineObject : PSHostInternal : System.Management.Automation.Internal.Host.InternalHost InternalState : System.Management.Automation.SessionState IsStopping : False CommandInfo : Install-Package Context : System.Management.Automation.ExecutionContext
PackageManagement makes heavy use of async in their cmdlets. My guess is they are inheriting our single threaded background synchronization context when they previously were not.
Note: Cancelling the command via their internal API ($rs.ExecutionContext.CurrentCommandProcessor.Command.Cancel()
) doesn't do anything, which makes sense if it's a threading related dead lock.