Skip to content

Commit 897a966

Browse files
committed
FIXUP: Fixing some issues with debugging
1 parent bb504d5 commit 897a966

File tree

7 files changed

+118
-31
lines changed

7 files changed

+118
-31
lines changed

src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class DebugAdapter : DebugAdapterBase
2525
private EditorSession editorSession;
2626

2727
private bool noDebug;
28+
private bool isAttachSession;
2829
private bool waitingForAttach;
2930
private bool ownsEditorSession;
3031
private string scriptPathToLaunch;
@@ -187,8 +188,12 @@ protected async Task HandleLaunchRequest(
187188
#endif
188189
}
189190

190-
editorSession.PowerShellContext.SetWorkingDirectory(workingDir);
191-
Logger.Write(LogLevel.Verbose, "Working dir set to: " + workingDir);
191+
// TODO: What's the right approach here?
192+
if (this.editorSession.PowerShellContext.CurrentRunspace.Location == RunspaceLocation.Local)
193+
{
194+
editorSession.PowerShellContext.SetWorkingDirectory(workingDir);
195+
Logger.Write(LogLevel.Verbose, "Working dir set to: " + workingDir);
196+
}
192197

193198
// Prepare arguments to the script - if specified
194199
string arguments = null;
@@ -205,6 +210,16 @@ protected async Task HandleLaunchRequest(
205210
#pragma warning restore 618
206211
this.arguments = arguments;
207212

213+
// If the current session is remote, map the script path to the remote
214+
// machine if necessary
215+
if (this.editorSession.PowerShellContext.CurrentRunspace.Location == RunspaceLocation.Remote)
216+
{
217+
this.scriptPathToLaunch =
218+
this.editorSession.RemoteFileManager.GetMappedPath(
219+
this.scriptPathToLaunch,
220+
this.editorSession.PowerShellContext.CurrentRunspace);
221+
}
222+
208223
await requestContext.SendResult(null);
209224

210225
// If no script is being launched, execute an empty script to
@@ -226,6 +241,8 @@ protected async Task HandleAttachRequest(
226241
AttachRequestArguments attachParams,
227242
RequestContext<object> requestContext)
228243
{
244+
this.isAttachSession = true;
245+
229246
// If there are no host processes to attach to or the user cancels selection, we get a null for the process id.
230247
// This is not an error, just a request to stop the original "attach to" request.
231248
// Testing against "undefined" is a HACK because I don't know how to make "Cancel" on quick pick loading
@@ -270,8 +287,7 @@ await requestContext.SendError(
270287
}
271288
}
272289

273-
int processId;
274-
if (int.TryParse(attachParams.ProcessId, out processId) && (processId > 0))
290+
if (int.TryParse(attachParams.ProcessId, out int processId) && (processId > 0))
275291
{
276292
PowerShellVersionDetails runspaceVersion =
277293
this.editorSession.PowerShellContext.CurrentRunspace.PowerShellVersion;
@@ -296,6 +312,10 @@ await requestContext.SendError(
296312
return;
297313
}
298314

315+
// Stop the current read loop because the debugger
316+
// will start its own
317+
//this.editorSession.ConsoleService.CancelReadLoop();
318+
299319
// Execute the Debug-Runspace command but don't await it because it
300320
// will block the debug adapter initialization process. The
301321
// InitializedEvent will be sent as soon as the RunspaceChanged
@@ -327,13 +347,27 @@ protected async Task HandleDisconnectRequest(
327347
{
328348
EventHandler<SessionStateChangedEventArgs> handler = null;
329349

350+
// Define a handler that encapsulates the RequestContext so
351+
// that it can be completed once the executed script is
352+
// shutting down.
330353
handler =
331354
async (o, e) =>
332355
{
333356
if (e.NewSessionState == PowerShellContextState.Ready)
334357
{
335358
await requestContext.SendResult(null);
336359
this.editorSession.PowerShellContext.SessionStateChanged -= handler;
360+
361+
if (this.isAttachSession)
362+
{
363+
// Start up the read loop again if this is a shared session
364+
if (!this.ownsEditorSession)
365+
{
366+
this.editorSession.ConsoleService.StartReadLoop();
367+
}
368+
369+
await this.Stop();
370+
}
337371
}
338372
};
339373

@@ -741,7 +775,10 @@ async void powerShellContext_RunspaceChanged(object sender, RunspaceChangedEvent
741775
this.waitingForAttach = false;
742776
await this.SendEvent(InitializedEvent.Type, null);
743777
}
744-
else if (e.ChangeAction == RunspaceChangeAction.Exit && this.editorSession.PowerShellContext.IsDebuggerStopped)
778+
else if (
779+
e.ChangeAction == RunspaceChangeAction.Exit &&
780+
(this.editorSession == null ||
781+
this.editorSession.PowerShellContext.IsDebuggerStopped))
745782
{
746783
// Exited the session while the debugger is stopped,
747784
// send a ContinuedEvent so that the client changes the

src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ public LanguageServer(HostDetails hostDetails, ProfilePaths profilePaths, Channe
7878
this.editorSession,
7979
this);
8080

81+
this.editorSession.StartDebugService(this.editorOperations);
82+
8183
// Always send console prompts through the UI in the language service
8284
// TODO: This will change later once we have a general REPL available
8385
// in VS Code.

src/PowerShellEditorServices/Console/ConsoleReadLine.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,14 @@ public async Task<string> ReadCommandLine(CancellationToken cancellationToken)
210210
{
211211
historyIndex = -1;
212212

213-
using (RunspaceHandle runspaceHandle = await this.powerShellContext.GetRunspaceHandle())
214-
using (PowerShell powerShell = PowerShell.Create())
215-
{
216-
powerShell.Runspace = runspaceHandle.Runspace;
217-
powerShell.AddCommand("Get-History");
218-
currentHistory = powerShell.Invoke();
219-
}
213+
PSCommand command = new PSCommand();
214+
command.AddCommand("Get-History");
215+
216+
currentHistory =
217+
await this.powerShellContext.ExecuteCommand<PSObject>(
218+
command,
219+
false,
220+
false) as Collection<PSObject>;
220221

221222
if (currentHistory != null)
222223
{

src/PowerShellEditorServices/Console/ConsoleService.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,18 @@ public void StartReadLoop()
119119
TaskScheduler.Default);
120120
}
121121

122+
/// <summary>
123+
/// Cancels an active read loop.
124+
/// </summary>
125+
public void CancelReadLoop()
126+
{
127+
if (this.readLineCancellationToken != null)
128+
{
129+
this.readLineCancellationToken.Cancel();
130+
this.readLineCancellationToken = null;
131+
}
132+
}
133+
122134
/// <summary>
123135
/// Stops the current terminal-based interactive console.
124136
/// </summary>
@@ -141,6 +153,8 @@ public void StopInteractiveConsole()
141153
/// <param name="echoToConsole">If true, the input will be echoed to the console.</param>
142154
public void ExecuteCommand(string inputString, bool echoToConsole)
143155
{
156+
this.CancelReadLoop();
157+
144158
if (this.activePromptHandler != null)
145159
{
146160
if (echoToConsole)
@@ -321,15 +335,6 @@ await this.powerShellContext.ExecuteScriptString(
321335
while (!cancellationToken.IsCancellationRequested);
322336
}
323337

324-
private void CancelReadLoop()
325-
{
326-
if (this.readLineCancellationToken != null)
327-
{
328-
this.readLineCancellationToken.Cancel();
329-
this.readLineCancellationToken = null;
330-
}
331-
}
332-
333338
#endregion
334339

335340
#region Events
@@ -427,6 +432,9 @@ private void activePromptHandler_PromptCancelled(object sender, EventArgs e)
427432

428433
private void PowerShellContext_DebuggerStop(object sender, System.Management.Automation.DebuggerStopEventArgs e)
429434
{
435+
// Cancel any existing prompt first
436+
this.CancelReadLoop();
437+
430438
this.WriteDebuggerBanner(e);
431439
this.StartReadLoop();
432440
}

src/PowerShellEditorServices/Session/EditorSession.cs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ public class EditorSession
6060
/// </summary>
6161
public TemplateService TemplateService { get; private set; }
6262

63+
/// <summary>
64+
/// Gets the RemoteFileManager instance for this session.
65+
/// </summary>
66+
public RemoteFileManager RemoteFileManager { get; private set; }
67+
6368
#endregion
6469

6570
#region Public Methods
@@ -74,12 +79,13 @@ public class EditorSession
7479
/// <param name="profilePaths">
7580
/// An object containing the profile paths for the session.
7681
/// </param>
77-
public void StartSession(HostDetails hostDetails, ProfilePaths profilePaths)
82+
public void StartSession(
83+
HostDetails hostDetails,
84+
ProfilePaths profilePaths)
7885
{
7986
// Initialize all services
8087
this.PowerShellContext = new PowerShellContext(hostDetails, profilePaths);
8188
this.LanguageService = new LanguageService(this.PowerShellContext);
82-
this.DebugService = new DebugService(this.PowerShellContext);
8389
this.ConsoleService = new ConsoleService(this.PowerShellContext);
8490
this.ExtensionService = new ExtensionService(this.PowerShellContext);
8591
this.TemplateService = new TemplateService(this.PowerShellContext);
@@ -111,15 +117,28 @@ public void StartDebugSession(
111117
// Initialize all services
112118
this.PowerShellContext = new PowerShellContext(hostDetails, profilePaths);
113119
this.ConsoleService = new ConsoleService(this.PowerShellContext);
114-
this.DebugService =
115-
new DebugService(
116-
this.PowerShellContext,
117-
new RemoteFileManager(this.PowerShellContext, editorOperations));
120+
this.RemoteFileManager = new RemoteFileManager(this.PowerShellContext, editorOperations);
121+
this.DebugService = new DebugService(this.PowerShellContext, this.RemoteFileManager);
118122

119123
// Create a workspace to contain open files
120124
this.Workspace = new Workspace(this.PowerShellContext.LocalPowerShellVersion.Version);
121125
}
122126

127+
/// <summary>
128+
/// Starts the DebugService if it's not already strated
129+
/// </summary>
130+
/// <param name="editorOperations">
131+
/// An IEditorOperations implementation used to interact with the editor.
132+
/// </param>
133+
public void StartDebugService(IEditorOperations editorOperations)
134+
{
135+
if (this.DebugService == null)
136+
{
137+
this.RemoteFileManager = new RemoteFileManager(this.PowerShellContext, editorOperations);
138+
this.DebugService = new DebugService(this.PowerShellContext, this.RemoteFileManager);
139+
}
140+
}
141+
123142
internal void InstantiateAnalysisService(string settingsPath = null)
124143
{
125144
// AnalysisService will throw FileNotFoundException if

src/PowerShellEditorServices/Session/PowerShellContext.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -735,10 +735,10 @@ public void AbortExecution()
735735
{
736736
this.ResumeDebugger(DebuggerResumeAction.Stop);
737737
}
738-
else
739-
{
738+
//else
739+
//{
740740
this.powerShell.BeginStop(null, null);
741-
}
741+
//}
742742

743743
this.SessionState = PowerShellContextState.Aborting;
744744
}
@@ -1461,6 +1461,24 @@ private void OnDebuggerStop(object sender, DebuggerStopEventArgs e)
14611461
// Notify listeners that the debugger has resumed
14621462
this.DebuggerResumed?.Invoke(this, e.ResumeAction);
14631463

1464+
// Pop the current RunspaceDetails if we were attached
1465+
// to a runspace and the resume action is Stop
1466+
if (this.CurrentRunspace.Context == RunspaceContext.DebuggedRunspace &&
1467+
e.ResumeAction == DebuggerResumeAction.Stop)
1468+
{
1469+
this.PopRunspace();
1470+
}
1471+
else if (e.ResumeAction != DebuggerResumeAction.Stop)
1472+
{
1473+
// Update the session state
1474+
this.OnSessionStateChanged(
1475+
this,
1476+
new SessionStateChangedEventArgs(
1477+
PowerShellContextState.Running,
1478+
PowerShellExecutionResult.NotFinished,
1479+
null));
1480+
}
1481+
14641482
break;
14651483
}
14661484
else if (taskIndex == 1)

src/PowerShellEditorServices/Session/RunspaceDetails.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ internal static RunspaceDetails CreateFromRunspace(
152152

153153
var runspaceId = runspace.InstanceId;
154154
var runspaceLocation = RunspaceLocation.Local;
155+
var runspaceContext = RunspaceContext.Original;
155156
var versionDetails = PowerShellVersionDetails.GetVersionDetails(runspace);
156157

157158
string connectionString = null;
@@ -166,6 +167,7 @@ internal static RunspaceDetails CreateFromRunspace(
166167
if (connectionInfo.ProcessId != null)
167168
{
168169
connectionString = connectionInfo.ProcessId.ToString();
170+
runspaceContext = RunspaceContext.EnteredProcess;
169171
}
170172
}
171173
catch (RuntimeBinderException)
@@ -193,7 +195,7 @@ internal static RunspaceDetails CreateFromRunspace(
193195
sessionDetails,
194196
versionDetails,
195197
runspaceLocation,
196-
RunspaceContext.Original,
198+
runspaceContext,
197199
connectionString);
198200
}
199201

0 commit comments

Comments
 (0)