-
Notifications
You must be signed in to change notification settings - Fork 242
Description
Prerequisites
- I have written a descriptive issue title.
- I have searched all open and closed issues to ensure it has not already been reported.
- I have read the troubleshooting guide.
- I am sure this issue is with PowerShell Editor Services itself and does not reproduce in a standalone PowerShell instance, and is not an issue with my editor.
- I have verified that I am using the latest version of PowerShell Editor Services.
- If this is a security issue, I have read the security issue reporting guidance.
Summary
When using remote PowerShell debugging from VS Code server (Linux → Windows over PSSession over SSH) with a launch configuration and path mappings, the remote PSSession unexpectedly drops immediately after the debug session finishes. As soon as any command is run post-debugging, the user gets kicked back to the local session.
Updated Technical Analysis:
After investigating the PowerShellEditorServices codebase, I traced the issue through this execution flow:
Launch sessions never set ExecutionCompleted = true when they finish normally
When the debug session ends, the DisconnectHandler runs and checks ExecutionCompleted DisconnectHandler.cs:55-58
Because ExecutionCompleted is still false, it calls _debugService.Abort()
Abort() calls SetDebugResuming(DebuggerResumeAction.Stop) PowerShellDebugContext.cs:97
SetDebugResuming() then calls _psesHost.SetExit() PowerShellDebugContext.cs:115
SetExit() sets _shouldExit = true on the remote frame when it's a REPL with multiple frames PsesInternalHost.cs:360-371
The next time the run loop executes (RunExecutionLoop, around line 917), it sees _shouldExit == true for a remote, non-nested REPL frame and calls PopPowerShell() PsesInternalHost.cs:917-922
PopPowerShell() pops the remote REPL frame and detects the runspace change, which causes it to pop from _runspaceStack, exiting the PSSession PsesInternalHost.cs:763-790
Root Cause
The root cause is that SetExit() is being called inappropriately after the debug frame has been popped. When Abort() is called from DisconnectHandler, the current frame is the main remote REPL frame (not a debug or nested frame), so setting _shouldExit = true causes the remote session to exit on the next command.
Launch sessions should set ExecutionCompleted = true in OnExecutionCompletedAsync LaunchAndAttachHandler.cs:493 , but this isn't happening properly, causing the disconnect handler to treat a normal completion as an abort scenario.
Proposed Fix
Add an early return in SetExit() when the frame isn't nested and isn't a debug frame:
if (!frame.IsNested && !frame.IsDebug)
{
return;
}
PowerShell Version
$PSVersionTable
Name Value
---- -----
PSVersion 7.5.4
PSEdition Core
GitCommitId 7.5.4
OS Rocky Linux 8.10 (Green Obsidian)
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0Editor Version
emacs --version
GNU Emacs 30.1.90PowerShell Editor Services Version
$pseditor.EditorServicesVersion
Major Minor Build Revision
----- ----- ----- --------
4 4 0 0Steps to Reproduce
Steps to Reproduce
Set up VS Code server on Linux
Configure launch debugging with path mappings
Establish remote PSSession to Windows machine over SSH
Set breakpoint
Start a launch-based debug session
Let the debug session complete normally
Run any command in the remote session
Observe that the PSSession drops and returns to local session
Expected Behavior
The remote PSSession should remain active after a launch debug session completes, allowing continued work in the remote context.
Actual Behavior
The remote PSSession drops immediately after the first command is run following debug session completion.
Visuals
No response
Logs
No response