Skip to content

Fix crash when breakpoint gets hit outside of debug mode #409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 31, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 46 additions & 11 deletions src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class DebugAdapter : DebugAdapterBase
private bool isAttachSession;
private bool waitingForAttach;
private string scriptToLaunch;
private bool enableConsoleRepl;
private bool ownsEditorSession;
private bool executionCompleted;
private string arguments;
Expand All @@ -44,29 +45,29 @@ public DebugAdapter(EditorSession editorSession, ChannelBase serverChannel)
: base(serverChannel)
{
this.editorSession = editorSession;
this.editorSession.PowerShellContext.RunspaceChanged += this.powerShellContext_RunspaceChanged;
this.editorSession.DebugService.DebuggerStopped += this.DebugService_DebuggerStopped;
this.editorSession.PowerShellContext.DebuggerResumed += this.powerShellContext_DebuggerResumed;
}

public DebugAdapter(
HostDetails hostDetails,
ProfilePaths profilePaths,
ChannelBase serverChannel,
IEditorOperations editorOperations)
: this(hostDetails, profilePaths, serverChannel, editorOperations, false)
{
}

public DebugAdapter(
HostDetails hostDetails,
ProfilePaths profilePaths,
ChannelBase serverChannel,
IEditorOperations editorOperations,
bool enableConsoleRepl)
: base(serverChannel)
{
this.ownsEditorSession = true;
this.editorSession = new EditorSession();
this.editorSession.StartDebugSession(hostDetails, profilePaths, editorOperations);
this.editorSession.PowerShellContext.RunspaceChanged += this.powerShellContext_RunspaceChanged;
this.editorSession.DebugService.DebuggerStopped += this.DebugService_DebuggerStopped;
this.editorSession.PowerShellContext.DebuggerResumed += this.powerShellContext_DebuggerResumed;

// The assumption in this overload is that the debugger
// is running in UI-hosted mode, no terminal interface
this.editorSession.ConsoleService.OutputWritten += this.powerShellContext_OutputWritten;
this.outputDebouncer = new OutputDebouncer(this);
this.enableConsoleRepl = enableConsoleRepl;
}

protected override void Initialize()
Expand Down Expand Up @@ -139,6 +140,8 @@ private async Task OnExecutionCompleted(Task executeTask)
await this.outputDebouncer.Flush();
}

this.UnregisterEventHandlers();

if (this.isAttachSession)
{
// Ensure the read loop is stopped
Expand Down Expand Up @@ -198,6 +201,7 @@ protected override void Shutdown()
{
this.editorSession.PowerShellContext.RunspaceChanged -= this.powerShellContext_RunspaceChanged;
this.editorSession.DebugService.DebuggerStopped -= this.DebugService_DebuggerStopped;
this.editorSession.PowerShellContext.DebuggerResumed -= this.powerShellContext_DebuggerResumed;

if (this.ownsEditorSession)
{
Expand Down Expand Up @@ -238,6 +242,8 @@ protected async Task HandleLaunchRequest(
LaunchRequestArguments launchParams,
RequestContext<object> requestContext)
{
this.RegisterEventHandlers();

// Set the working directory for the PowerShell runspace to the cwd passed in via launch.json.
// In case that is null, use the the folder of the script to be executed. If the resulting
// working dir path is a file path then extract the directory and use that.
Expand Down Expand Up @@ -335,6 +341,8 @@ protected async Task HandleAttachRequest(
{
this.isAttachSession = true;

this.RegisterEventHandlers();

// If there are no host processes to attach to or the user cancels selection, we get a null for the process id.
// This is not an error, just a request to stop the original "attach to" request.
// Testing against "undefined" is a HACK because I don't know how to make "Cancel" on quick pick loading
Expand Down Expand Up @@ -454,6 +462,8 @@ protected async Task HandleDisconnectRequest(
}
else
{
this.UnregisterEventHandlers();

await requestContext.SendResult(null);
await this.Stop();
}
Expand Down Expand Up @@ -839,6 +849,31 @@ await this.SendEvent(
});
}

private void RegisterEventHandlers()
{
this.editorSession.PowerShellContext.RunspaceChanged += this.powerShellContext_RunspaceChanged;
this.editorSession.DebugService.DebuggerStopped += this.DebugService_DebuggerStopped;
this.editorSession.PowerShellContext.DebuggerResumed += this.powerShellContext_DebuggerResumed;

if (!this.enableConsoleRepl)
{
this.editorSession.ConsoleService.OutputWritten += this.powerShellContext_OutputWritten;
this.outputDebouncer = new OutputDebouncer(this);
}
}

private void UnregisterEventHandlers()
{
this.editorSession.PowerShellContext.RunspaceChanged -= this.powerShellContext_RunspaceChanged;
this.editorSession.DebugService.DebuggerStopped -= this.DebugService_DebuggerStopped;
this.editorSession.PowerShellContext.DebuggerResumed -= this.powerShellContext_DebuggerResumed;

if (!this.enableConsoleRepl)
{
this.editorSession.ConsoleService.OutputWritten -= this.powerShellContext_OutputWritten;
}
}

#endregion

#region Event Handlers
Expand Down