vscode-powershell icon indicating copy to clipboard operation
vscode-powershell copied to clipboard

'Safe handle has been closed' when stopping debugger while in a dynamicparam section in v2.2

Open fsackur opened this issue 3 years ago • 14 comments

Prerequisites

  • [X] Write a descriptive title.
  • [X] Make sure you are able to repro it on the latest released version
  • [X] Search the existing issues, especially the pinned issues.

Exception report

Last 200 Keys:

<omitted irrelevant keystrokes>
 f o o Spacebar - b Tab

### Exception

System.ObjectDisposedException: Safe handle has been closed
   at System.Threading.WaitHandle.WaitMultiple(WaitHandle[] waitHandles, Int32 millisecondsTimeout, Boolean exitContext, Boolean WaitAll)
   at System.Threading.WaitHandle.WaitAny(WaitHandle[] waitHandles, Int32 millisecondsTimeout, Boolean exitContext)
   at Microsoft.PowerShell.PSConsoleReadLine.ReadKey()
   at Microsoft.PowerShell.PSConsoleReadLine.InputLoop()
   at Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics, CancellationToken cancellationToken, Nullable`1 lastRunStatus)

Screenshot

N/A

Environment data

PS Version: 5.1.19041.1320
PS HostName: Visual Studio Code Host
PSReadLine Version: 2.2.0-beta4
PSReadLine EditMode: Windows
OS: 10.0.19041.1 (WinBuild.160101.0800)
BufferWidth: 227
BufferHeight: 28

Steps to reproduce

  • Use VS Code with PowerShell Preview 2021.12.0 extension
  • Create a function with dynamic parameters, e.g.:
function foo
{
    [CmdletBinding()]
    param ()

    dynamicparam
    {
        $DynParams = [Management.Automation.RuntimeDefinedParameterDictionary]::new()

        $DynParam = [Management.Automation.RuntimeDefinedParameter]::new(
            'bar',
            [string],
            [Collections.ObjectModel.Collection[System.Attribute]]::new()
        )

        $DynParams.Add($DynParam.Name, $DynParam)

        return $DynParams
    }
}
  • Put a breakpoint within the dynamicparam block and start an interactive session
  • Invoke the dynamic parameter with foo - and hit <tab>
  • Debugger stops in the dynamicparam block, as expected
  • Stop the debugger with <Ctrl-F5>
  • Integrated console returns, but shows error message

Expected behavior

No exception

Actual behavior

Error shown

fsackur avatar Dec 23 '21 17:12 fsackur

The exception indicates that the cancellationtoken passed to PSConsoleReadLine.ReadLine was disposed prematurely somehow.

daxian-dbw avatar Jan 04 '22 00:01 daxian-dbw

Well, I can reproduce this, which is great, but not sure why the token is getting prematurely disposed. Working on it 🤷

andyleejordan avatar Jan 27 '22 21:01 andyleejordan

@daxian-dbw I think this recurs when ReadLine is invoked in a nested manner. In this bug report's case, the dynamic parameter was being expanded by ReadLine, then the debugger is invoked and a new nested debug prompt opens up, invoking ReadLine a second time. I was also able to reproduce accidentally when working on another bug, and it was again when ReadLine was running and I called it a second time. Is this a supported scenario for ReadLine, if not, what's the best way to handle it?

andyleejordan avatar Feb 01 '22 21:02 andyleejordan

It's not a supported scenario. PSConsoleReadLine.ReadLine is a static method, but the operations are all around a singleton of PSConsoleReadLine. Reentry of the PSReadLine means corrupting the text buffer of the singleton and more, so it won't work.

Is it possible to identify that we are re-entering the ReadLine method? If so, how about use the old legacy readline in that rare scenario?

daxian-dbw avatar Feb 05 '22 01:02 daxian-dbw

Yeah even debugging outside of VSCode seems to fall apart in this scenario. We may want to consider automatically resuming in this case, and suggest debugging these scenarios be done via attach to process.

SeeminglyScience avatar Feb 05 '22 13:02 SeeminglyScience

Hey @fsackur, I can no longer reproduce this with the latest preview, and we fixed some issues around when to display the prompt in https://github.com/PowerShell/PowerShellEditorServices/pull/1690. Can you please verify that this no longer reproduces with v2022.2.0-preview?

andyleejordan avatar Feb 09 '22 19:02 andyleejordan

Marking as fixed, if it does still repro, please let me know, and re-open it!

andyleejordan avatar Feb 09 '22 20:02 andyleejordan

This issue has been marked as fixed. It has been automatically closed for housekeeping purposes.

ghost avatar Feb 09 '22 22:02 ghost

I do still see the issue in VS Code 1.64.2 with the PS Preview extension in the PS Integrated Terminal using PSv7.2.1:

### Environment
PSReadLine: 2.2.0-beta5
PowerShell: 2022.2.0
OS: Microsoft Windows 10.0.22000
BufferWidth: 256
BufferHeight: 31

However, in PSRL 2.2.1-rc1 in a "normal" terminal, I do not see the issue.

fsackur avatar Feb 12 '22 19:02 fsackur

This issue has been marked as fixed. It has been automatically closed for housekeeping purposes.

ghost avatar Feb 14 '22 19:02 ghost

This looks pretty broken in the stable extension too 😢

andyleejordan avatar Feb 23 '22 21:02 andyleejordan

Unfortunately still repros with v2022.4.1-preview and with https://github.com/PowerShell/PowerShellEditorServices/pull/1758, but next up is some serious work in PSReadLine.

andyleejordan avatar Apr 19 '22 00:04 andyleejordan

It'd be nice to have a better error message here, but this is still a case of needing re-entrance in PSReadLine. Now that attach to process works, I think that's the best way to debug argument completers, tab completion in general, and PSReadLine key handlers.

SeeminglyScience avatar Apr 19 '22 14:04 SeeminglyScience

Agreed.

andyleejordan avatar Apr 19 '22 16:04 andyleejordan