private void SetBreakpoint(FunctionContext functionContext, int sequencePointIndex) { this.BreakpointBitArray = functionContext._breakPoints; this.ScriptBlock = functionContext._scriptBlock; this.SequencePointIndex = sequencePointIndex; base.SetEnabled(true); this.BreakpointBitArray.Set(this.SequencePointIndex, true); }
internal static void CheckActionPreference(FunctionContext funcContext, Exception exception) { ActionPreference preference; if (exception is TargetInvocationException) { exception = exception.InnerException; } CommandProcessorBase.CheckForSevereException(exception); RuntimeException exception2 = exception as RuntimeException; if (exception2 == null) { exception2 = ConvertToRuntimeException(exception, funcContext.CurrentPosition); } else { InterpreterError.UpdateExceptionErrorRecordPosition(exception2, funcContext.CurrentPosition); } RuntimeException.LockStackTrace(exception2); ExecutionContext context = funcContext._executionContext; Pipe outputPipe = funcContext._outputPipe; IScriptExtent scriptPosition = exception2.ErrorRecord.InvocationInfo.ScriptPosition; SetErrorVariables(scriptPosition, exception2, context, outputPipe); context.QuestionMarkVariableValue = false; bool flag = funcContext._traps.Any<Tuple<Type[], Action<FunctionContext>[], Type[]>>() && (funcContext._traps.Last<Tuple<Type[], Action<FunctionContext>[], Type[]>>().Item2 != null); if (!flag && !NeedToQueryForActionPreference(exception2, context)) { throw exception2; } if (flag) { preference = ProcessTraps(funcContext, exception2); } else { preference = QueryForAction(exception2, exception2.Message, context); } context.QuestionMarkVariableValue = false; switch (preference) { case ActionPreference.SilentlyContinue: case ActionPreference.Ignore: return; case ActionPreference.Stop: exception2.SuppressPromptInInterpreter = true; throw exception2; } if (!flag && exception2.WasThrownFromThrowStatement) { throw exception2; } bool flag2 = ReportErrorRecord(scriptPosition, exception2, context); context.QuestionMarkVariableValue = false; if (!flag2) { throw exception2; } }
internal Pipe[] BindForExpression(FunctionContext funcContext) { ExecutionContext context = funcContext._executionContext; Pipe redirectionPipe = this.GetRedirectionPipe(context, null); Pipe[] pipeArray = new Pipe[7]; switch (base.FromStream) { case RedirectionStream.All: pipeArray[1] = funcContext._outputPipe; pipeArray[2] = context.ShellFunctionErrorOutputPipe; pipeArray[3] = context.ExpressionWarningOutputPipe; pipeArray[4] = context.ExpressionVerboseOutputPipe; pipeArray[5] = context.ExpressionDebugOutputPipe; funcContext._outputPipe = redirectionPipe; context.ShellFunctionErrorOutputPipe = redirectionPipe; context.ExpressionWarningOutputPipe = redirectionPipe; context.ExpressionVerboseOutputPipe = redirectionPipe; context.ExpressionDebugOutputPipe = redirectionPipe; return pipeArray; case RedirectionStream.Output: pipeArray[1] = funcContext._outputPipe; funcContext._outputPipe = redirectionPipe; return pipeArray; case RedirectionStream.Error: pipeArray[(int) base.FromStream] = context.ShellFunctionErrorOutputPipe; context.ShellFunctionErrorOutputPipe = redirectionPipe; return pipeArray; case RedirectionStream.Warning: pipeArray[(int) base.FromStream] = context.ExpressionWarningOutputPipe; context.ExpressionWarningOutputPipe = redirectionPipe; return pipeArray; case RedirectionStream.Verbose: pipeArray[(int) base.FromStream] = context.ExpressionVerboseOutputPipe; context.ExpressionVerboseOutputPipe = redirectionPipe; return pipeArray; case RedirectionStream.Debug: pipeArray[(int) base.FromStream] = context.ExpressionDebugOutputPipe; context.ExpressionDebugOutputPipe = redirectionPipe; return pipeArray; case RedirectionStream.Host: return pipeArray; } return pipeArray; }
private static IScriptExtent FindSequencePoint(FunctionContext functionContext, int line, int column, out int sequencePointIndex) { IScriptExtent[] sequencePoints = functionContext._scriptBlock.SequencePoints; for (int i = 0; i < sequencePoints.Length; i++) { IScriptExtent extent = sequencePoints[i]; if (extent.ContainsLineAndColumn(line, column)) { sequencePointIndex = i; return extent; } } sequencePointIndex = -1; return null; }
public PSScriptCmdlet(ScriptBlock scriptBlock, bool useNewScope, bool fromScriptFile, System.Management.Automation.ExecutionContext context) { this._scriptBlock = scriptBlock; this._useLocalScope = useNewScope; this._fromScriptFile = fromScriptFile; this._runOptimized = this._scriptBlock.Compile((context._debuggingMode <= 0) && useNewScope); this._localsTuple = this._scriptBlock.MakeLocalsTuple(this._runOptimized); this._localsTuple.SetAutomaticVariable(AutomaticVariable.PSCmdlet, this, context); this._scriptBlock.SetPSScriptRootAndPSCommandPath(this._localsTuple, context); FunctionContext context2 = new FunctionContext { _localsTuple = this._localsTuple, _scriptBlock = this._scriptBlock, _sequencePoints = this._scriptBlock.SequencePoints, _executionContext = context }; this._functionContext = context2; this._rethrowExitException = context.ScriptCommandProcessorShouldRethrowExit; context.ScriptCommandProcessorShouldRethrowExit = false; }
internal bool TrySetBreakpoint(string scriptFile, FunctionContext functionContext) { if (scriptFile.Equals(base.Script, StringComparison.OrdinalIgnoreCase)) { int num; System.Management.Automation.ScriptBlock block = functionContext._scriptBlock; Ast ast = block.Ast; if (!ast.Extent.ContainsLineAndColumn(this.Line, this.Column)) { return false; } IScriptExtent[] sequencePoints = block.SequencePoints; if ((sequencePoints.Length == 1) && (sequencePoints[0] == block.Ast.Extent)) { return false; } bool flag = CheckBreakpointInScript.IsInNestedScriptBlock(((IParameterMetadataProvider) ast).Body, this); IScriptExtent extent = FindSequencePoint(functionContext, this.Line, this.Column, out num); if ((extent != null) && (!flag || ((extent.StartLineNumber == this.Line) && (this.Column == 0)))) { this.SetBreakpoint(functionContext, num); return true; } if (flag) { return false; } ScriptBlockAst body = ((IParameterMetadataProvider) ast).Body; if ((((body.DynamicParamBlock == null) || body.DynamicParamBlock.Extent.IsAfter(this.Line, this.Column)) && ((body.BeginBlock == null) || body.BeginBlock.Extent.IsAfter(this.Line, this.Column))) && (((body.ProcessBlock == null) || body.ProcessBlock.Extent.IsAfter(this.Line, this.Column)) && ((body.EndBlock == null) || body.EndBlock.Extent.IsAfter(this.Line, this.Column)))) { this.SetBreakpoint(functionContext, 0); return true; } if ((this.Column == 0) && (FindSequencePoint(functionContext, this.Line + 1, 0, out num) != null)) { this.SetBreakpoint(functionContext, num); return true; } } return false; }
internal void UnbindForExpression(FunctionContext funcContext, Pipe[] pipes) { if (pipes != null) { ExecutionContext context = funcContext._executionContext; switch (this.FromStream) { case RedirectionStream.All: funcContext._outputPipe = pipes[1]; context.ShellFunctionErrorOutputPipe = pipes[2]; context.ExpressionWarningOutputPipe = pipes[3]; context.ExpressionVerboseOutputPipe = pipes[4]; context.ExpressionDebugOutputPipe = pipes[5]; return; case RedirectionStream.Output: funcContext._outputPipe = pipes[1]; return; case RedirectionStream.Error: context.ShellFunctionErrorOutputPipe = pipes[(int) this.FromStream]; return; case RedirectionStream.Warning: context.ExpressionWarningOutputPipe = pipes[(int) this.FromStream]; return; case RedirectionStream.Verbose: context.ExpressionVerboseOutputPipe = pipes[(int) this.FromStream]; return; case RedirectionStream.Debug: context.ExpressionDebugOutputPipe = pipes[(int) this.FromStream]; return; case RedirectionStream.Host: return; } } }
private void SetupBreakpoints(FunctionContext functionContext) { ScriptBlock scriptBlock = functionContext._scriptBlock; Tuple<List<LineBreakpoint>, BitArray> tuple = this._mapScriptToBreakpoints.GetValue(scriptBlock.ScriptBlockData, _ => Tuple.Create<List<LineBreakpoint>, BitArray>(new List<LineBreakpoint>(), new BitArray(scriptBlock.SequencePoints.Length))); functionContext._boundBreakpoints = tuple.Item1; functionContext._breakPoints = tuple.Item2; this.SetPendingBreakpoints(functionContext); }
private void SetPendingBreakpoints(FunctionContext functionContext) { if (this._pendingBreakpoints.Any<LineBreakpoint>()) { List<LineBreakpoint> list = new List<LineBreakpoint>(); string file = functionContext._scriptBlock.File; if (file != null) { Tuple<List<LineBreakpoint>, BitArray> tuple; this.RegisterScriptFile(file, functionContext.CurrentPosition.StartScriptPosition.GetFullScript()); this._mapScriptToBreakpoints.TryGetValue(functionContext._scriptBlock.ScriptBlockData, out tuple); foreach (LineBreakpoint breakpoint in this._pendingBreakpoints) { bool flag = false; if (breakpoint.TrySetBreakpoint(file, functionContext)) { if (this._context._debuggingMode == 0) { this._context._debuggingMode = 1; } flag = true; tuple.Item1.Add(breakpoint); this._boundBreakpoints[file].Item2.Add(breakpoint); } if (!flag) { list.Add(breakpoint); } } this._pendingBreakpoints = list; } } }
internal void OnSequencePointHit(FunctionContext functionContext) { Func<LineBreakpoint, bool> predicate = null; if ((this._context.ShouldTraceStatement && !this._callStack.Last<CallStackInfo>().IsFrameHidden) && !functionContext._scriptBlock.DebuggerStepThrough) { this.TraceLine(functionContext.CurrentPosition); } if ((this._steppingMode == SteppingMode.StepIn) && ((this._overOrOutFrame == null) || (this._callStack.Last<CallStackInfo>() == this._overOrOutFrame))) { if (!this._callStack.Last<CallStackInfo>().IsFrameHidden) { this._overOrOutFrame = null; this.StopOnSequencePoint(functionContext, _emptyBreakpointList); } else if (this._overOrOutFrame == null) { this.ResumeExecution(DebuggerResumeAction.StepOut); } } else { if (functionContext._breakPoints == null) { this.SetupBreakpoints(functionContext); } if (functionContext._breakPoints[functionContext._currentSequencePointIndex]) { if (predicate == null) { predicate = breakpoint => (breakpoint.SequencePointIndex == functionContext._currentSequencePointIndex) && breakpoint.Enabled; } List<Breakpoint> breakpoints = functionContext._boundBreakpoints.Where<LineBreakpoint>(predicate).ToList<Breakpoint>(); breakpoints = this.TriggerBreakpoints(breakpoints); if (breakpoints.Any<Breakpoint>()) { this.StopOnSequencePoint(functionContext, breakpoints); } } } }
// Called from generated code on entering the script function, called once for each dynamicparam, begin, or end // block, and once for each object written to the pipeline. Also called when entering a trap. internal void EnterScriptFunction(FunctionContext functionContext) { Diagnostics.Assert(functionContext._executionContext == _context, "Wrong debugger is being used."); var invocationInfo = (InvocationInfo)functionContext._localsTuple.GetAutomaticVariable(AutomaticVariable.MyInvocation); var newCallStackInfo = new CallStackInfo { InvocationInfo = invocationInfo, File = functionContext._file, DebuggerStepThrough = functionContext._debuggerStepThrough, FunctionContext = functionContext, IsFrameHidden = functionContext._debuggerHidden, }; _callStack.Add(newCallStackInfo); if (_context._debuggingMode > 0) { var scriptCommandInfo = invocationInfo.MyCommand as ExternalScriptInfo; if (scriptCommandInfo != null) { RegisterScriptFile(scriptCommandInfo); } bool checkLineBp = CheckCommand(invocationInfo); SetupBreakpoints(functionContext); if (functionContext._debuggerStepThrough && _overOrOutFrame == null && _steppingMode == SteppingMode.StepIn) { // Treat like step out, but only if we're not already stepping out ResumeExecution(DebuggerResumeAction.StepOut); } if (checkLineBp) { OnSequencePointHit(functionContext); } if (_context.PSDebugTraceLevel > 1 && !functionContext._debuggerStepThrough && !functionContext._debuggerHidden) { TraceScriptFunctionEntry(functionContext); } } }
public PSScriptCmdlet(ScriptBlock scriptBlock, bool useNewScope, bool fromScriptFile, ExecutionContext context) { _scriptBlock = scriptBlock; _useLocalScope = useNewScope; _fromScriptFile = fromScriptFile; _runOptimized = _scriptBlock.Compile(optimized: context._debuggingMode > 0 ? false : useNewScope); _localsTuple = _scriptBlock.MakeLocalsTuple(_runOptimized); _localsTuple.SetAutomaticVariable(AutomaticVariable.PSCmdlet, this, context); _scriptBlock.SetPSScriptRootAndPSCommandPath(_localsTuple, context); _functionContext = new FunctionContext { _localsTuple = _localsTuple, _scriptBlock = _scriptBlock, _file = _scriptBlock.File, _sequencePoints = _scriptBlock.SequencePoints, _debuggerHidden = _scriptBlock.DebuggerHidden, _debuggerStepThrough = _scriptBlock.DebuggerStepThrough, _executionContext = context, }; _rethrowExitException = context.ScriptCommandProcessorShouldRethrowExit; context.ScriptCommandProcessorShouldRethrowExit = false; }
internal bool TrySetBreakpoint(string scriptFile, FunctionContext functionContext) { Diagnostics.Assert(SequencePointIndex == -1, "shouldn't be trying to set on a pending breakpoint"); if (!scriptFile.Equals(this.Script, StringComparison.OrdinalIgnoreCase)) return false; // A quick check to see if the breakpoint is within the scriptblock. bool couldBeInNestedScriptBlock; var scriptBlock = functionContext._scriptBlock; if (scriptBlock != null) { var ast = scriptBlock.Ast; if (!ast.Extent.ContainsLineAndColumn(Line, Column)) return false; var sequencePoints = functionContext._sequencePoints; if (sequencePoints.Length == 1 && sequencePoints[0] == scriptBlock.Ast.Extent) { // If there was no real executable code in the function (e.g. only function definitions), // we added the entire scriptblock as a sequence point, but it shouldn't be allowed as a breakpoint. return false; } couldBeInNestedScriptBlock = CheckBreakpointInScript.IsInNestedScriptBlock(((IParameterMetadataProvider)ast).Body, this); } else { couldBeInNestedScriptBlock = false; } int sequencePointIndex; var sequencePoint = FindSequencePoint(functionContext, Line, Column, out sequencePointIndex); if (sequencePoint != null) { // If the bp could be in a nested script block, we want to be careful and get the bp in the correct script block. // If it's a simple line bp (no column specified), then the start line must match the bp line exactly, otherwise // we assume the bp is in the nested script block. if (!couldBeInNestedScriptBlock || (sequencePoint.StartLineNumber == Line && Column == 0)) { SetBreakpoint(functionContext, sequencePointIndex); return true; } } // Before using heuristics, make sure the breakpoint isn't in a nested function/script block. if (couldBeInNestedScriptBlock) { return false; } // Not found. First, we check if the line/column is before any real code. If so, we'll // move the breakpoint to the first interesting sequence point (could be a dynamicparam, // begin, process, or end block.) if (scriptBlock != null) { var ast = scriptBlock.Ast; var bodyAst = ((IParameterMetadataProvider)ast).Body; if ((bodyAst.DynamicParamBlock == null || bodyAst.DynamicParamBlock.Extent.IsAfter(Line, Column)) && (bodyAst.BeginBlock == null || bodyAst.BeginBlock.Extent.IsAfter(Line, Column)) && (bodyAst.ProcessBlock == null || bodyAst.ProcessBlock.Extent.IsAfter(Line, Column)) && (bodyAst.EndBlock == null || bodyAst.EndBlock.Extent.IsAfter(Line, Column))) { SetBreakpoint(functionContext, 0); return true; } } // Still not found. Try fudging a bit, but only if it's a simple line breakpoint. if (Column == 0 && FindSequencePoint(functionContext, Line + 1, 0, out sequencePointIndex) != null) { SetBreakpoint(functionContext, sequencePointIndex); return true; } return false; }
private void WriteToCurrentErrorPipe(bool createLocalScope, Pipe outputPipe, ref object[] args, ExecutionContext contextFromTLS, Action<FunctionContext> codeToInvoke, MutableTuple mutableTuple, PSLanguageMode? languageMode, ref Dictionary<string, PSVariable> strs) { if (!createLocalScope) { if (contextFromTLS.EngineSessionState.CurrentScope.LocalsTuple != null) { contextFromTLS.EngineSessionState.CurrentScope.DottedScopes.Push(mutableTuple); strs = new Dictionary<string, PSVariable>(); } else { contextFromTLS.EngineSessionState.CurrentScope.LocalsTuple = mutableTuple; } } else { SessionStateScope sessionStateScope = contextFromTLS.EngineSessionState.NewScope(false); contextFromTLS.EngineSessionState.CurrentScope = sessionStateScope; sessionStateScope.LocalsTuple = mutableTuple; } if (languageMode.HasValue) { contextFromTLS.LanguageMode = languageMode.Value; } args = ScriptBlock.BindArgumentsForScripblockInvoke((RuntimeDefinedParameter[])this.RuntimeDefinedParameters.Data, args, contextFromTLS, !createLocalScope, strs, mutableTuple); mutableTuple.SetAutomaticVariable(AutomaticVariable.Args, args, contextFromTLS); contextFromTLS.EngineSessionState.CurrentScope.ScopeOrigin = CommandOrigin.Internal; FunctionContext functionContext = new FunctionContext(); functionContext._executionContext = contextFromTLS; functionContext._outputPipe = outputPipe; functionContext._localsTuple = mutableTuple; functionContext._scriptBlock = this; functionContext._sequencePoints = this.SequencePoints; FunctionContext functionContext1 = functionContext; codeToInvoke(functionContext1); }
private void SetPendingBreakpoints(FunctionContext functionContext) { if (!_pendingBreakpoints.Any()) return; var newPendingBreakpoints = new List<LineBreakpoint>(); var currentScriptFile = functionContext._file; // If we're not in a file, we can't have any line breakpoints. if (currentScriptFile == null) return; // Normally we register a script file when the script is run or the module is imported, // but if there weren't any breakpoints when the script was run and the script was dotted, // we will end up here with pending breakpoints, but we won't have cached the list of // breakpoints in the script. RegisterScriptFile(currentScriptFile, functionContext.CurrentPosition.StartScriptPosition.GetFullScript()); Tuple<List<LineBreakpoint>, BitArray> tuple; if (!_mapScriptToBreakpoints.TryGetValue(functionContext._sequencePoints, out tuple)) { Diagnostics.Assert(false, "If the script block is still alive, the entry should not be collected."); } Diagnostics.Assert(tuple.Item1 == functionContext._boundBreakpoints, "What's up?"); foreach (var breakpoint in _pendingBreakpoints) { bool bound = false; if (breakpoint.TrySetBreakpoint(currentScriptFile, functionContext)) { if (_context._debuggingMode == 0) { SetInternalDebugMode(InternalDebugMode.Enabled); } bound = true; tuple.Item1.Add(breakpoint); // We need to keep track of any breakpoints that are bound in each script because they may // need to be rebound if the script changes. var boundBreakpoints = _boundBreakpoints[currentScriptFile].Item2; Diagnostics.Assert(boundBreakpoints.IndexOf(breakpoint) < 0, "Don't add more than once."); boundBreakpoints.Add(breakpoint); } if (!bound) { newPendingBreakpoints.Add(breakpoint); } } _pendingBreakpoints = newPendingBreakpoints; }
private void StopOnSequencePoint(FunctionContext functionContext, List<Breakpoint> breakpoints) { if (functionContext._debuggerHidden) { // Never stop in a DebuggerHidden scriptblock. return; } if (functionContext._sequencePoints.Length == 1 && functionContext._scriptBlock != null && object.ReferenceEquals(functionContext._sequencePoints[0], functionContext._scriptBlock.Ast.Extent)) { // If the script is empty or only defines functions, we used the script block extent as a sequence point, but that // was only intended for error reporting, it was not meant to be hit as a breakpoint. return; } var invocationInfo = new InvocationInfo(null, functionContext.CurrentPosition, _context); OnDebuggerStop(invocationInfo, breakpoints); }
private static ActionPreference ProcessTraps(FunctionContext funcContext, RuntimeException rte) { int index = -1; Exception replaceParentContainsErrorRecordException = null; Exception innerException = rte.InnerException; Type[] types = funcContext._traps.Last<Tuple<Type[], Action<FunctionContext>[], Type[]>>().Item1; Action<FunctionContext>[] actionArray = funcContext._traps.Last<Tuple<Type[], Action<FunctionContext>[], Type[]>>().Item2; if (innerException != null) { index = FindMatchingHandlerByType(innerException.GetType(), types); replaceParentContainsErrorRecordException = innerException; } if ((index == -1) || types[index].Equals(typeof(CatchAll))) { int num2 = FindMatchingHandlerByType(rte.GetType(), types); if (num2 != index) { index = num2; replaceParentContainsErrorRecordException = rte; } } if (index != -1) { try { ErrorRecord errorRecord = rte.ErrorRecord; ExecutionContext context = funcContext._executionContext; if (context.CurrentCommandProcessor != null) { context.CurrentCommandProcessor.ForgetScriptException(); } try { MutableTuple tuple = MutableTuple.MakeTuple(funcContext._traps.Last<Tuple<Type[], Action<FunctionContext>[], Type[]>>().Item3[index], Compiler.DottedLocalsNameIndexMap); tuple.SetAutomaticVariable(AutomaticVariable.Underbar, new ErrorRecord(errorRecord, replaceParentContainsErrorRecordException), context); for (int i = 1; i < 9; i++) { tuple.SetValue(i, funcContext._localsTuple.GetValue(i)); } SessionStateScope scope = context.EngineSessionState.NewScope(false); context.EngineSessionState.CurrentScope = scope; scope.LocalsTuple = tuple; FunctionContext context2 = new FunctionContext { _scriptBlock = funcContext._scriptBlock, _sequencePoints = funcContext._sequencePoints, _executionContext = funcContext._executionContext, _boundBreakpoints = funcContext._boundBreakpoints, _outputPipe = funcContext._outputPipe, _breakPoints = funcContext._breakPoints, _localsTuple = tuple }; actionArray[index](context2); } catch (TargetInvocationException exception3) { throw exception3.InnerException; } finally { context.EngineSessionState.RemoveScope(context.EngineSessionState.CurrentScope); } return QueryForAction(rte, replaceParentContainsErrorRecordException.Message, context); } catch (ContinueException) { return ActionPreference.SilentlyContinue; } catch (BreakException) { return ActionPreference.Stop; } } return ActionPreference.Stop; }
internal void TraceScriptFunctionEntry(FunctionContext functionContext) { var methodName = functionContext._functionName; if (String.IsNullOrEmpty(functionContext._file)) { Trace("TraceEnteringFunction", ParserStrings.TraceEnteringFunction, methodName); } else { Trace("TraceEnteringFunctionDefinedInFile", ParserStrings.TraceEnteringFunctionDefinedInFile, methodName, functionContext._file); } }
internal override void Prepare(IDictionary psDefaultParameterValues) { if (UseLocalScope) { Diagnostics.Assert(CommandScope.LocalsTuple == null, "a newly created scope shouldn't have it's tuple set."); CommandScope.LocalsTuple = _localsTuple; } _localsTuple.SetAutomaticVariable(AutomaticVariable.MyInvocation, this.Command.MyInvocation, _context); _scriptBlock.SetPSScriptRootAndPSCommandPath(_localsTuple, _context); _functionContext = new FunctionContext { _executionContext = _context, _outputPipe = commandRuntime.OutputPipe, _localsTuple = _localsTuple, _scriptBlock = _scriptBlock, _file = _scriptBlock.File, _debuggerHidden = _scriptBlock.DebuggerHidden, _debuggerStepThrough = _scriptBlock.DebuggerStepThrough, _sequencePoints = _scriptBlock.SequencePoints, }; }
private void SetupBreakpoints(FunctionContext functionContext) { var scriptDebugData = _mapScriptToBreakpoints.GetValue(functionContext._sequencePoints, _ => Tuple.Create(new List<LineBreakpoint>(), new BitArray(functionContext._sequencePoints.Length))); functionContext._boundBreakpoints = scriptDebugData.Item1; functionContext._breakPoints = scriptDebugData.Item2; SetPendingBreakpoints(functionContext); }
private void StopOnSequencePoint(FunctionContext functionContext, List<Breakpoint> breakpoints) { if (!functionContext._scriptBlock.DebuggerHidden && ((functionContext._sequencePoints.Length != 1) || !object.ReferenceEquals(functionContext._sequencePoints[0], functionContext._scriptBlock.Ast.Extent))) { InvocationInfo invocationInfo = new InvocationInfo(null, functionContext.CurrentPosition, this._context); this.OnDebuggerStop(invocationInfo, breakpoints); } }
internal void TraceScriptFunctionEntry(FunctionContext functionContext) { ScriptBlock block = functionContext._scriptBlock; string str = functionContext._functionName; if (string.IsNullOrEmpty(block.File)) { this.Trace("TraceEnteringFunction", ParserStrings.TraceEnteringFunction, new object[] { str }); } else { this.Trace("TraceEnteringFunctionDefinedInFile", ParserStrings.TraceEnteringFunctionDefinedInFile, new object[] { str, block.File }); } }
internal override void Prepare(IDictionary psDefaultParameterValues) { if (base.UseLocalScope) { base.CommandScope.LocalsTuple = this._localsTuple; } this._localsTuple.SetAutomaticVariable(AutomaticVariable.MyInvocation, base.Command.MyInvocation, base._context); this._scriptBlock.SetPSScriptRootAndPSCommandPath(this._localsTuple, base._context); FunctionContext context = new FunctionContext { _executionContext = base._context, _outputPipe = base.commandRuntime.OutputPipe, _localsTuple = this._localsTuple, _scriptBlock = this._scriptBlock, _sequencePoints = this._scriptBlock.SequencePoints }; this._functionContext = context; }
internal CallStackFrame(System.Management.Automation.Language.FunctionContext functionContext, System.Management.Automation.InvocationInfo invocationInfo) { this.InvocationInfo = invocationInfo; this._functionContext = functionContext; this.Position = functionContext.CurrentPosition; }
internal static void InvokePipeline (object input, bool ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext) { PipelineProcessor pipelineProcessor = new PipelineProcessor (); System.Management.Automation.ExecutionContext context = funcContext._executionContext; Pipe pipe = funcContext._outputPipe; try { if (context.Events != null) { context.Events.ProcessPendingActions (); } if ((input == AutomationNull.Value) && !ignoreInput) { AddNoopCommandProcessor (pipelineProcessor, context); } CommandProcessorBase commandProcessor = null; CommandRedirection[] redirections = null; for (int i = 0; i < pipeElements.Length; i++) { redirections = (commandRedirections != null) ? commandRedirections [i] : null; commandProcessor = AddCommand (pipelineProcessor, pipeElements [i], pipeElementAsts [i], redirections, context); } if ((commandProcessor != null) && !commandProcessor.CommandRuntime.OutputPipe.IsRedirected) { pipelineProcessor.LinkPipelineSuccessOutput (pipe ?? new Pipe (new ArrayList ())); if (redirections != null) { foreach (CommandRedirection redirection in redirections) { if (redirection is MergingRedirection) { redirection.Bind (pipelineProcessor, commandProcessor, context); } } } } context.PushPipelineProcessor (pipelineProcessor); try { pipelineProcessor.SynchronousExecuteEnumerate (input, null, true); } finally { context.PopPipelineProcessor (false); } } finally { context.QuestionMarkVariableValue = !pipelineProcessor.ExecutionFailed; pipelineProcessor.Dispose(); } }
private void SetBreakpoint(FunctionContext functionContext, int sequencePointIndex) { // Remember the bitarray so we when the last breakpoint is removed, we can avoid // stopping at the sequence point. this.BreakpointBitArray = functionContext._breakPoints; this.SequencePoints = functionContext._sequencePoints; SequencePointIndex = sequencePointIndex; this.BreakpointBitArray.Set(SequencePointIndex, true); }
private void EnterScriptFunction(FunctionContext functionContext) { InvocationInfo automaticVariable = (InvocationInfo) functionContext._localsTuple.GetAutomaticVariable(AutomaticVariable.MyInvocation); ScriptBlock block = functionContext._scriptBlock; CallStackInfo item = new CallStackInfo { InvocationInfo = automaticVariable, ScriptBlock = block, FunctionContext = functionContext, IsFrameHidden = block.DebuggerHidden }; this._callStack.Add(item); if (this._context._debuggingMode > 0) //TODO: REVIEW: Why was 0?? { ExternalScriptInfo myCommand = automaticVariable.MyCommand as ExternalScriptInfo; if (myCommand != null) { this.RegisterScriptFile(myCommand); } bool flag = this.CheckCommand(automaticVariable); this.SetupBreakpoints(functionContext); if ((block.DebuggerStepThrough && (this._overOrOutFrame == null)) && (this._steppingMode == SteppingMode.StepIn)) { this.ResumeExecution(DebuggerResumeAction.StepOut); } if (flag) { this.OnSequencePointHit(functionContext); } if (((this._context.PSDebugTraceLevel > 1) && !block.DebuggerStepThrough) && !block.DebuggerHidden) { this.TraceScriptFunctionEntry(functionContext); } } }
internal void InvokeWithPipeImpl(ScriptBlockClauseToInvoke clauseToInvoke, bool createLocalScope, Dictionary<string, ScriptBlock> functionsToDefine, List<PSVariable> variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, object dollarUnder, object input, object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, params object[] args) { if (clauseToInvoke == ScriptBlockClauseToInvoke.Begin && !HasBeginBlock) { return; } else if (clauseToInvoke == ScriptBlockClauseToInvoke.Process && !HasProcessBlock) { return; } else if (clauseToInvoke == ScriptBlockClauseToInvoke.End && !HasEndBlock) { return; } ExecutionContext context = GetContextFromTLS(); Diagnostics.Assert(SessionStateInternal == null || SessionStateInternal.ExecutionContext == context, "The scriptblock is being invoked in a runspace different than the one where it was created"); if (context.CurrentPipelineStopping) { throw new PipelineStoppedException(); } // Validate at the arguments are consistent. The only public API that gets you here never sets createLocalScope to false... Diagnostics.Assert(createLocalScope == true || functionsToDefine == null, "When calling ScriptBlock.InvokeWithContext(), if 'functionsToDefine' != null then 'createLocalScope' must be true"); Diagnostics.Assert(createLocalScope == true || variablesToDefine == null, "When calling ScriptBlock.InvokeWithContext(), if 'variablesToDefine' != null then 'createLocalScope' must be true"); if (args == null) { args = Utils.EmptyArray<object>(); } bool runOptimized = context._debuggingMode > 0 ? false : createLocalScope; var codeToInvoke = GetCodeToInvoke(ref runOptimized, clauseToInvoke); if (codeToInvoke == null) return; if (outputPipe == null) { // If we don't have a pipe to write to, we need to discard all results. outputPipe = new Pipe { NullPipe = true }; } var locals = MakeLocalsTuple(runOptimized); if (dollarUnder != AutomationNull.Value) { locals.SetAutomaticVariable(AutomaticVariable.Underbar, dollarUnder, context); } if (input != AutomationNull.Value) { locals.SetAutomaticVariable(AutomaticVariable.Input, input, context); } if (scriptThis != AutomationNull.Value) { locals.SetAutomaticVariable(AutomaticVariable.This, scriptThis, context); } SetPSScriptRootAndPSCommandPath(locals, context); var oldShellFunctionErrorOutputPipe = context.ShellFunctionErrorOutputPipe; var oldExternalErrorOutput = context.ExternalErrorOutput; var oldScopeOrigin = context.EngineSessionState.CurrentScope.ScopeOrigin; var oldSessionState = context.EngineSessionState; // If the script block has a different language mode than the current, // change the language mode. PSLanguageMode? oldLanguageMode = null; PSLanguageMode? newLanguageMode = null; if ((this.LanguageMode.HasValue) && (this.LanguageMode != context.LanguageMode)) { oldLanguageMode = context.LanguageMode; newLanguageMode = this.LanguageMode; } Dictionary<string, PSVariable> backupWhenDotting = null; try { var myInvocationInfo = invocationInfo; if (myInvocationInfo == null) { var callerFrame = context.Debugger.GetCallStack().LastOrDefault(); var extent = (callerFrame != null) ? callerFrame.FunctionContext.CurrentPosition : Ast.Extent; myInvocationInfo = new InvocationInfo(null, extent, context); } locals.SetAutomaticVariable(AutomaticVariable.MyInvocation, myInvocationInfo, context); if (SessionStateInternal != null) context.EngineSessionState = SessionStateInternal; // If we don't want errors written, hide the error pipe. switch (errorHandlingBehavior) { case ErrorHandlingBehavior.WriteToCurrentErrorPipe: // no need to do anything break; case ErrorHandlingBehavior.WriteToExternalErrorPipe: context.ShellFunctionErrorOutputPipe = null; break; case ErrorHandlingBehavior.SwallowErrors: context.ShellFunctionErrorOutputPipe = null; context.ExternalErrorOutput = new DiscardingPipelineWriter(); break; } if (createLocalScope) { var newScope = context.EngineSessionState.NewScope(false); context.EngineSessionState.CurrentScope = newScope; newScope.LocalsTuple = locals; // Inject passed in functions into the scope if (functionsToDefine != null) { foreach (var def in functionsToDefine) { if (string.IsNullOrWhiteSpace(def.Key)) { PSInvalidOperationException e = PSTraceSource.NewInvalidOperationException( ParserStrings.EmptyFunctionNameInFunctionDefinitionDictionary); e.SetErrorId("EmptyFunctionNameInFunctionDefinitionDictionary"); throw e; } if (def.Value == null) { PSInvalidOperationException e = PSTraceSource.NewInvalidOperationException( ParserStrings.NullFunctionBodyInFunctionDefinitionDictionary, def.Key); e.SetErrorId("NullFunctionBodyInFunctionDefinitionDictionary"); throw e; } newScope.FunctionTable.Add(def.Key, new FunctionInfo(def.Key, def.Value, context)); } } // Inject passed in variables into the scope if (variablesToDefine != null) { int index = 0; foreach (var psvar in variablesToDefine) { // Check for null entries. if (psvar == null) { PSInvalidOperationException e = PSTraceSource.NewInvalidOperationException( ParserStrings.NullEntryInVariablesDefinitionList, index); e.SetErrorId("NullEntryInVariablesDefinitionList"); throw e; } string name = psvar.Name; Diagnostics.Assert(!(string.Equals(name, "this") || string.Equals(name, "_") || string.Equals(name, "input")), "The list of variables to set in the scriptblock's scope cannot contain 'this', '_' or 'input'. These variables should be removed before passing the collection to this routine."); index++; newScope.Variables.Add(name, psvar); } } } else { if (context.EngineSessionState.CurrentScope.LocalsTuple == null) { // If the locals tuple is, that means either: // * we're invoking a script block for a module // * something unexpected context.EngineSessionState.CurrentScope.LocalsTuple = locals; } else { context.EngineSessionState.CurrentScope.DottedScopes.Push(locals); backupWhenDotting = new Dictionary<string, PSVariable>(); } } // Set the language mode if (newLanguageMode.HasValue) { context.LanguageMode = newLanguageMode.Value; } args = BindArgumentsForScriptblockInvoke( (RuntimeDefinedParameter[])RuntimeDefinedParameters.Data, args, context, !createLocalScope, backupWhenDotting, locals); locals.SetAutomaticVariable(AutomaticVariable.Args, args, context); context.EngineSessionState.CurrentScope.ScopeOrigin = CommandOrigin.Internal; var functionContext = new FunctionContext { _executionContext = context, _outputPipe = outputPipe, _localsTuple = locals, _scriptBlock = this, _file = this.File, _debuggerHidden = this.DebuggerHidden, _debuggerStepThrough = this.DebuggerStepThrough, _sequencePoints = SequencePoints, }; ScriptBlock.LogScriptBlockStart(this, context.CurrentRunspace.InstanceId); try { codeToInvoke(functionContext); } finally { ScriptBlock.LogScriptBlockEnd(this, context.CurrentRunspace.InstanceId); } } catch (TargetInvocationException tie) { // DynamicInvoke always wraps, so unwrap here. throw tie.InnerException; } finally { // Restore the language mode if (oldLanguageMode.HasValue) { context.LanguageMode = oldLanguageMode.Value; } // Now restore the output pipe... context.ShellFunctionErrorOutputPipe = oldShellFunctionErrorOutputPipe; context.ExternalErrorOutput = oldExternalErrorOutput; // Restore the interactive command state... context.EngineSessionState.CurrentScope.ScopeOrigin = oldScopeOrigin; if (createLocalScope) { context.EngineSessionState.RemoveScope(context.EngineSessionState.CurrentScope); } else if (backupWhenDotting != null) { context.EngineSessionState.CurrentScope.DottedScopes.Pop(); Diagnostics.Assert(backupWhenDotting != null, "when dotting, this dictionary isn't null"); foreach (var pair in backupWhenDotting) { if (pair.Value != null) { context.EngineSessionState.SetVariable(pair.Value, false, CommandOrigin.Internal); } else { context.EngineSessionState.RemoveVariable(pair.Key); } } } // Restore session state... context.EngineSessionState = oldSessionState; } }
/// <summary> /// Constructor /// </summary> /// <param name="functionContext">Function context</param> /// <param name="invocationInfo">Invocation Info</param> internal CallStackFrame(FunctionContext functionContext, InvocationInfo invocationInfo) { if (invocationInfo == null) { throw new PSArgumentNullException("invocationInfo"); } if (functionContext != null) { this.InvocationInfo = invocationInfo; FunctionContext = functionContext; this.Position = functionContext.CurrentPosition; } else { // WF functions do not have functionContext. Use InvocationInfo. this.InvocationInfo = invocationInfo; this.Position = invocationInfo.ScriptPosition; FunctionContext = new FunctionContext(); FunctionContext._functionName = invocationInfo.ScriptName; } }
internal CallStackFrame(System.Management.Automation.Language.FunctionContext functionContext, System.Management.Automation.InvocationInfo invocationInfo) { this.InvocationInfo = invocationInfo; this._functionContext = functionContext; this.Position = functionContext.CurrentPosition; }
private static object GetExpressionValue(ExpressionAst expressionAst, bool isTrustedInput, ExecutionContext context, SessionStateInternal sessionStateInternal, IDictionary usingValues, ref Func<FunctionContext, object> lambda, ref IScriptExtent[] sequencePoints, ref Type localsTupleType) { object constantValue; if (IsConstantValueVisitor.IsConstant(expressionAst, out constantValue)) { return constantValue; } // If this isn't trusted input, then just return. if (!isTrustedInput) { return null; } // Can't be exposed to untrusted input - exposing private variable names / etc. could be // information disclosure. var variableAst = expressionAst as VariableExpressionAst; if (variableAst != null) { // We can avoid creating a lambda for the common case of a simple variable expression. return VariableOps.GetVariableValue(variableAst.VariablePath, context, variableAst); } // Can't be exposed to untrusted input - invoking arbitrary code could result in remote code // execution. if (lambda == null) { lambda = (new Compiler()).CompileSingleExpression(expressionAst, out sequencePoints, out localsTupleType); } SessionStateInternal oldSessionState = context.EngineSessionState; try { if (sessionStateInternal != null && context.EngineSessionState != sessionStateInternal) { // If we're running a function from a module, we need to evaluate the initializers in the // module context, not the callers context... context.EngineSessionState = sessionStateInternal; } var resultList = new List<object>(); var pipe = new Pipe(resultList); try { var functionContext = new FunctionContext { _sequencePoints = sequencePoints, _executionContext = context, _file = expressionAst.Extent.File, _outputPipe = pipe, _localsTuple = MutableTuple.MakeTuple(localsTupleType, DottedLocalsNameIndexMap) }; if (usingValues != null) { var boundParameters = new PSBoundParametersDictionary { ImplicitUsingParameters = usingValues }; functionContext._localsTuple.SetAutomaticVariable(AutomaticVariable.PSBoundParameters, boundParameters, context); } var result = lambda(functionContext); if (result == AutomationNull.Value) { return resultList.Count == 0 ? null : PipelineOps.PipelineResult(resultList); } return result; } catch (TargetInvocationException tie) { throw tie.InnerException; } } catch (TerminateException) { // the debugger is terminating the execution; bubble up the exception throw; } catch (FlowControlException) { // ignore break, continue and return exceptions return null; } finally { context.EngineSessionState = oldSessionState; } }