Skip to content

Commit 7ec9bfe

Browse files
authored
Merge pull request #1574 from rjmholt/pipelinethread-fix-debugging
Fix debugging with PSES pipeline thread changes
2 parents 800518c + 87022dc commit 7ec9bfe

File tree

114 files changed

+1906
-12966
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+1906
-12966
lines changed

ex.js

-13
This file was deleted.

src/PowerShellEditorServices.Hosting/Internal/EditorServicesRunner.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ private async Task CreateEditorServicesAndRunUntilShutdown()
130130
_logger.Log(PsesLogLevel.Diagnostic, "Creating/running editor services");
131131

132132
bool creatingLanguageServer = _config.LanguageServiceTransport != null;
133-
bool creatingDebugServer = false;// _config.DebugServiceTransport != null;
133+
bool creatingDebugServer = _config.DebugServiceTransport != null;
134134
bool isTempDebugSession = creatingDebugServer && !creatingLanguageServer;
135135

136136
// Set up information required to instantiate servers

src/PowerShellEditorServices/Extensions/Api/EditorUIService.cs

+9-3
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ public async Task<string> PromptInputAsync(string message)
116116
new ShowInputPromptRequest
117117
{
118118
Name = message,
119-
}).Returning<ShowInputPromptResponse>(CancellationToken.None);
119+
})
120+
.Returning<ShowInputPromptResponse>(CancellationToken.None)
121+
.ConfigureAwait(false);
120122

121123
if (response.PromptCancelled)
122124
{
@@ -142,7 +144,9 @@ public async Task<IReadOnlyList<string>> PromptMultipleSelectionAsync(string mes
142144
Message = message,
143145
Choices = choiceDetails,
144146
DefaultChoices = defaultChoiceIndexes?.ToArray(),
145-
}).Returning<ShowChoicePromptResponse>(CancellationToken.None);
147+
})
148+
.Returning<ShowChoicePromptResponse>(CancellationToken.None)
149+
.ConfigureAwait(false);
146150

147151
if (response.PromptCancelled)
148152
{
@@ -168,7 +172,9 @@ public async Task<string> PromptSelectionAsync(string message, IReadOnlyList<Pro
168172
Message = message,
169173
Choices = choiceDetails,
170174
DefaultChoices = defaultChoiceIndex > -1 ? new[] { defaultChoiceIndex } : null,
171-
}).Returning<ShowChoicePromptResponse>(CancellationToken.None);
175+
})
176+
.Returning<ShowChoicePromptResponse>(CancellationToken.None)
177+
.ConfigureAwait(false);
172178

173179
if (response.PromptCancelled)
174180
{

src/PowerShellEditorServices/Extensions/EditorObject.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public EditorContext GetEditorContext()
137137
internal void SetAsStaticInstance()
138138
{
139139
EditorObject.Instance = this;
140-
s_editorObjectReady.SetResult(true);
140+
s_editorObjectReady.TrySetResult(true);
141141
}
142142
}
143143
}

src/PowerShellEditorServices/PowerShellEditorServices.csproj

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
<ItemGroup>
4646
<Compile Remove="Extensions\Api\DocumentSymbolService.cs" />
4747
<Compile Remove="Services\Extension\Templating\**" />
48-
<Compile Remove="Services\PowerShellContext\**\*.cs" />
4948
<EmbeddedResource Remove="Services\Extension\Templating\**" />
5049
<None Remove="Services\Extension\Templating\**" />
5150
</ItemGroup>

src/PowerShellEditorServices/Server/PsesDebugServer.cs

+19-27
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@
1111
using Microsoft.PowerShell.EditorServices.Handlers;
1212
using Microsoft.PowerShell.EditorServices.Services;
1313
using Microsoft.PowerShell.EditorServices.Services.PowerShell;
14-
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Console;
14+
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Debugging;
15+
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Host;
16+
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Runspace;
1517
using Microsoft.PowerShell.EditorServices.Utility;
16-
using OmniSharp.Extensions.DebugAdapter.Protocol;
17-
using OmniSharp.Extensions.DebugAdapter.Protocol.Serialization;
1818
using OmniSharp.Extensions.DebugAdapter.Server;
19-
using OmniSharp.Extensions.JsonRpc;
2019
using OmniSharp.Extensions.LanguageServer.Server;
2120

2221
namespace Microsoft.PowerShell.EditorServices.Server
@@ -29,7 +28,7 @@ internal class PsesDebugServer : IDisposable
2928
/// <summary>
3029
/// This is a bool but must be an int, since Interlocked.Exchange can't handle a bool
3130
/// </summary>
32-
private static int s_hasRunPsrlStaticCtor = 0;
31+
private static readonly IdempotentLatch s_psrlCtorLatch = new();
3332

3433
private static readonly Lazy<CmdletInfo> s_lazyInvokeReadLineConstructorCmdletInfo = new Lazy<CmdletInfo>(() =>
3534
{
@@ -45,7 +44,7 @@ internal class PsesDebugServer : IDisposable
4544

4645
private DebugAdapterServer _debugAdapterServer;
4746

48-
private PowerShellExecutionService _executionService;
47+
private PowerShellDebugContext _debugContext;
4948

5049
protected readonly ILoggerFactory _loggerFactory;
5150

@@ -78,31 +77,17 @@ public async Task StartAsync()
7877
{
7978
// We need to let the PowerShell Context Service know that we are in a debug session
8079
// so that it doesn't send the powerShell/startDebugger message.
81-
_executionService = ServiceProvider.GetService<PowerShellExecutionService>();
82-
83-
/*
84-
// Needed to make sure PSReadLine's static properties are initialized in the pipeline thread.
85-
// This is only needed for Temp sessions who only have a debug server.
86-
if (_usePSReadLine && _useTempSession && Interlocked.Exchange(ref s_hasRunPsrlStaticCtor, 1) == 0)
87-
{
88-
// This must be run synchronously to ensure debugging works
89-
_executionService
90-
.ExecuteDelegateAsync((cancellationToken) =>
91-
{
92-
// Is this needed now that we do things the cool way??
93-
}, "PSRL static constructor execution", CancellationToken.None)
94-
.GetAwaiter()
95-
.GetResult();
96-
}
97-
*/
80+
_debugContext = ServiceProvider.GetService<PsesInternalHost>().DebugContext;
81+
_debugContext.IsDebugServerActive = true;
9882

9983
options
10084
.WithInput(_inputStream)
10185
.WithOutput(_outputStream)
102-
.WithServices(serviceCollection => serviceCollection
103-
.AddLogging()
104-
.AddOptions()
105-
.AddPsesDebugServices(ServiceProvider, this, _useTempSession))
86+
.WithServices(serviceCollection =>
87+
serviceCollection
88+
.AddLogging()
89+
.AddOptions()
90+
.AddPsesDebugServices(ServiceProvider, this, _useTempSession))
10691
// TODO: Consider replacing all WithHandler with AddSingleton
10792
.WithHandler<LaunchAndAttachHandler>()
10893
.WithHandler<DisconnectHandler>()
@@ -119,6 +104,9 @@ public async Task StartAsync()
119104
// The OnInitialize delegate gets run when we first receive the _Initialize_ request:
120105
// https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Initialize
121106
.OnInitialize(async (server, request, cancellationToken) => {
107+
// Ensure the debugger mode is set correctly - this is required for remote debugging to work
108+
_debugContext.EnableDebugMode();
109+
122110
var breakpointService = server.GetService<BreakpointService>();
123111
// Clear any existing breakpoints before proceeding
124112
await breakpointService.RemoveAllBreakpointsAsync().ConfigureAwait(false);
@@ -140,6 +128,10 @@ public async Task StartAsync()
140128

141129
public void Dispose()
142130
{
131+
// Note that the lifetime of the DebugContext is longer than the debug server;
132+
// It represents the debugger on the PowerShell process we're in,
133+
// while a new debug server is spun up for every debugging session
134+
_debugContext.IsDebugServerActive = false;
143135
_debugAdapterServer.Dispose();
144136
_inputStream.Dispose();
145137
_outputStream.Dispose();

src/PowerShellEditorServices/Server/PsesServiceCollectionExtensions.cs

+13-7
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ public static IServiceCollection AddPsesLanguageServices(
2828
.AddSingleton<HostStartupInfo>(hostStartupInfo)
2929
.AddSingleton<WorkspaceService>()
3030
.AddSingleton<SymbolsService>()
31-
.AddSingleton<EditorServicesConsolePSHost>()
31+
.AddSingleton<PsesInternalHost>()
3232
.AddSingleton<IRunspaceContext>(
33-
(provider) => provider.GetService<EditorServicesConsolePSHost>())
34-
.AddSingleton<PowerShellExecutionService>(
35-
(provider) => provider.GetService<EditorServicesConsolePSHost>().ExecutionService)
33+
(provider) => provider.GetService<PsesInternalHost>())
34+
.AddSingleton<IInternalPowerShellExecutionService>(
35+
(provider) => provider.GetService<PsesInternalHost>())
3636
.AddSingleton<ConfigurationService>()
3737
.AddSingleton<IPowerShellDebugContext>(
38-
(provider) => provider.GetService<EditorServicesConsolePSHost>().DebugContext)
38+
(provider) => provider.GetService<PsesInternalHost>().DebugContext)
3939
.AddSingleton<TemplateService>()
4040
.AddSingleton<EditorOperationsService>()
4141
.AddSingleton<RemoteFileManagerService>()
@@ -45,7 +45,7 @@ public static IServiceCollection AddPsesLanguageServices(
4545
provider.GetService<ILanguageServerFacade>(),
4646
provider,
4747
provider.GetService<EditorOperationsService>(),
48-
provider.GetService<PowerShellExecutionService>());
48+
provider.GetService<IInternalPowerShellExecutionService>());
4949

5050
// This is where we create the $psEditor variable
5151
// so that when the console is ready, it will be available
@@ -65,7 +65,13 @@ public static IServiceCollection AddPsesDebugServices(
6565
PsesDebugServer psesDebugServer,
6666
bool useTempSession)
6767
{
68-
return collection.AddSingleton(languageServiceProvider.GetService<PowerShellExecutionService>())
68+
PsesInternalHost internalHost = languageServiceProvider.GetService<PsesInternalHost>();
69+
70+
return collection
71+
.AddSingleton<PsesInternalHost>(internalHost)
72+
.AddSingleton<IRunspaceContext>(internalHost)
73+
.AddSingleton<IPowerShellDebugContext>(internalHost.DebugContext)
74+
.AddSingleton(languageServiceProvider.GetService<IInternalPowerShellExecutionService>())
6975
.AddSingleton(languageServiceProvider.GetService<WorkspaceService>())
7076
.AddSingleton(languageServiceProvider.GetService<RemoteFileManagerService>())
7177
.AddSingleton<PsesDebugServer>(psesDebugServer)

src/PowerShellEditorServices/Services/DebugAdapter/BreakpointService.cs

+16-16
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ namespace Microsoft.PowerShell.EditorServices.Services
1919
internal class BreakpointService
2020
{
2121
private readonly ILogger<BreakpointService> _logger;
22-
private readonly PowerShellExecutionService _executionService;
23-
private readonly EditorServicesConsolePSHost _editorServicesHost;
22+
private readonly IInternalPowerShellExecutionService _executionService;
23+
private readonly PsesInternalHost _editorServicesHost;
2424
private readonly DebugStateService _debugStateService;
2525

2626
// TODO: This needs to be managed per nested session
@@ -32,8 +32,8 @@ internal class BreakpointService
3232

3333
public BreakpointService(
3434
ILoggerFactory factory,
35-
PowerShellExecutionService executionService,
36-
EditorServicesConsolePSHost editorServicesHost,
35+
IInternalPowerShellExecutionService executionService,
36+
PsesInternalHost editorServicesHost,
3737
DebugStateService debugStateService)
3838
{
3939
_logger = factory.CreateLogger<BreakpointService>();
@@ -44,23 +44,23 @@ public BreakpointService(
4444

4545
public async Task<List<Breakpoint>> GetBreakpointsAsync()
4646
{
47-
if (BreakpointApiUtils.SupportsBreakpointApis)
47+
if (BreakpointApiUtils.SupportsBreakpointApis(_editorServicesHost.CurrentRunspace))
4848
{
4949
return BreakpointApiUtils.GetBreakpoints(
5050
_editorServicesHost.Runspace.Debugger,
5151
_debugStateService.RunspaceId);
5252
}
5353

5454
// Legacy behavior
55-
PSCommand psCommand = new PSCommand();
56-
psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Get-PSBreakpoint");
57-
IEnumerable<Breakpoint> breakpoints = await _executionService.ExecutePSCommandAsync<Breakpoint>(psCommand, new PowerShellExecutionOptions(), CancellationToken.None);
55+
PSCommand psCommand = new PSCommand()
56+
.AddCommand(@"Microsoft.PowerShell.Utility\Get-PSBreakpoint");
57+
IEnumerable<Breakpoint> breakpoints = await _executionService.ExecutePSCommandAsync<Breakpoint>(psCommand, CancellationToken.None).ConfigureAwait(false);
5858
return breakpoints.ToList();
5959
}
6060

6161
public async Task<IEnumerable<BreakpointDetails>> SetBreakpointsAsync(string escapedScriptPath, IEnumerable<BreakpointDetails> breakpoints)
6262
{
63-
if (BreakpointApiUtils.SupportsBreakpointApis)
63+
if (BreakpointApiUtils.SupportsBreakpointApis(_editorServicesHost.CurrentRunspace))
6464
{
6565
foreach (BreakpointDetails breakpointDetails in breakpoints)
6666
{
@@ -140,7 +140,7 @@ public async Task<IEnumerable<BreakpointDetails>> SetBreakpointsAsync(string esc
140140
if (psCommand != null)
141141
{
142142
IEnumerable<Breakpoint> setBreakpoints =
143-
await _executionService.ExecutePSCommandAsync<Breakpoint>(psCommand, new PowerShellExecutionOptions(), CancellationToken.None);
143+
await _executionService.ExecutePSCommandAsync<Breakpoint>(psCommand, CancellationToken.None).ConfigureAwait(false);
144144
configuredBreakpoints.AddRange(
145145
setBreakpoints.Select(BreakpointDetails.Create));
146146
}
@@ -150,7 +150,7 @@ public async Task<IEnumerable<BreakpointDetails>> SetBreakpointsAsync(string esc
150150

151151
public async Task<IEnumerable<CommandBreakpointDetails>> SetCommandBreakpoints(IEnumerable<CommandBreakpointDetails> breakpoints)
152152
{
153-
if (BreakpointApiUtils.SupportsBreakpointApis)
153+
if (BreakpointApiUtils.SupportsBreakpointApis(_editorServicesHost.CurrentRunspace))
154154
{
155155
foreach (CommandBreakpointDetails commandBreakpointDetails in breakpoints)
156156
{
@@ -217,7 +217,7 @@ public async Task<IEnumerable<CommandBreakpointDetails>> SetCommandBreakpoints(I
217217
if (psCommand != null)
218218
{
219219
IEnumerable<Breakpoint> setBreakpoints =
220-
await _executionService.ExecutePSCommandAsync<Breakpoint>(psCommand, new PowerShellExecutionOptions(), CancellationToken.None);
220+
await _executionService.ExecutePSCommandAsync<Breakpoint>(psCommand, CancellationToken.None).ConfigureAwait(false);
221221
configuredBreakpoints.AddRange(
222222
setBreakpoints.Select(CommandBreakpointDetails.Create));
223223
}
@@ -232,7 +232,7 @@ public async Task RemoveAllBreakpointsAsync(string scriptPath = null)
232232
{
233233
try
234234
{
235-
if (BreakpointApiUtils.SupportsBreakpointApis)
235+
if (BreakpointApiUtils.SupportsBreakpointApis(_editorServicesHost.CurrentRunspace))
236236
{
237237
foreach (Breakpoint breakpoint in BreakpointApiUtils.GetBreakpoints(
238238
_editorServicesHost.Runspace.Debugger,
@@ -262,7 +262,7 @@ public async Task RemoveAllBreakpointsAsync(string scriptPath = null)
262262

263263
psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Remove-PSBreakpoint");
264264

265-
await _executionService.ExecutePSCommandAsync<object>(psCommand, new PowerShellExecutionOptions(), CancellationToken.None).ConfigureAwait(false);
265+
await _executionService.ExecutePSCommandAsync<object>(psCommand, CancellationToken.None).ConfigureAwait(false);
266266
}
267267
catch (Exception e)
268268
{
@@ -272,7 +272,7 @@ public async Task RemoveAllBreakpointsAsync(string scriptPath = null)
272272

273273
public async Task RemoveBreakpointsAsync(IEnumerable<Breakpoint> breakpoints)
274274
{
275-
if (BreakpointApiUtils.SupportsBreakpointApis)
275+
if (BreakpointApiUtils.SupportsBreakpointApis(_editorServicesHost.CurrentRunspace))
276276
{
277277
foreach (Breakpoint breakpoint in breakpoints)
278278
{
@@ -308,7 +308,7 @@ public async Task RemoveBreakpointsAsync(IEnumerable<Breakpoint> breakpoints)
308308
psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Remove-PSBreakpoint");
309309
psCommand.AddParameter("Id", breakpoints.Select(b => b.Id).ToArray());
310310

311-
await _executionService.ExecutePSCommandAsync<object>(psCommand, new PowerShellExecutionOptions(), CancellationToken.None);
311+
await _executionService.ExecutePSCommandAsync<object>(psCommand, CancellationToken.None).ConfigureAwait(false);
312312
}
313313
}
314314

0 commit comments

Comments
 (0)