@@ -162,8 +162,18 @@ public RunspaceDetails CurrentRunspace
162162 /// </summary>
163163 public string InitialWorkingDirectory { get ; private set ; }
164164
165+ /// <summary>
166+ /// Tracks the state of the LSP debug server (not the PowerShell debugger).
167+ /// </summary>
165168 internal bool IsDebugServerActive { get ; set ; }
166169
170+ /// <summary>
171+ /// Tracks if the PowerShell session started the debug server itself (true), or if it was
172+ /// started by an LSP notification (false). Essentially, this marks if we're responsible for
173+ /// stopping the debug server (and thus need to send a notification to do so).
174+ /// </summary>
175+ internal bool OwnsDebugServerState { get ; set ; }
176+
167177 internal DebuggerStopEventArgs CurrentDebuggerStopEventArgs { get ; private set ; }
168178
169179 #endregion
@@ -777,6 +787,21 @@ public async Task<IEnumerable<TResult>> ExecuteCommandAsync<TResult>(
777787 await this . sessionStateLock . ReleaseForExecuteCommand ( ) . ConfigureAwait ( false ) ;
778788 }
779789
790+ // This is the edge case where the debug server is running because it was
791+ // started by PowerShell (and not by an LSP event), and we're no longer in the
792+ // debugger within PowerShell, so since we own the state we need to stop the
793+ // debug server too.
794+ //
795+ // Strangely one would think we could check `!PromptNest.IsInDebugger` but that
796+ // doesn't work, we have to check if the shell is nested instead. Therefore this
797+ // is a bit fragile, and I don't know how it'll work in a remoting scenario.
798+ if ( IsDebugServerActive && OwnsDebugServerState && ! shell . IsNested )
799+ {
800+ logger . LogDebug ( "Stopping LSP debugger because PowerShell debugger stopped running!" ) ;
801+ OwnsDebugServerState = false ;
802+ _languageServer ? . SendNotification ( "powerShell/stopDebugger" ) ;
803+ }
804+
780805 if ( shell . HadErrors )
781806 {
782807 var strBld = new StringBuilder ( 1024 ) ;
@@ -2422,8 +2447,14 @@ private void OnDebuggerStop(object sender, DebuggerStopEventArgs e)
24222447 // when the DebugServer is fully started.
24232448 CurrentDebuggerStopEventArgs = e ;
24242449
2450+ // If this event has fired but the LSP debug server is not active, it means that the
2451+ // PowerShell debugger has started some other way (most likely an existing PSBreakPoint
2452+ // was executed). So not only do we have to start the server, but later we will be
2453+ // responsible for stopping it too.
24252454 if ( ! IsDebugServerActive )
24262455 {
2456+ logger . LogDebug ( "Starting LSP debugger because PowerShell debugger is running!" ) ;
2457+ OwnsDebugServerState = true ;
24272458 _languageServer ? . SendNotification ( "powerShell/startDebugger" ) ;
24282459 }
24292460
0 commit comments