Skip to content

Commit a0a8df1

Browse files
committed
Get debugging to work again
1 parent cc86db4 commit a0a8df1

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

src/PowerShellEditorServices/Services/PowerShell/Console/ConsoleReplRunner.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Microsoft.Extensions.Logging;
2-
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Context;
32
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Execution;
43
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Utility;
54
using System;

src/PowerShellEditorServices/Services/PowerShell/Debugging/PowerShellDebugContext.cs

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public void ProcessDebuggerResult(DebuggerCommandResults debuggerResult)
116116
{
117117
if (debuggerResult.ResumeAction != null)
118118
{
119+
SetDebugResuming(debuggerResult.ResumeAction.Value);
119120
RaiseDebuggerResumingEvent(new DebuggerResumingEventArgs(debuggerResult.ResumeAction.Value));
120121
}
121122
}

src/PowerShellEditorServices/Services/PowerShell/Execution/PipelineThreadExecutor.cs

+4-7
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ internal class PipelineThreadExecutor
2929

3030
private readonly EditorServicesConsolePSHost _psesHost;
3131

32-
private readonly PowerShellDebugContext _debugContext;
33-
3432
private readonly IReadLineProvider _readLineProvider;
3533

3634
private readonly HostStartupInfo _hostInfo;
@@ -58,7 +56,6 @@ public PipelineThreadExecutor(
5856
_logger = loggerFactory.CreateLogger<PipelineThreadExecutor>();
5957
_hostInfo = hostInfo;
6058
_psesHost = psesHost;
61-
_debugContext = psesHost.DebugContext;
6259
_readLineProvider = readLineProvider;
6360
_consumerThreadCancellationSource = new CancellationTokenSource();
6461
_executionQueue = new BlockingCollection<ISynchronousTask>();
@@ -187,18 +184,18 @@ private void RunNestedLoop(in CancellationScope cancellationScope)
187184

188185
private void RunDebugLoop(in CancellationScope cancellationScope)
189186
{
190-
_debugContext.EnterDebugLoop(cancellationScope.CancellationToken);
187+
_psesHost.DebugContext.EnterDebugLoop(cancellationScope.CancellationToken);
191188
try
192189
{
193190
// Run commands, but cancelling our blocking wait if the debugger resumes
194-
foreach (ISynchronousTask task in _executionQueue.GetConsumingEnumerable(_debugContext.OnResumeCancellationToken))
191+
foreach (ISynchronousTask task in _executionQueue.GetConsumingEnumerable(_psesHost.DebugContext.OnResumeCancellationToken))
195192
{
196193
// We don't want to cancel the current command when the debugger resumes,
197194
// since that command will be resuming the debugger.
198195
// Instead let it complete and check the cancellation afterward.
199196
RunTaskSynchronously(task, cancellationScope.CancellationToken);
200197

201-
if (_debugContext.OnResumeCancellationToken.IsCancellationRequested)
198+
if (_psesHost.DebugContext.OnResumeCancellationToken.IsCancellationRequested)
202199
{
203200
break;
204201
}
@@ -210,7 +207,7 @@ private void RunDebugLoop(in CancellationScope cancellationScope)
210207
}
211208
finally
212209
{
213-
_debugContext.ExitDebugLoop();
210+
_psesHost.DebugContext.ExitDebugLoop();
214211
}
215212
}
216213

src/PowerShellEditorServices/Services/PowerShell/Host/EditorServicesConsolePSHost.cs

+26-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ internal class EditorServicesConsolePSHost : PSHost, IHostSupportsInteractiveSes
3636

3737
private readonly ReadLineProvider _readLineProvider;
3838

39+
private readonly Stack<KeyValuePair<Runspace, RunspaceInfo>> _runspacesInUse;
40+
3941
private string _localComputerName;
4042

4143
private int _hostStarted = 0;
@@ -48,20 +50,22 @@ public EditorServicesConsolePSHost(
4850
_logger = loggerFactory.CreateLogger<EditorServicesConsolePSHost>();
4951
_psFrameStack = new Stack<PowerShellContextFrame>();
5052
_psFactory = new PowerShellFactory(loggerFactory, this);
53+
_runspacesInUse = new Stack<KeyValuePair<Runspace, RunspaceInfo>>();
5154
_hostInfo = hostInfo;
5255
Name = hostInfo.Name;
5356
Version = hostInfo.Version;
5457

5558
_readLineProvider = new ReadLineProvider(loggerFactory);
5659
_pipelineExecutor = new PipelineThreadExecutor(loggerFactory, hostInfo, this, _readLineProvider);
5760
ExecutionService = new PowerShellExecutionService(loggerFactory, this, _pipelineExecutor);
58-
DebugContext = new PowerShellDebugContext(loggerFactory, languageServer, this, _consoleReplRunner);
5961
UI = new EditorServicesConsolePSHostUserInterface(loggerFactory, _readLineProvider, hostInfo.PSHost.UI);
6062

6163
if (hostInfo.ConsoleReplEnabled)
6264
{
6365
_consoleReplRunner = new ConsoleReplRunner(loggerFactory, this, _readLineProvider, ExecutionService);
6466
}
67+
68+
DebugContext = new PowerShellDebugContext(loggerFactory, languageServer, this, _consoleReplRunner);
6569
}
6670

6771
public override CultureInfo CurrentCulture => _hostInfo.PSHost.CurrentCulture;
@@ -217,9 +221,28 @@ private void SetExit()
217221

218222
private void PushPowerShellAndRunLoop(SMA.PowerShell pwsh, PowerShellFrameType frameType)
219223
{
224+
RunspaceInfo runspaceInfo = null;
225+
if (_runspacesInUse.Count > 0)
226+
{
227+
// This is more than just an optimization.
228+
// When debugging, we cannot execute PowerShell directly to get this information;
229+
// trying to do so will block on the command that called us, deadlocking execution.
230+
// Instead, since we are reusing the runspace, we reuse that runspace's info as well.
231+
KeyValuePair<Runspace, RunspaceInfo> currentRunspace = _runspacesInUse.Peek();
232+
if (currentRunspace.Key == pwsh.Runspace)
233+
{
234+
runspaceInfo = currentRunspace.Value;
235+
}
236+
}
237+
238+
if (runspaceInfo is null)
239+
{
240+
RunspaceOrigin runspaceOrigin = pwsh.Runspace.RunspaceIsRemote ? RunspaceOrigin.EnteredProcess : RunspaceOrigin.Local;
241+
runspaceInfo = RunspaceInfo.CreateFromPowerShell(_logger, pwsh, runspaceOrigin, _localComputerName);
242+
_runspacesInUse.Push(new KeyValuePair<Runspace, RunspaceInfo>(pwsh.Runspace, runspaceInfo));
243+
}
244+
220245
// TODO: Improve runspace origin detection here
221-
RunspaceOrigin runspaceOrigin = pwsh.Runspace.RunspaceIsRemote ? RunspaceOrigin.EnteredProcess : RunspaceOrigin.Local;
222-
var runspaceInfo = RunspaceInfo.CreateFromPowerShell(_logger, pwsh, runspaceOrigin, _localComputerName);
223246
PushPowerShellAndRunLoop(new PowerShellContextFrame(pwsh, runspaceInfo, frameType));
224247
}
225248

0 commit comments

Comments
 (0)