Skip to content

Commit a0ace7e

Browse files
committed
Send stopDebugger notification when appropriate
1 parent 53b3952 commit a0ace7e

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

src/PowerShellEditorServices/Server/PsesDebugServer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public async Task StartAsync()
7777
// so that it doesn't send the powerShell/startDebugger message.
7878
_powerShellContextService = ServiceProvider.GetService<PowerShellContextService>();
7979
_powerShellContextService.IsDebugServerActive = true;
80+
_powerShellContextService.OwnsDebugServerState = false;
8081

8182
// Needed to make sure PSReadLine's static properties are initialized in the pipeline thread.
8283
// This is only needed for Temp sessions who only have a debug server.

src/PowerShellEditorServices/Services/PowerShellContext/PowerShellContextService.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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,20 @@ 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+
_languageServer?.SendNotification("powerShell/stopDebugger");
802+
}
803+
780804
if (shell.HadErrors)
781805
{
782806
var strBld = new StringBuilder(1024);
@@ -2422,8 +2446,14 @@ private void OnDebuggerStop(object sender, DebuggerStopEventArgs e)
24222446
// when the DebugServer is fully started.
24232447
CurrentDebuggerStopEventArgs = e;
24242448

2449+
// If this event has fired but the LSP debug server is not active, it means that the
2450+
// PowerShell debugger has started some other way (most likely an existing PSBreakPoint
2451+
// was executed). So not only do we have to start the server, but later we will be
2452+
// responsible for stopping it too.
24252453
if (!IsDebugServerActive)
24262454
{
2455+
logger.LogDebug("Starting LSP debugger because PowerShell debugger is running!");
2456+
OwnsDebugServerState = true;
24272457
_languageServer?.SendNotification("powerShell/startDebugger");
24282458
}
24292459

0 commit comments

Comments
 (0)