/// <summary> /// Constructor. /// </summary> /// <param name="invocationInfo"></param> /// <param name="breakpoints"></param> /// <param name="resumeAction"></param> public DebuggerStopEventArgs( InvocationInfo invocationInfo, Collection<Breakpoint> breakpoints, DebuggerResumeAction resumeAction) { this.InvocationInfo = invocationInfo; this.Breakpoints = new ReadOnlyCollection<Breakpoint>(breakpoints); this.ResumeAction = resumeAction; }
/// <summary> /// Sets the parent debugger, breakpoints, function source and other /// debugging context information. /// </summary> /// <param name="parent">Parent debugger</param> /// <param name="breakPoints">List of breakpoints</param> /// <param name="startAction">Debugger mode</param> /// <param name="host">PowerShell host</param> /// <param name="path">Current path</param> /// <param name="functionSourceMap">Function to source map</param> public virtual void SetParent( Debugger parent, IEnumerable<Breakpoint> breakPoints, DebuggerResumeAction? startAction, PSHost host, PathInfo path, Dictionary<string, DebugSource> functionSourceMap) { throw new PSNotImplementedException(); }
/// <summary> /// Sets the parent debugger and breakpoints. /// </summary> /// <param name="parent">Parent debugger</param> /// <param name="breakPoints">List of breakpoints</param> /// <param name="startAction">Debugger mode</param> /// <param name="host">host</param> /// <param name="path">Current path</param> public virtual void SetParent( Debugger parent, IEnumerable<Breakpoint> breakPoints, DebuggerResumeAction? startAction, PSHost host, PathInfo path) { throw new PSNotImplementedException(); }
/// <summary> /// Sets the debugger resume action. /// </summary> /// <param name="resumeAction">DebuggerResumeAction</param> public abstract void SetDebuggerAction(DebuggerResumeAction resumeAction);
private void ResumeDebugger(DebuggerResumeAction action) { _debuggerExecutionTask?.SetResult(action); }
/// <summary> /// Exits debugger mode with the provided resume action. /// </summary> /// <param name="resumeAction">DebuggerResumeAction</param> public override void SetDebuggerAction(DebuggerResumeAction resumeAction) { if (!_inDebugMode) { throw new PSInvalidOperationException( StringUtil.Format(DebuggerStrings.CannotSetRemoteDebuggerAction)); } ExitDebugMode(resumeAction); }
private void ResumeExecution(DebuggerResumeAction action) { switch (action) { case DebuggerResumeAction.Continue: break; case DebuggerResumeAction.StepInto: this._steppingMode = SteppingMode.StepIn; this._overOrOutFrame = null; return; case DebuggerResumeAction.StepOut: if (this._callStack.Count <= 1) { break; } this._steppingMode = SteppingMode.StepIn; this._overOrOutFrame = this._callStack[this._callStack.Count - 2]; return; case DebuggerResumeAction.StepOver: this._steppingMode = SteppingMode.StepIn; this._overOrOutFrame = this._callStack.Last<CallStackInfo>(); return; case DebuggerResumeAction.Stop: this._steppingMode = SteppingMode.None; this._overOrOutFrame = null; throw new TerminateException(); default: return; } this._steppingMode = SteppingMode.None; this._overOrOutFrame = null; }
private void ExitDebugMode(DebuggerResumeAction resumeAction) { this.debuggerStopEventArgs.ResumeAction = resumeAction; try { this.Runspace.ExecutionContext.EngineHostInterface.ExitNestedPrompt(); } catch (ExitNestedPromptException exitNestedPromptException) { } }
private DebuggerCommandResults ProcessCommandForActiveDebugger(PSCommand command, PSDataCollection<PSObject> output) { // Check for debugger "detach" command which is only applicable to nested debugging. bool detachCommand = ((command.Commands.Count > 0) && ((command.Commands[0].CommandText.Equals("Detach", StringComparison.OrdinalIgnoreCase)) || (command.Commands[0].CommandText.Equals("d", StringComparison.OrdinalIgnoreCase)))); Debugger activeDebugger; if (_activeDebuggers.TryPeek(out activeDebugger)) { if (detachCommand) { // Exit command means to cancel the nested debugger session. This needs to be done by the // owner of the session so we raise an event and release the debugger stop. UnhandledBreakpointMode = UnhandledBreakpointProcessingMode.Ignore; RaiseNestedDebuggingCancelEvent(); return new DebuggerCommandResults(DebuggerResumeAction.Continue, true); } else if ((command.Commands.Count > 0) && (command.Commands[0].CommandText.IndexOf(".EnterNestedPrompt()", StringComparison.OrdinalIgnoreCase) > 0)) { // Prevent a host EnterNestedPrompt() call from occuring in an active debugger. // Host nested prompt makes no sense in this case and can cause hangs depending on host implementation. throw new PSNotSupportedException(); } // Get current debugger stop breakpoint info. DebuggerStopEventArgs stopArgs; if (_debuggerStopEventArgs.TryPeek(out stopArgs)) { string commandText = command.Commands[0].CommandText; // Check to see if this is a resume command that we handle here. DebuggerCommand dbgCommand = _commandProcessor.ProcessBasicCommand(commandText); if (dbgCommand != null && dbgCommand.ResumeAction != null) { _lastActiveDebuggerAction = dbgCommand.ResumeAction.Value; return new DebuggerCommandResults(dbgCommand.ResumeAction, true); } // If active debugger is Workflow debugger then process command here (for "list" and "help"). if (activeDebugger.GetType().FullName.Equals("Microsoft.PowerShell.Workflow.PSWorkflowDebugger", StringComparison.OrdinalIgnoreCase)) { DebuggerCommand results = _commandProcessor.ProcessCommand(null, commandText, stopArgs.InvocationInfo, output); if ((results != null) && results.ExecutedByDebugger) { return new DebuggerCommandResults(results.ResumeAction, true); } } } return activeDebugger.ProcessCommand(command, output); } if (detachCommand) { // Detach command only applies to nested debugging. So if there isn't any active debugger then emit error. throw new PSInvalidOperationException(DebuggerStrings.InvalidDetachCommand); } return null; }
private void HandleActiveJobDebuggerStop(object sender, DebuggerStopEventArgs args) { // If we are debugging nested runspaces then ignore job debugger stops if (_runningRunspaces.Count > 0) { return; } // Forward active debugger event. if (args != null) { // Save copy of arguments. DebuggerStopEventArgs copyArgs = new DebuggerStopEventArgs( args.InvocationInfo, new Collection<Breakpoint>(args.Breakpoints), args.ResumeAction); _debuggerStopEventArgs.Push(copyArgs); CallStackInfo savedCallStackItem = null; try { // Wait for up to 5 seconds for output processing to complete. _processingOutputCompleteEvent.Wait(5000); // Fix up call stack representing this WF call. savedCallStackItem = FixUpCallStack(); // Blocking call that raises stop event. RaiseDebuggerStopEvent(args); _lastActiveDebuggerAction = args.ResumeAction; } finally { RestoreCallStack(savedCallStackItem); _debuggerStopEventArgs.TryPop(out copyArgs); } } }
private Debugger PopActiveDebugger() { Debugger poppedDebugger = null; if (_activeDebuggers.TryPop(out poppedDebugger)) { int runningJobCount; lock (_syncObject) { runningJobCount = _runningJobs.Count; } if (runningJobCount == 0) { // If we are back to the root debugger and are in step mode, ensure // that the root debugger is in step mode to continue stepping. switch (_lastActiveDebuggerAction) { case DebuggerResumeAction.StepInto: case DebuggerResumeAction.StepOver: case DebuggerResumeAction.StepOut: // Set script debugger to step mode after the WF running // script completes. _steppingMode = SteppingMode.StepIn; _overOrOutFrame = _nestedRunningFrame; _nestedRunningFrame = null; break; case DebuggerResumeAction.Stop: _nestedDebuggerStop = true; break; default: ResumeExecution(DebuggerResumeAction.Continue); break; } // Allow script debugger to continue in debugging mode. _processingOutputCount = 0; SetInternalDebugMode(InternalDebugMode.Enabled); _currentDebuggerAction = _lastActiveDebuggerAction; _lastActiveDebuggerAction = DebuggerResumeAction.Continue; } } return poppedDebugger; }
private void AddToJobRunningList(PSJobStartEventArgs jobArgs, DebuggerResumeAction startAction) { bool newJob = false; lock (_syncObject) { jobArgs.Job.StateChanged += HandleJobStateChanged; if (jobArgs.Job.IsPersistentState(jobArgs.Job.JobStateInfo.State)) { jobArgs.Job.StateChanged -= HandleJobStateChanged; return; } if (!_runningJobs.ContainsKey(jobArgs.Job.InstanceId)) { // For now ignore WF jobs started asynchronously from script. if (jobArgs.IsAsync) { return; } // Turn on output processing monitoring on workflow job so that // the debug stop events can coordinate with end of output processing. jobArgs.Job.OutputProcessingStateChanged += HandleOutputProcessingStateChanged; jobArgs.Job.MonitorOutputProcessing = true; _runningJobs.Add(jobArgs.Job.InstanceId, jobArgs); jobArgs.Debugger.DebuggerStop += HandleMonitorRunningJobsDebuggerStop; jobArgs.Debugger.BreakpointUpdated += HandleBreakpointUpdated; newJob = true; } } if (newJob) { jobArgs.Debugger.SetParent( this, _idToBreakpoint.Values.ToArray<Breakpoint>(), startAction, _context.EngineHostInterface.ExternalHost, _context.SessionState.Path.CurrentLocation, GetFunctionToSourceMap()); } else { // If job already in collection then make sure start action is set. // Note that this covers the case where Debug-Job was performed on // an async job, which then becomes sync, the user continues execution // and then wants to break (step mode) into the debugger *again*. jobArgs.Debugger.SetDebuggerStepMode(true); } }
/// <summary> /// Set ScriptDebugger action. /// </summary> /// <param name="resumeAction">DebuggerResumeAction</param> public override void SetDebuggerAction(DebuggerResumeAction resumeAction) { throw new PSNotSupportedException( StringUtil.Format(DebuggerStrings.CannotSetDebuggerAction)); }
/// <summary> /// Resumes execution after a breakpoint/step event has been handled /// </summary> private void ResumeExecution(DebuggerResumeAction action) { _previousDebuggerAction = _currentDebuggerAction; _currentDebuggerAction = action; switch (action) { case DebuggerResumeAction.StepInto: _steppingMode = SteppingMode.StepIn; _overOrOutFrame = null; break; case DebuggerResumeAction.StepOut: if (_callStack.Count > 1) { // When we pop to the parent frame, we'll clear _overOrOutFrame (so OnSequencePointHit // will stop) and continue with a step. _steppingMode = SteppingMode.StepIn; _overOrOutFrame = _callStack[_callStack.Count - 2]; } else { // Stepping out of the top frame is just like continue (allow hitting // breakpoints in the current frame, but otherwise just go.) goto case DebuggerResumeAction.Continue; } break; case DebuggerResumeAction.StepOver: _steppingMode = SteppingMode.StepIn; _overOrOutFrame = _callStack.Last(); break; case DebuggerResumeAction.Continue: // nothing to do, just continue _steppingMode = SteppingMode.None; _overOrOutFrame = null; break; case DebuggerResumeAction.Stop: _steppingMode = SteppingMode.None; _overOrOutFrame = null; throw new TerminateException(); default: Debug.Assert(false, "Received an unknown action: " + action); break; } }
private void OnDebuggerResumed(object sender, DebuggerResumeAction e) { this.CurrentDebuggerStoppedEventArgs = null; }
private void HandleActiveRunspaceDebuggerStop(object sender, DebuggerStopEventArgs args) { // Save copy of arguments. DebuggerStopEventArgs copyArgs = new DebuggerStopEventArgs( args.InvocationInfo, new Collection<Breakpoint>(args.Breakpoints), args.ResumeAction); _debuggerStopEventArgs.Push(copyArgs); // Forward active debugger event. try { // Blocking call that raises the stop event. RaiseDebuggerStopEvent(args); _lastActiveDebuggerAction = args.ResumeAction; } catch (Exception ex) { // Catch all external user generated exceptions thrown on event thread. CommandProcessorBase.CheckForSevereException(ex); } finally { _debuggerStopEventArgs.TryPop(out copyArgs); PopActiveDebugger(); } }
/// <summary> /// SetDebuggerAction /// </summary> /// <param name="resumeAction">DebuggerResumeAction</param> public override void SetDebuggerAction(DebuggerResumeAction resumeAction) { CheckForValidateState(); SetRemoteDebug(false, RunspaceAvailability.Busy); using (PowerShell ps = GetNestedPowerShell()) { ps.AddCommand(DebuggerUtils.SetDebuggerActionFunctionName).AddParameter("ResumeAction", resumeAction); ps.Invoke(); // If an error exception is returned then throw it here. if (ps.ErrorBuffer.Count > 0) { Exception e = ps.ErrorBuffer[0].Exception; if (e != null) { throw e; } } } }
/// <summary> /// SetDebuggerAction /// </summary> /// <param name="resumeAction">Debugger resume action</param> public override void SetDebuggerAction(DebuggerResumeAction resumeAction) { _wrappedDebugger.SetDebuggerAction(resumeAction); }
public DebuggerCommand(string command, DebuggerResumeAction? action, bool repeatOnEnter, bool executedByDebugger) { this.resumeAction = action; this.command = command; this.repeatOnEnter = repeatOnEnter; this.executedByDebugger = executedByDebugger; }
/// <summary> /// Constructor /// </summary> /// <param name="resumeAction">Resume action</param> /// <param name="evaluatedByDebugger">True if evaluated by debugger</param> public DebuggerCommandResults( DebuggerResumeAction? resumeAction, bool evaluatedByDebugger) { ResumeAction = resumeAction; EvaluatedByDebugger = evaluatedByDebugger; }
/// <summary> /// Exits the debugger's nested prompt. /// </summary> private void ExitDebugMode(DebuggerResumeAction resumeAction) { _debuggerStopEventArgs.ResumeAction = resumeAction; try { // // Note that we need to exit the nested prompt via the InternalHost interface. // // ExitNestedPrompt must always be run on the local runspace. Runspace runspace = _runspaceRef.OldRunspace ?? this.RunspaceRef.Runspace; runspace.ExecutionContext.EngineHostInterface.ExitNestedPrompt(); } catch (ExitNestedPromptException) { // ignore the exception } }
public DebuggerCommand(string command, DebuggerResumeAction? action, bool repeatOnEnter, bool executedByDebugger) { ResumeAction = action; Command = command; RepeatOnEnter = repeatOnEnter; ExecutedByDebugger = executedByDebugger; }
/// <summary> /// Exits the server side nested pipeline. /// </summary> private void ExitDebugMode(DebuggerResumeAction resumeAction) { _debuggerStopEventArgs.ResumeAction = resumeAction; try { if (_nestedDebugging) { // Release nested debugger. _nestedDebugStopCompleteEvent.Set(); } else { // Release EnterDebugMode blocking call. _driverInvoker.ExitNestedPipeline(); } _runspace.ExecutionContext.SetVariable(SpecialVariables.NestedPromptCounterVarPath, 0); } catch (Exception e) { CommandProcessor.CheckForSevereException(e); } }
/// <summary> /// Sets the debugger resume action. /// </summary> /// <param name="resumeAction">Debugger resume action.</param> public override void SetDebuggerAction(DebuggerResumeAction resumeAction) { _wrappedDebugger.SetDebuggerAction(resumeAction); }