Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
debugger.cs5955 linesDownload Raw Back to debugger
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections;5using System.Collections.Concurrent;6using System.Collections.Generic;7using System.Collections.ObjectModel;8using System.Diagnostics;9using System.Diagnostics.CodeAnalysis;10using System.Globalization;11using System.IO;12using System.Linq;13using System.Management.Automation.Host;14using System.Management.Automation.Internal;15using System.Management.Automation.Internal.Host;16using System.Management.Automation.Language;17using System.Management.Automation.Runspaces;18using System.Runtime.CompilerServices;19using System.Text.RegularExpressions;20using System.Threading;21 22using Microsoft.PowerShell.Commands.Internal.Format;23 24namespace System.Management.Automation25{26    #region Event Args27 28    /// <summary>29    /// Possible actions for the debugger after hitting a breakpoint/step.30    /// </summary>31    public enum DebuggerResumeAction32    {33        /// <summary>34        /// Continue running until the next breakpoint, or the end of the script.35        /// </summary>36        Continue = 0,37        /// <summary>38        /// Step to next statement, going into functions, scripts, etc.39        /// </summary>40        StepInto = 1,41        /// <summary>42        /// Step to next statement, going over functions, scripts, etc.43        /// </summary>44        StepOut = 2,45        /// <summary>46        /// Step to next statement after the current function, script, etc.47        /// </summary>48        StepOver = 3,49        /// <summary>50        /// Stop executing the script.51        /// </summary>52        Stop = 4,53    }54 55    /// <summary>56    /// Arguments for the DebuggerStop event.57    /// </summary>58    public class DebuggerStopEventArgs : EventArgs59    {60        /// <summary>61        /// Initializes the DebuggerStopEventArgs.62        /// </summary>63        internal DebuggerStopEventArgs(InvocationInfo invocationInfo, List<Breakpoint> breakpoints)64        {65            this.InvocationInfo = invocationInfo;66            this.Breakpoints = new ReadOnlyCollection<Breakpoint>(breakpoints);67            this.ResumeAction = DebuggerResumeAction.Continue;68        }69 70        /// <summary>71        /// Constructor.72        /// </summary>73        /// <param name="invocationInfo"></param>74        /// <param name="breakpoints"></param>75        /// <param name="resumeAction"></param>76        public DebuggerStopEventArgs(77            InvocationInfo invocationInfo,78            Collection<Breakpoint> breakpoints,79            DebuggerResumeAction resumeAction)80        {81            this.InvocationInfo = invocationInfo;82            this.Breakpoints = new ReadOnlyCollection<Breakpoint>(breakpoints);83            this.ResumeAction = resumeAction;84        }85 86        /// <summary>87        /// Invocation info of the code being executed.88        /// </summary>89        public InvocationInfo InvocationInfo { get; internal set; }90 91        /// <summary>92        /// The breakpoint(s) hit.93        /// </summary>94        /// <remarks>95        /// Note there may be more than one breakpoint on the same object (line, variable, command). A single event is96        /// raised for all these breakpoints.97        /// </remarks>98        public ReadOnlyCollection<Breakpoint> Breakpoints { get; }99 100        /// <summary>101        /// This property must be set in the event handler to indicate the debugger what it should do next.102        /// </summary>103        /// <remarks>104        /// The default action is DebuggerAction.Continue.105        /// DebuggerAction.StepToLine is only valid when debugging an script.106        /// </remarks>107        public DebuggerResumeAction ResumeAction { get; set; }108 109        /// <summary>110        /// This property is used internally for remote debug stops only.  It is used to signal the remote debugger proxy111        /// that it should *not* send a resume action to the remote debugger.  This is used by runspace debug processing to112        /// leave pending runspace debug sessions suspended until a debugger is attached.113        /// </summary>114        internal bool SuspendRemote { get; set; }115    }116 117    /// <summary>118    /// Kinds of breakpoint updates.119    /// </summary>120    public enum BreakpointUpdateType121    {122        /// <summary>123        /// A breakpoint was set.124        /// </summary>125        Set = 0,126        /// <summary>127        /// A breakpoint was removed.128        /// </summary>129        Removed = 1,130        /// <summary>131        /// A breakpoint was enabled.132        /// </summary>133        Enabled = 2,134        /// <summary>135        /// A breakpoint was disabled.136        /// </summary>137        Disabled = 3138    }139 140    /// <summary>141    /// Arguments for the BreakpointUpdated event.142    /// </summary>143    public class BreakpointUpdatedEventArgs : EventArgs144    {145        /// <summary>146        /// Initializes the BreakpointUpdatedEventArgs.147        /// </summary>148        internal BreakpointUpdatedEventArgs(Breakpoint breakpoint, BreakpointUpdateType updateType, int breakpointCount)149        {150            this.Breakpoint = breakpoint;151            this.UpdateType = updateType;152            this.BreakpointCount = breakpointCount;153        }154 155        /// <summary>156        /// Gets the breakpoint that was updated.157        /// </summary>158        public Breakpoint Breakpoint { get; }159 160        /// <summary>161        /// Gets the type of update.162        /// </summary>163        public BreakpointUpdateType UpdateType { get; }164 165        /// <summary>166        /// Gets the current breakpoint count.167        /// </summary>168        public int BreakpointCount { get; }169    }170 171    #region PSJobStartEventArgs172 173    /// <summary>174    /// Arguments for the script job start callback event.175    /// </summary>176    public sealed class PSJobStartEventArgs : EventArgs177    {178        /// <summary>179        /// Job to be started.180        /// </summary>181        public Job Job { get; }182 183        /// <summary>184        /// Job debugger.185        /// </summary>186        public Debugger Debugger { get; }187 188        /// <summary>189        /// Job is run asynchronously.190        /// </summary>191        public bool IsAsync { get; }192 193        /// <summary>194        /// Constructor.195        /// </summary>196        /// <param name="job">Started job.</param>197        /// <param name="debugger">Debugger.</param>198        /// <param name="isAsync">Job started asynchronously.</param>199        public PSJobStartEventArgs(Job job, Debugger debugger, bool isAsync)200        {201            this.Job = job;202            this.Debugger = debugger;203            this.IsAsync = isAsync;204        }205    }206 207    #endregion208 209    #region Runspace Debug Processing210 211    /// <summary>212    /// StartRunspaceDebugProcessing event arguments.213    /// </summary>214    public sealed class StartRunspaceDebugProcessingEventArgs : EventArgs215    {216        /// <summary> The runspace to process </summary>217        public Runspace Runspace { get; }218 219        /// <summary>220        /// When set to true this will cause PowerShell to process this runspace debug session through its221        /// script debugger.  To use the default processing return from this event call after setting222        /// this property to true.223        /// </summary>224        public bool UseDefaultProcessing225        {226            get;227            set;228        }229 230        /// <summary>231        /// Constructor.232        /// </summary>233        public StartRunspaceDebugProcessingEventArgs(Runspace runspace)234        {235            if (runspace == null) { throw new PSArgumentNullException(nameof(runspace)); }236 237            Runspace = runspace;238        }239    }240 241    /// <summary>242    /// ProcessRunspaceDebugEnd event arguments.243    /// </summary>244    public sealed class ProcessRunspaceDebugEndEventArgs : EventArgs245    {246        /// <summary>247        /// The runspace where internal debug processing has ended.248        /// </summary>249        public Runspace Runspace { get; }250 251        /// <summary>252        /// Constructor.253        /// </summary>254        /// <param name="runspace"></param>255        public ProcessRunspaceDebugEndEventArgs(Runspace runspace)256        {257            if (runspace == null) { throw new PSArgumentNullException(nameof(runspace)); }258 259            Runspace = runspace;260        }261    }262 263    #endregion264 265    #endregion266 267    #region Enums268 269    /// <summary>270    /// Defines debugging mode.271    /// </summary>272    [Flags]273    public enum DebugModes274    {275        /// <summary>276        /// PowerShell script debugging is disabled.277        /// </summary>278        None = 0x0,279 280        /// <summary>281        /// Default setting for original PowerShell script debugging.282        /// Compatible with PowerShell Versions 2 and 3.283        /// </summary>284        Default = 0x1,285 286        /// <summary>287        /// PowerShell script debugging.288        /// </summary>289        LocalScript = 0x2,290 291        /// <summary>292        /// PowerShell remote script debugging.293        /// </summary>294        RemoteScript = 0x4295    }296 297    /// <summary>298    /// Defines unhandled breakpoint processing behavior.299    /// </summary>300    internal enum UnhandledBreakpointProcessingMode301    {302        /// <summary>303        /// Ignore unhandled breakpoint events.304        /// </summary>305        Ignore = 1,306 307        /// <summary>308        /// Wait on unhandled breakpoint events until a handler is available.309        /// </summary>310        Wait311    }312 313    #endregion314 315    #region Debugger base class316 317    /// <summary>318    /// Base class for all PowerShell debuggers.319    /// </summary>320    public abstract class Debugger321    {322        #region Events323 324        /// <summary>325        /// Event raised when the debugger hits a breakpoint or a step.326        /// </summary>327        public event EventHandler<DebuggerStopEventArgs> DebuggerStop;328 329        /// <summary>330        /// Event raised when a breakpoint is updated.331        /// </summary>332        public event EventHandler<BreakpointUpdatedEventArgs> BreakpointUpdated;333 334        /// <summary>335        /// Event raised when nested debugging is cancelled.336        /// </summary>337        internal event EventHandler<EventArgs> NestedDebuggingCancelledEvent;338 339        #region Runspace Debug Processing Events340 341        /// <summary>342        /// Event raised when a runspace debugger needs breakpoint processing.343        /// </summary>344        public event EventHandler<StartRunspaceDebugProcessingEventArgs> StartRunspaceDebugProcessing;345 346        /// <summary>347        /// Event raised when a runspace debugger is finished being processed.348        /// </summary>349        public event EventHandler<ProcessRunspaceDebugEndEventArgs> RunspaceDebugProcessingCompleted;350 351        /// <summary>352        /// Event raised to indicate that the debugging session is over and runspace debuggers queued for353        /// processing should be released.354        /// </summary>355        public event EventHandler<EventArgs> CancelRunspaceDebugProcessing;356 357        #endregion358 359        #endregion360 361        #region Properties362 363        /// <summary>364        /// True when the debugger is stopped.365        /// </summary>366        protected bool DebuggerStopped367        {368            get;369            private set;370        }371 372        /// <summary>373        /// IsPushed.374        /// </summary>375        internal virtual bool IsPushed376        {377            get { return false; }378        }379 380        /// <summary>381        /// IsRemote.382        /// </summary>383        internal virtual bool IsRemote384        {385            get { return false; }386        }387 388        /// <summary>389        /// Returns true if the debugger is preserving a DebuggerStopEvent390        /// event.  Use ReleaseSavedDebugStop() to allow event to process.391        /// </summary>392        internal virtual bool IsPendingDebugStopEvent393        {394            get { throw new PSNotImplementedException(); }395        }396 397        /// <summary>398        /// Returns true if debugger has been set to stepInto mode.399        /// </summary>400        internal virtual bool IsDebuggerSteppingEnabled401        {402            get { throw new PSNotImplementedException(); }403        }404 405        /// <summary>406        /// Returns true if there is a handler for debugger stops.407        /// </summary>408        internal bool IsDebugHandlerSubscribed409        {410            get { return (DebuggerStop != null); }411        }412 413        /// <summary>414        /// UnhandledBreakpointMode.415        /// </summary>416        internal virtual UnhandledBreakpointProcessingMode UnhandledBreakpointMode417        {418            get { throw new PSNotImplementedException(); }419 420            set { throw new PSNotImplementedException(); }421        }422 423        /// <summary>424        /// DebuggerMode.425        /// </summary>426        public DebugModes DebugMode { get; protected set; } = DebugModes.Default;427 428        /// <summary>429        /// Returns true if debugger has breakpoints set and430        /// is currently active.431        /// </summary>432        public virtual bool IsActive433        {434            get { return false; }435        }436 437        /// <summary>438        /// InstanceId.439        /// </summary>440        public virtual Guid InstanceId441        {442            get { return s_instanceId; }443        }444 445        /// <summary>446        /// True when debugger is stopped at a breakpoint.447        /// </summary>448        public virtual bool InBreakpoint449        {450            get { return DebuggerStopped; }451        }452 453        #endregion454 455        #region Protected Methods456 457        /// <summary>458        /// RaiseDebuggerStopEvent.459        /// </summary>460        /// <param name="args">DebuggerStopEventArgs.</param>461        [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]462        protected void RaiseDebuggerStopEvent(DebuggerStopEventArgs args)463        {464            try465            {466                DebuggerStopped = true;467                DebuggerStop.SafeInvoke<DebuggerStopEventArgs>(this, args);468            }469            finally470            {471                DebuggerStopped = false;472            }473        }474 475        /// <summary>476        /// IsDebuggerStopEventSubscribed.477        /// </summary>478        /// <returns>True if event subscription exists.</returns>479        protected bool IsDebuggerStopEventSubscribed()480        {481            return (DebuggerStop != null);482        }483 484        /// <summary>485        /// RaiseBreakpointUpdatedEvent.486        /// </summary>487        /// <param name="args">BreakpointUpdatedEventArgs.</param>488        [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]489        protected void RaiseBreakpointUpdatedEvent(BreakpointUpdatedEventArgs args)490        {491            BreakpointUpdated.SafeInvoke<BreakpointUpdatedEventArgs>(this, args);492        }493 494        /// <summary>495        /// IsDebuggerBreakpointUpdatedEventSubscribed.496        /// </summary>497        /// <returns>True if event subscription exists.</returns>498        protected bool IsDebuggerBreakpointUpdatedEventSubscribed()499        {500            return (BreakpointUpdated != null);501        }502 503        #region Runspace Debug Processing504 505        /// <summary/>506        protected void RaiseStartRunspaceDebugProcessingEvent(StartRunspaceDebugProcessingEventArgs args)507        {508            if (args == null) { throw new PSArgumentNullException(nameof(args)); }509 510            StartRunspaceDebugProcessing.SafeInvoke<StartRunspaceDebugProcessingEventArgs>(this, args);511        }512 513        /// <summary/>514        protected void RaiseRunspaceProcessingCompletedEvent(ProcessRunspaceDebugEndEventArgs args)515        {516            if (args == null) { throw new PSArgumentNullException(nameof(args)); }517 518            RunspaceDebugProcessingCompleted.SafeInvoke<ProcessRunspaceDebugEndEventArgs>(this, args);519        }520 521        /// <summary/>522        protected bool IsStartRunspaceDebugProcessingEventSubscribed()523        {524            return (StartRunspaceDebugProcessing != null);525        }526 527        /// <summary/>528        protected void RaiseCancelRunspaceDebugProcessingEvent()529        {530            CancelRunspaceDebugProcessing.SafeInvoke<EventArgs>(this, null);531        }532 533        #endregion534 535        #endregion536 537        #region Public Methods538 539        /// <summary>540        /// Evaluates provided command either as a debugger specific command541        /// or a PowerShell command.542        /// </summary>543        /// <param name="command">PowerShell command.</param>544        /// <param name="output">Output.</param>545        /// <returns>DebuggerCommandResults.</returns>546        public abstract DebuggerCommandResults ProcessCommand(PSCommand command, PSDataCollection<PSObject> output);547 548        /// <summary>549        /// Sets the debugger resume action.550        /// </summary>551        /// <param name="resumeAction">DebuggerResumeAction.</param>552        public abstract void SetDebuggerAction(DebuggerResumeAction resumeAction);553 554        /// <summary>555        /// Stops a running command.556        /// </summary>557        public abstract void StopProcessCommand();558 559        /// <summary>560        /// Returns current debugger stop event arguments if debugger is in561        /// debug stop state.  Otherwise returns null.562        /// </summary>563        /// <returns>DebuggerStopEventArgs.</returns>564        public abstract DebuggerStopEventArgs GetDebuggerStopArgs();565 566        /// <summary>567        /// Sets the parent debugger, breakpoints and other debugging context information.568        /// </summary>569        /// <param name="parent">Parent debugger.</param>570        /// <param name="breakPoints">List of breakpoints.</param>571        /// <param name="startAction">Debugger mode.</param>572        /// <param name="host">Host.</param>573        /// <param name="path">Current path.</param>574        public virtual void SetParent(575            Debugger parent,576            IEnumerable<Breakpoint> breakPoints,577            DebuggerResumeAction? startAction,578            PSHost host,579            PathInfo path)580        {581            throw new PSNotImplementedException();582        }583 584        /// <summary>585        /// Sets the debugger mode.586        /// </summary>587        public virtual void SetDebugMode(DebugModes mode)588        {589            this.DebugMode = mode;590        }591 592        /// <summary>593        /// Returns IEnumerable of CallStackFrame objects.594        /// </summary>595        /// <returns></returns>596        public virtual IEnumerable<CallStackFrame> GetCallStack()597        {598            return new Collection<CallStackFrame>();599        }600 601        /// <summary>602        /// Get a breakpoint by id in the current runspace, primarily for Enable/Disable/Remove-PSBreakpoint cmdlets.603        /// </summary>604        /// <param name="id">Id of the breakpoint you want.</param>605        public Breakpoint GetBreakpoint(int id) =>606            GetBreakpoint(id, runspaceId: null);607 608        /// <summary>609        /// Get a breakpoint by id, primarily for Enable/Disable/Remove-PSBreakpoint cmdlets.610        /// </summary>611        /// <param name="id">Id of the breakpoint you want.</param>612        /// <param name="runspaceId">The runspace id of the runspace you want to interact with. A null value will use the current runspace.</param>613        public virtual Breakpoint GetBreakpoint(int id, int? runspaceId) =>614            throw new PSNotImplementedException();615 616        /// <summary>617        /// Adds the provided set of breakpoints to the debugger, in the current runspace.618        /// </summary>619        /// <param name="breakpoints">Breakpoints.</param>620        public void SetBreakpoints(IEnumerable<Breakpoint> breakpoints) =>621            SetBreakpoints(breakpoints, runspaceId: null);622 623        /// <summary>624        /// Adds the provided set of breakpoints to the debugger.625        /// </summary>626        /// <param name="breakpoints">Breakpoints.</param>627        /// <param name="runspaceId">The runspace id of the runspace you want to interact with, null being the current runspace.</param>628        public virtual void SetBreakpoints(IEnumerable<Breakpoint> breakpoints, int? runspaceId) =>629            throw new PSNotImplementedException();630 631        /// <summary>632        /// Returns breakpoints in the current runspace, primarily for the Get-PSBreakpoint cmdlet.633        /// </summary>634        public List<Breakpoint> GetBreakpoints() =>635            GetBreakpoints(runspaceId: null);636 637        /// <summary>638        /// Returns breakpoints primarily for the Get-PSBreakpoint cmdlet.639        /// </summary>640        /// <param name="runspaceId">The runspace id of the runspace you want to interact with. A null value will use the current runspace.</param>641        public virtual List<Breakpoint> GetBreakpoints(int? runspaceId) =>642            throw new PSNotImplementedException();643 644        /// <summary>645        /// Sets a command breakpoint in the current runspace in the debugger.646        /// </summary>647        /// <param name="command">The name of the command that will trigger the breakpoint. This value may not be null.</param>648        /// <param name="action">The action to take when the breakpoint is hit. If null, PowerShell will break into the debugger when the breakpoint is hit.</param>649        /// <param name="path">The path to the script file where the breakpoint may be hit. If null, the breakpoint may be hit anywhere the command is invoked.</param>650        /// <returns>The command breakpoint that was set.</returns>651        public CommandBreakpoint SetCommandBreakpoint(string command, ScriptBlock action, string path) =>652            SetCommandBreakpoint(command, action, path, runspaceId: null);653 654        /// <summary>655        /// Sets a command breakpoint in the debugger.656        /// </summary>657        /// <param name="command">The name of the command that will trigger the breakpoint. This value may not be null.</param>658        /// <param name="action">The action to take when the breakpoint is hit. If null, PowerShell will break into the debugger when the breakpoint is hit.</param>659        /// <param name="path">The path to the script file where the breakpoint may be hit. If null, the breakpoint may be hit anywhere the command is invoked.</param>660        /// <param name="runspaceId">The runspace id of the runspace you want to interact with. A value of null will use the current runspace.</param>661        /// <returns>The command breakpoint that was set.</returns>662        public virtual CommandBreakpoint SetCommandBreakpoint(string command, ScriptBlock action, string path, int? runspaceId) =>663            throw new PSNotImplementedException();664 665        /// <summary>666        /// Sets a line breakpoint in the current runspace in the debugger.667        /// </summary>668        /// <param name="path">The path to the script file where the breakpoint may be hit. This value may not be null.</param>669        /// <param name="line">The line in the script file where the breakpoint may be hit. This value must be greater than or equal to 1.</param>670        /// <param name="column">The column in the script file where the breakpoint may be hit. If 0, the breakpoint will trigger on any statement on the line.</param>671        /// <param name="action">The action to take when the breakpoint is hit. If null, PowerShell will break into the debugger when the breakpoint is hit.</param>672        /// <returns>The line breakpoint that was set.</returns>673        public LineBreakpoint SetLineBreakpoint(string path, int line, int column, ScriptBlock action) =>674            SetLineBreakpoint(path, line, column, action, runspaceId: null);675 676        /// <summary>677        /// Sets a line breakpoint in the debugger.678        /// </summary>679        /// <param name="path">The path to the script file where the breakpoint may be hit. This value may not be null.</param>680        /// <param name="line">The line in the script file where the breakpoint may be hit. This value must be greater than or equal to 1.</param>681        /// <param name="column">The column in the script file where the breakpoint may be hit. If 0, the breakpoint will trigger on any statement on the line.</param>682        /// <param name="action">The action to take when the breakpoint is hit. If null, PowerShell will break into the debugger when the breakpoint is hit.</param>683        /// <param name="runspaceId">The runspace id of the runspace you want to interact with. A null value will use the current runspace.</param>684        /// <returns>The line breakpoint that was set.</returns>685        public virtual LineBreakpoint SetLineBreakpoint(string path, int line, int column, ScriptBlock action, int? runspaceId) =>686            throw new PSNotImplementedException();687 688        /// <summary>689        /// Sets a variable breakpoint in the current runspace in the debugger.690        /// </summary>691        /// <param name="variableName">The name of the variable that will trigger the breakpoint. This value may not be null.</param>692        /// <param name="accessMode">The variable access mode that will trigger the breakpoint.</param>693        /// <param name="action">The action to take when the breakpoint is hit. If null, PowerShell will break into the debugger when the breakpoint is hit.</param>694        /// <param name="path">The path to the script file where the breakpoint may be hit. If null, the breakpoint may be hit anywhere the variable is accessed using the specified access mode.</param>695        /// <returns>The variable breakpoint that was set.</returns>696        public VariableBreakpoint SetVariableBreakpoint(string variableName, VariableAccessMode accessMode, ScriptBlock action, string path) =>697            SetVariableBreakpoint(variableName, accessMode, action, path, runspaceId: null);698 699        /// <summary>700        /// Sets a variable breakpoint in the debugger.701        /// </summary>702        /// <param name="variableName">The name of the variable that will trigger the breakpoint. This value may not be null.</param>703        /// <param name="accessMode">The variable access mode that will trigger the breakpoint.</param>704        /// <param name="action">The action to take when the breakpoint is hit. If null, PowerShell will break into the debugger when the breakpoint is hit.</param>705        /// <param name="path">The path to the script file where the breakpoint may be hit. If null, the breakpoint may be hit anywhere the variable is accessed using the specified access mode.</param>706        /// <param name="runspaceId">The runspace id of the runspace you want to interact with. A null value will use the current runspace.</param>707        /// <returns>The variable breakpoint that was set.</returns>708        public virtual VariableBreakpoint SetVariableBreakpoint(string variableName, VariableAccessMode accessMode, ScriptBlock action, string path, int? runspaceId) =>709            throw new PSNotImplementedException();710 711        /// <summary>712        /// Removes a breakpoint from the debugger in the current runspace.713        /// </summary>714        /// <param name="breakpoint">The breakpoint to remove from the debugger. This value may not be null.</param>715        /// <returns>True if the breakpoint was removed from the debugger; false otherwise.</returns>716        public bool RemoveBreakpoint(Breakpoint breakpoint) =>717            RemoveBreakpoint(breakpoint, runspaceId: null);718 719        /// <summary>720        /// Removes a breakpoint from the debugger.721        /// </summary>722        /// <param name="breakpoint">The breakpoint to remove from the debugger. This value may not be null.</param>723        /// <param name="runspaceId">The runspace id of the runspace you want to interact with. A null value will use the current runspace.</param>724        /// <returns>True if the breakpoint was removed from the debugger; false otherwise.</returns>725        public virtual bool RemoveBreakpoint(Breakpoint breakpoint, int? runspaceId) =>726            throw new PSNotImplementedException();727 728        /// <summary>729        /// Enables a breakpoint in the debugger in the current runspace.730        /// </summary>731        /// <param name="breakpoint">The breakpoint to enable in the debugger. This value may not be null.</param>732        /// <returns>The updated breakpoint if it was found; null if the breakpoint was not found in the debugger.</returns>733        public Breakpoint EnableBreakpoint(Breakpoint breakpoint) =>734            EnableBreakpoint(breakpoint, runspaceId: null);735 736        /// <summary>737        /// Enables a breakpoint in the debugger.738        /// </summary>739        /// <param name="breakpoint">The breakpoint to enable in the debugger. This value may not be null.</param>740        /// <param name="runspaceId">The runspace id of the runspace you want to interact with. A null value will use the current runspace.</param>741        /// <returns>The updated breakpoint if it was found; null if the breakpoint was not found in the debugger.</returns>742        public virtual Breakpoint EnableBreakpoint(Breakpoint breakpoint, int? runspaceId) =>743            throw new PSNotImplementedException();744 745        /// <summary>746        /// Disables a breakpoint in the debugger in the current runspace.747        /// </summary>748        /// <param name="breakpoint">The breakpoint to enable in the debugger. This value may not be null.</param>749        /// <returns>The updated breakpoint if it was found; null if the breakpoint was not found in the debugger.</returns>750        public Breakpoint DisableBreakpoint(Breakpoint breakpoint) =>751            DisableBreakpoint(breakpoint, runspaceId: null);752 753        /// <summary>754        /// Disables a breakpoint in the debugger.755        /// </summary>756        /// <param name="breakpoint">The breakpoint to enable in the debugger. This value may not be null.</param>757        /// <param name="runspaceId">The runspace id of the runspace you want to interact with. A null value will use the current runspace.</param>758        /// <returns>The updated breakpoint if it was found; null if the breakpoint was not found in the debugger.</returns>759        public virtual Breakpoint DisableBreakpoint(Breakpoint breakpoint, int? runspaceId) =>760            throw new PSNotImplementedException();761 762        /// <summary>763        /// Resets the command processor source information so that it is764        /// updated with latest information on the next debug stop.765        /// </summary>766        public virtual void ResetCommandProcessorSource()767        {768            throw new PSNotImplementedException();769        }770 771        /// <summary>772        /// Sets debugger stepping mode.773        /// </summary>774        /// <param name="enabled">True if stepping is to be enabled.</param>775        public virtual void SetDebuggerStepMode(bool enabled)776        {777            throw new PSNotImplementedException();778        }779 780        #endregion781 782        #region Internal Methods783 784        /// <summary>785        /// Breaks into the debugger.786        /// </summary>787        /// <param name="triggerObject">The object that triggered the breakpoint, if there is one.</param>788        internal virtual void Break(object triggerObject = null)789        {790            throw new PSNotImplementedException();791        }792 793        /// <summary>794        /// Returns script position message of current execution stack item.795        /// This is used for WDAC audit mode logging for script information enhancement.796        /// </summary>797        /// <returns>Script position message string.</returns>798        internal virtual string GetCurrentScriptPosition()799        {800            throw new PSNotImplementedException();801        }802 803        /// <summary>804        /// Passes the debugger command to the internal script debugger command processor.  This805        /// is used internally to handle debugger commands such as list, help, etc.806        /// </summary>807        /// <param name="command">Command string.</param>808        /// <param name="output">Output collection.</param>809        /// <returns>DebuggerCommand containing information on whether and how the command was processed.</returns>810        internal virtual DebuggerCommand InternalProcessCommand(string command, IList<PSObject> output)811        {812            throw new PSNotImplementedException();813        }814 815        /// <summary>816        /// Creates a source list based on root script debugger source information if available, with817        /// the current source line highlighted.  This is used internally for nested runspace debugging818        /// where the runspace command is run in context of a parent script.819        /// </summary>820        /// <param name="lineNum">Current source line.</param>821        /// <param name="output">Output collection.</param>822        /// <returns>True if source listed successfully.</returns>823        internal virtual bool InternalProcessListCommand(int lineNum, IList<PSObject> output)824        {825            throw new PSNotImplementedException();826        }827 828        /// <summary>829        /// Sets up debugger to debug provided job or its child jobs.830        /// </summary>831        /// <param name="job">832        /// Job object that is either a debuggable job or a container of833        /// debuggable child jobs.834        /// </param>835        /// <param name="breakAll">836        /// If true, the debugger automatically invokes a break all when it837        /// attaches to the job.838        /// </param>839        internal virtual void DebugJob(Job job, bool breakAll) =>840            throw new PSNotImplementedException();841 842        /// <summary>843        /// Removes job from debugger job list and pops the its844        /// debugger from the active debugger stack.845        /// </summary>846        /// <param name="job">Job.</param>847        internal virtual void StopDebugJob(Job job)848        {849            throw new PSNotImplementedException();850        }851 852        /// <summary>853        /// GetActiveDebuggerCallStack.854        /// </summary>855        /// <returns>Array of stack frame objects of active debugger.</returns>856        internal virtual CallStackFrame[] GetActiveDebuggerCallStack()857        {858            throw new PSNotImplementedException();859        }860 861        /// <summary>862        /// Method to add the provided runspace information to the debugger863        /// for monitoring of debugger events.  This is used to implement nested864        /// debugging of runspaces.865        /// </summary>866        /// <param name="args">PSEntityCreatedRunspaceEventArgs.</param>867        internal virtual void StartMonitoringRunspace(PSMonitorRunspaceInfo args)868        {869            throw new PSNotImplementedException();870        }871 872        /// <summary>873        /// Method to end the monitoring of a runspace for debugging events.874        /// </summary>875        /// <param name="args">PSEntityCreatedRunspaceEventArgs.</param>876        internal virtual void EndMonitoringRunspace(PSMonitorRunspaceInfo args)877        {878            throw new PSNotImplementedException();879        }880 881        /// <summary>882        /// If a debug stop event is currently pending then this method will release883        /// the event to continue processing.884        /// </summary>885        internal virtual void ReleaseSavedDebugStop()886        {887            throw new PSNotImplementedException();888        }889 890        /// <summary>891        /// Sets up debugger to debug provided Runspace in a nested debug session.892        /// </summary>893        /// <param name="runspace">894        /// The runspace to debug.895        /// </param>896        /// <param name="breakAll">897        /// If true, the debugger automatically invokes a break all when it898        /// attaches to the runspace.899        /// </param>900        internal virtual void DebugRunspace(Runspace runspace, bool breakAll) =>901            throw new PSNotImplementedException();902 903        /// <summary>904        /// Removes the provided Runspace from the nested "active" debugger state.905        /// </summary>906        /// <param name="runspace">Runspace.</param>907        internal virtual void StopDebugRunspace(Runspace runspace)908        {909            throw new PSNotImplementedException();910        }911 912        /// <summary>913        /// Raises the NestedDebuggingCancelledEvent event.914        /// </summary>915        internal void RaiseNestedDebuggingCancelEvent()916        {917            // Raise event on worker thread.918            Threading.ThreadPool.QueueUserWorkItem(919                (state) =>920                {921                    try922                    {923                        NestedDebuggingCancelledEvent.SafeInvoke<EventArgs>(this, null);924                    }925                    catch (Exception)926                    {927                    }928                });929        }930 931        #endregion932 933        #region Runspace Debug Processing Methods934 935        /// <summary>936        /// Adds the provided Runspace object to the runspace debugger processing queue.937        /// The queue will then raise the StartRunspaceDebugProcessing events for each runspace to allow938        /// a host script debugger implementation to provide an active debugging session.939        /// </summary>940        /// <param name="runspace">Runspace to debug.</param>941        internal virtual void QueueRunspaceForDebug(Runspace runspace)942        {943            throw new PSNotImplementedException();944        }945 946        /// <summary>947        /// Causes the CancelRunspaceDebugProcessing event to be raised which notifies subscribers that current debugging948        /// sessions should be cancelled.949        /// </summary>950        public virtual void CancelDebuggerProcessing()951        {952            throw new PSNotImplementedException();953        }954 955        #endregion956 957        #region Members958 959        internal const string CannotProcessCommandNotStopped = "Debugger:CannotProcessCommandNotStopped";960 961        internal const string CannotEnableDebuggerSteppingInvalidMode = "Debugger:CannotEnableDebuggerSteppingInvalidMode";962 963        private static readonly Guid s_instanceId = new Guid();964 965        #endregion966    }967 968    #endregion969 970    #region ScriptDebugger class971 972    /// <summary>973    /// Holds the debugging information for a Monad Shell session.974    /// </summary>975    internal sealed class ScriptDebugger : Debugger, IDisposable976    {977        #region constructors978 979        internal ScriptDebugger(ExecutionContext context)980        {981            _context = context;982            _inBreakpoint = false;983            _idToBreakpoint = new ConcurrentDictionary<int, Breakpoint>();984            // The string key is function context file path. The int key is sequencePoint index.985            _pendingBreakpoints = new ConcurrentDictionary<string, ConcurrentDictionary<int, LineBreakpoint>>(StringComparer.OrdinalIgnoreCase);986            _boundBreakpoints = new ConcurrentDictionary<string, Tuple<WeakReference, ConcurrentDictionary<int, LineBreakpoint>>>(StringComparer.OrdinalIgnoreCase);987            _commandBreakpoints = new ConcurrentDictionary<int, CommandBreakpoint>();988            _variableBreakpoints = new ConcurrentDictionary<string, ConcurrentDictionary<int, VariableBreakpoint>>(StringComparer.OrdinalIgnoreCase);989            _steppingMode = SteppingMode.None;990            _callStack = new CallStackList { _callStackList = new List<CallStackInfo>() };991 992            _runningJobs = new Dictionary<Guid, PSJobStartEventArgs>();993            _activeDebuggers = new ConcurrentStack<Debugger>();994            _debuggerStopEventArgs = new ConcurrentStack<DebuggerStopEventArgs>();995            _syncObject = new object();996            _syncActiveDebuggerStopObject = new object();997 998            _runningRunspaces = new Dictionary<Guid, PSMonitorRunspaceInfo>();999        }1000 1001        /// <summary>1002        /// Static constructor.1003        /// </summary>1004        static ScriptDebugger()1005        {1006            s_processDebugPromptMatch = StringUtil.Format(@"""[{0}:", DebuggerStrings.NestedRunspaceDebuggerPromptProcessName);1007        }1008 1009        #endregion constructors1010 1011        #region properties1012 1013        /// <summary>1014        /// True when debugger is stopped at a breakpoint.1015        /// </summary>1016        public override bool InBreakpoint1017        {1018            get1019            {1020                if (_inBreakpoint)1021                {1022                    return _inBreakpoint;1023                }1024 1025                Debugger activeDebugger;1026                if (_activeDebuggers.TryPeek(out activeDebugger))1027                {1028                    return activeDebugger.InBreakpoint;1029                }1030 1031                return false;1032            }1033        }1034 1035        internal override bool IsPushed1036        {1037            get { return (!_activeDebuggers.IsEmpty); }1038        }1039 1040        /// <summary>1041        /// Returns true if the debugger is preserving a DebuggerStopEvent1042        /// event.  Use ReleaseSavedDebugStop() to allow event to process.1043        /// </summary>1044        internal override bool IsPendingDebugStopEvent1045        {1046            get1047            {1048                return ((_preserveDebugStopEvent != null) && !_preserveDebugStopEvent.IsSet);1049            }1050        }1051 1052        /// <summary>1053        /// Returns true if debugger has been set to stepInto mode.1054        /// </summary>1055        internal override bool IsDebuggerSteppingEnabled1056        {1057            get1058            {1059                return ((_context._debuggingMode == (int)InternalDebugMode.Enabled) &&1060                        (_currentDebuggerAction == DebuggerResumeAction.StepInto) &&1061                        (_steppingMode != SteppingMode.None));1062            }1063        }1064 1065        private bool? _isLocalSession;1066 1067        private bool IsLocalSession1068        {1069            get1070            {1071                // Remote debug sessions always have a ServerRemoteHost.  Otherwise it is a local session.1072                _isLocalSession ??= !((_context.InternalHost.ExternalHost != null) &&1073                    (_context.InternalHost.ExternalHost is System.Management.Automation.Remoting.ServerRemoteHost));1074 1075                return _isLocalSession.Value;1076            }1077        }1078 1079        /// <summary>1080        /// Gets or sets the object that triggered the current breakpoint.1081        /// </summary>1082        private object TriggerObject { get; set; }1083 1084        #endregion properties1085 1086        #region internal methods1087 1088        #region Reset Debugger1089 1090        /// <summary>1091        /// Resets debugger to initial state.1092        /// </summary>1093        internal void ResetDebugger()1094        {1095            SetDebugMode(DebugModes.None);1096            SetInternalDebugMode(InternalDebugMode.Disabled);1097 1098            _steppingMode = SteppingMode.None;1099            _inBreakpoint = false;1100            _idToBreakpoint.Clear();1101            _pendingBreakpoints.Clear();1102            _boundBreakpoints.Clear();1103            _commandBreakpoints.Clear();1104            _variableBreakpoints.Clear();1105            s_emptyBreakpointList.Clear();1106            _callStack.Clear();1107            _overOrOutFrame = null;1108            _commandProcessor = new DebuggerCommandProcessor();1109 1110            _currentInvocationInfo = null;1111            _inBreakpoint = false;1112            _psDebuggerCommand = null;1113            _savedIgnoreScriptDebug = false;1114            _isLocalSession = null;1115 1116            _nestedDebuggerStop = false;1117            _debuggerStopEventArgs.Clear();1118            _lastActiveDebuggerAction = DebuggerResumeAction.Continue;1119            _currentDebuggerAction = DebuggerResumeAction.Continue;1120            _previousDebuggerAction = DebuggerResumeAction.Continue;1121            _nestedRunningFrame = null;1122            _nestedDebuggerStop = false;1123            _processingOutputCount = 0;1124            _preserveUnhandledDebugStopEvent = false;1125 1126            ClearRunningJobList();1127            ClearRunningRunspaceList();1128            _activeDebuggers.Clear();1129 1130            ReleaseSavedDebugStop();1131 1132            SetDebugMode(DebugModes.Default);1133        }1134 1135        #endregion1136 1137        #region Call stack management1138 1139        // Called from generated code on entering the script function, called once for each dynamicparam, begin, or end1140        // block, and once for each object written to the pipeline.  Also called when entering a trap.1141        internal void EnterScriptFunction(FunctionContext functionContext)1142        {1143            Diagnostics.Assert(functionContext._executionContext == _context, "Wrong debugger is being used.");1144 1145            var invocationInfo = (InvocationInfo)functionContext._localsTuple.GetAutomaticVariable(AutomaticVariable.MyInvocation);1146            var newCallStackInfo = new CallStackInfo1147            {1148                InvocationInfo = invocationInfo,1149                File = functionContext._file,1150                DebuggerStepThrough = functionContext._debuggerStepThrough,1151                FunctionContext = functionContext,1152                IsFrameHidden = functionContext._debuggerHidden,1153            };1154            _callStack.Add(newCallStackInfo);1155 1156            if (_context._debuggingMode > 0)1157            {1158                var scriptCommandInfo = invocationInfo.MyCommand as ExternalScriptInfo;1159                if (scriptCommandInfo != null)1160                {1161                    RegisterScriptFile(scriptCommandInfo);1162                }1163 1164                bool checkLineBp = CheckCommand(invocationInfo);1165                SetupBreakpoints(functionContext);1166 1167                if (functionContext._debuggerStepThrough && _overOrOutFrame == null && _steppingMode == SteppingMode.StepIn)1168                {1169                    // Treat like step out, but only if we're not already stepping out1170                    ResumeExecution(DebuggerResumeAction.StepOut);1171                }1172 1173                if (checkLineBp)1174                {1175                    OnSequencePointHit(functionContext);1176                }1177 1178                if (_context.PSDebugTraceLevel > 1 && !functionContext._debuggerStepThrough && !functionContext._debuggerHidden)1179                {1180                    TraceScriptFunctionEntry(functionContext);1181                }1182            }1183        }1184 1185        private void SetupBreakpoints(FunctionContext functionContext)1186        {1187            var scriptDebugData = _mapScriptToBreakpoints.GetValue(functionContext._sequencePoints,1188                                                                   _ => Tuple.Create(new Dictionary<int, List<LineBreakpoint>>(),1189                                                                                     new BitArray(functionContext._sequencePoints.Length)));1190            functionContext._boundBreakpoints = scriptDebugData.Item1;1191            functionContext._breakPoints = scriptDebugData.Item2;1192            SetPendingBreakpoints(functionContext);1193        }1194 1195        // Called after exiting the script function, called once for each dynamicparam, begin, or end1196        // block, and once for each object written to the pipeline.  Also called when leaving a trap.1197        internal void ExitScriptFunction()1198        {1199            // If it's stepping over to exit the current frame, we need to clear the _overOrOutFrame,1200            // so that we will stop at the next statement in the outer frame.

Showing the first 1,200 of 5955 lines. Download the file for the rest.