DbgEngineValueNodeAssignmentResult AssignCore(DbgEvaluationInfo evalInfo, string expression, DbgEvaluationOptions options) { try { var ee = evalInfo.Context.Language.ExpressionEvaluator; var res = ee.Assign(evalInfo, Expression, expression, options); return(new DbgEngineValueNodeAssignmentResult(res.Flags, res.Error)); } catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex)) { return(new DbgEngineValueNodeAssignmentResult(DbgEEAssignmentResultFlags.None, PredefinedEvaluationErrorMessages.InternalDebuggerError)); } }
/// <summary> /// Creates an assembly that is used to get all the locals /// </summary> /// <param name="context">Evaluation context</param> /// <param name="frame">Frame</param> /// <param name="references">.NET module references</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public abstract DbgDotNetCompilationResult CompileGetLocals(DbgEvaluationContext context, DbgStackFrame frame, DbgModuleReference[] references, DbgEvaluationOptions options, CancellationToken cancellationToken);
public override DbgEvaluationResult Evaluate(DbgEvaluationInfo evalInfo, string expression, DbgEvaluationOptions options, object state) { if (evalInfo == null) { throw new ArgumentNullException(nameof(evalInfo)); } if (!(evalInfo.Context is DbgEvaluationContextImpl)) { throw new ArgumentException(); } if (evalInfo.Context.Language != Language) { throw new ArgumentException(); } if (evalInfo.Context.Runtime.RuntimeKindGuid != runtimeKindGuid) { throw new ArgumentException(); } if (expression == null) { throw new ArgumentNullException(nameof(expression)); } Debug.Assert((evalInfo.Context.Options & DbgEvaluationContextOptions.NoMethodBody) == 0, "Missing method debug info"); return(CreateResult(evalInfo.Context.Runtime, engineExpressionEvaluator.Evaluate(evalInfo, expression, options, state))); }
public override DbgDotNetCompilationResult CompileExpression(DbgEvaluationContext context, DbgStackFrame frame, DbgModuleReference[] references, DbgDotNetAlias[] aliases, string expression, DbgEvaluationOptions options, CancellationToken cancellationToken) { GetCompilationState <CSharpEvalContextState>(context, frame, references, out var langDebugInfo, out var method, out var methodToken, out var localVarSigTok, out var state, out var metadataBlocks, out var methodVersion); var getMethodDebugInfo = CreateGetMethodDebugInfo(state, langDebugInfo); var evalCtx = EvaluationContext.CreateMethodContext(state.MetadataContext, metadataBlocks, getMethodDebugInfo, method.Module.Mvid ?? Guid.Empty, methodToken, methodVersion, langDebugInfo.ILOffset, localVarSigTok); return(CompileExpressionCore(aliases, expression, options, state, metadataBlocks, evalCtx, cancellationToken)); }
public override DbgDotNetCompilationResult CompileAssignment(DbgEvaluationContext context, DbgStackFrame frame, DbgModuleReference[] references, DbgDotNetAlias[] aliases, string target, string expression, DbgEvaluationOptions options, CancellationToken cancellationToken) { GetCompilationState <CSharpEvalContextState>(context, frame, references, out var langDebugInfo, out var method, out var methodToken, out var localVarSigTok, out var state, out var metadataBlocks, out var methodVersion); var getMethodDebugInfo = CreateGetMethodDebugInfo(state, langDebugInfo); var evalCtx = EvaluationContext.CreateMethodContext(state.MetadataContext, metadataBlocks, getMethodDebugInfo, method.Module.Mvid ?? Guid.Empty, methodToken, methodVersion, langDebugInfo.ILOffset, localVarSigTok); state.MetadataContext = new CSharpMetadataContext(metadataBlocks, evalCtx); var compileResult = evalCtx.CompileAssignment(target, expression, CreateAliases(aliases), out var resultProperties, out var errorMessage); return(CreateCompilationResult(target, compileResult, resultProperties, errorMessage, DbgDotNetText.Empty)); }
public override DbgEngineEEAssignmentResult Assign(DbgEvaluationInfo evalInfo, string expression, string valueExpression, DbgEvaluationOptions options) => new DbgEngineEEAssignmentResult(DbgEEAssignmentResultFlags.CompilerError, ERROR);
DbgEngineEEAssignmentResult AssignCore(DbgEvaluationInfo evalInfo, string expression, string valueExpression, DbgEvaluationOptions options) { var resultFlags = DbgEEAssignmentResultFlags.None; try { var info = dbgAliasProvider.GetAliases(evalInfo); var refsResult = dbgModuleReferenceProvider.GetModuleReferences(evalInfo.Runtime, evalInfo.Frame, info.typeReferences); if (refsResult.ErrorMessage != null) { return(new DbgEngineEEAssignmentResult(resultFlags, refsResult.ErrorMessage)); } var compRes = expressionCompiler.CompileAssignment(evalInfo, refsResult.ModuleReferences, info.aliases, expression, valueExpression, options); evalInfo.CancellationToken.ThrowIfCancellationRequested(); if (compRes.IsError) { return(new DbgEngineEEAssignmentResult(resultFlags | DbgEEAssignmentResultFlags.CompilerError, compRes.ErrorMessage)); } var state = dnILInterpreter.CreateState(compRes.Assembly); Debug.Assert(compRes.CompiledExpressions.Length == 1); ref var exprInfo = ref compRes.CompiledExpressions[0]; if (exprInfo.ErrorMessage != null) { return(new DbgEngineEEAssignmentResult(resultFlags | DbgEEAssignmentResultFlags.CompilerError, exprInfo.ErrorMessage)); } resultFlags |= DbgEEAssignmentResultFlags.ExecutedCode; var res = dnILInterpreter.Execute(evalInfo, state, exprInfo.TypeName, exprInfo.MethodName, options, out _); if (res.HasError) { return(new DbgEngineEEAssignmentResult(resultFlags, res.ErrorMessage)); } if (res.ValueIsException) { res.Value.Dispose(); var error = string.Format(dnSpy_Debugger_DotNet_Resources.Method_X_ThrewAnExceptionOfType_Y, expression, res.Value.Type.FullName); return(new DbgEngineEEAssignmentResult(resultFlags, error)); } res.Value?.Dispose(); return(new DbgEngineEEAssignmentResult()); }
/// <summary> /// Creates an assembly that is used to get all the locals /// </summary> /// <param name="evalInfo">Evaluation info</param> /// <param name="references">.NET module references</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DbgDotNetCompilationResult CompileGetLocals(DbgEvaluationInfo evalInfo, DbgModuleReference[] references, DbgEvaluationOptions options);
/// <summary> /// Compiles an assignment /// </summary> /// <param name="evalInfo">Evaluation info</param> /// <param name="references">.NET module references</param> /// <param name="aliases">Aliases</param> /// <param name="target">Target expression (lhs)</param> /// <param name="expression">Expression (rhs)</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DbgDotNetCompilationResult CompileAssignment(DbgEvaluationInfo evalInfo, DbgModuleReference[] references, DbgDotNetAlias[] aliases, string target, string expression, DbgEvaluationOptions options);
public abstract DbgValueNodeInfo[] GetNodes(DbgEvaluationContext context, DbgLanguage language, DbgStackFrame frame, DbgEvaluationOptions options, DbgValueNodeEvaluationOptions nodeEvalOptions);
/// <summary> /// Compiles a type expression (compiles <see cref="DebuggerDisplayAttribute"/> expressions) /// </summary> /// <param name="evalInfo">Evaluation info</param> /// <param name="type">Type</param> /// <param name="references">.NET module references</param> /// <param name="aliases">Aliases</param> /// <param name="expression">Expression</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DbgDotNetCompilationResult CompileTypeExpression(DbgEvaluationInfo evalInfo, DmdType type, DbgModuleReference[] references, DbgDotNetAlias[] aliases, string expression, DbgEvaluationOptions options);
public override ValueNodesProviderResult GetNodes(DbgEvaluationInfo evalInfo, DbgLanguage language, DbgEvaluationOptions evalOptions, DbgValueNodeEvaluationOptions nodeEvalOptions, DbgValueFormatterOptions nameFormatterOptions) { var returnValues = language.ReturnValuesProvider.GetNodes(evalInfo, nodeEvalOptions); var variables = language.AutosProvider.GetNodes(evalInfo, nodeEvalOptions); var res = new DbgValueNodeInfo[returnValues.Length + variables.Length]; int ri = 0; for (int i = 0; i < returnValues.Length; i++, ri++) { res[ri] = new DbgValueNodeInfo(returnValues[i], GetNextReturnValueId(), causesSideEffects: false); } for (int i = 0; i < variables.Length; i++, ri++) { res[ri] = new DbgValueNodeInfo(variables[i], causesSideEffects: false); } const bool recreateAllNodes = false; return(new ValueNodesProviderResult(res, recreateAllNodes)); }
/// <summary> /// Assigns the value of an expression to another expression. It blocks the current thread until the evaluation is complete. /// </summary> /// <param name="context">Evaluation context</param> /// <param name="frame">Frame</param> /// <param name="expression">Target expression (lhs)</param> /// <param name="valueExpression">Source expression (rhs)</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public abstract DbgEEAssignmentResult Assign(DbgEvaluationContext context, DbgStackFrame frame, string expression, string valueExpression, DbgEvaluationOptions options, CancellationToken cancellationToken = default);
/// <summary> /// Evaluates an expression. It blocks the current thread until the evaluation is complete. /// The returned <see cref="DbgValue"/> is automatically closed when its runtime continues. /// </summary> /// <param name="context">Evaluation context</param> /// <param name="frame">Frame</param> /// <param name="expression">Expression to evaluate</param> /// <param name="options">Options</param> /// <param name="state">State created by <see cref="CreateExpressionEvaluatorState"/> or null to store the state in <paramref name="context"/></param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public abstract DbgEvaluationResult Evaluate(DbgEvaluationContext context, DbgStackFrame frame, string expression, DbgEvaluationOptions options, object state, CancellationToken cancellationToken = default);
public override DbgEngineValueNodeAssignmentResult Assign(DbgEvaluationInfo evalInfo, string expression, DbgEvaluationOptions options) => new DbgEngineValueNodeAssignmentResult(DbgEEAssignmentResultFlags.None, NullDbgEngineExpressionEvaluator.ERROR);
public DbgDotNetValueCreator(DbgDotNetEngineValueNodeFactory valueNodeFactory, DbgDotNetILInterpreter dnILInterpreter, DbgEvaluationInfo evalInfo, DbgValueNodeEvaluationOptions nodeOptions, DbgEvaluationOptions options, byte[] assemblyBytes) { this.valueNodeFactory = valueNodeFactory; this.dnILInterpreter = dnILInterpreter; this.evalInfo = evalInfo; this.nodeOptions = nodeOptions; this.options = options; this.assemblyBytes = assemblyBytes; }
public override DbgEngineEvaluationResult Evaluate(DbgEvaluationInfo evalInfo, string expression, DbgEvaluationOptions options, object state) => new DbgEngineEvaluationResult(ERROR);
/// <summary> /// Constructor /// </summary> /// <param name="expression">Expression to evaluate</param> /// <param name="nodeOptions">Value node options</param> /// <param name="options">Evaluation options</param> /// <param name="expressionEvaluatorState">Expression evaluator state or null, see <see cref="DbgExpressionEvaluator.CreateExpressionEvaluatorState"/></param> public DbgExpressionEvaluationInfo(string expression, DbgValueNodeEvaluationOptions nodeOptions, DbgEvaluationOptions options, object?expressionEvaluatorState) { Expression = expression ?? throw new ArgumentNullException(nameof(expression)); NodeOptions = nodeOptions; Options = options; ExpressionEvaluatorState = expressionEvaluatorState; }
public override DbgEngineEEAssignmentResult Assign(DbgEvaluationInfo evalInfo, string expression, string valueExpression, DbgEvaluationOptions options) { var dispatcher = evalInfo.Runtime.GetDotNetRuntime().Dispatcher; if (dispatcher.CheckAccess()) { return(AssignCore(evalInfo, expression, valueExpression, options)); } return(Assign(dispatcher, evalInfo, expression, valueExpression, options)); DbgEngineEEAssignmentResult Assign(DbgDotNetDispatcher dispatcher2, DbgEvaluationInfo evalInfo2, string expression2, string valueExpression2, DbgEvaluationOptions options2) { if (!dispatcher2.TryInvokeRethrow(() => AssignCore(evalInfo2, expression2, valueExpression2, options2), out var result)) { result = new DbgEngineEEAssignmentResult(DbgEEAssignmentResultFlags.None, DispatcherConstants.ProcessExitedError); } return(result); } }
public override ValueNodesProviderResult GetNodes(DbgEvaluationContext context, DbgLanguage language, DbgStackFrame frame, DbgEvaluationOptions evalOptions, DbgValueNodeEvaluationOptions nodeEvalOptions) { if (expressions.Count == 0) { return(new ValueNodesProviderResult(Array.Empty <DbgValueNodeInfo>(), false)); } var infos = new DbgExpressionEvaluationInfo[expressions.Count]; Debug.Assert((evalOptions & DbgEvaluationOptions.NoSideEffects) == 0); for (int i = 0; i < infos.Length; i++) { var info = expressions[i]; // Root nodes in watch window can always func-eval var realEvalOptions = evalOptions & ~DbgEvaluationOptions.NoFuncEval; var realNodeEvalOptions = nodeEvalOptions & ~DbgValueNodeEvaluationOptions.NoFuncEval; if (info.ForceEval) { realEvalOptions = evalOptions & ~DbgEvaluationOptions.NoSideEffects; } else { realEvalOptions = evalOptions | DbgEvaluationOptions.NoSideEffects; } Debug.Assert(((realEvalOptions & DbgEvaluationOptions.NoFuncEval) != 0) == ((realNodeEvalOptions & DbgValueNodeEvaluationOptions.NoFuncEval) != 0)); info.ForceEval = false; if (info.ExpressionEvaluatorState == null) { info.ExpressionEvaluatorState = language.ExpressionEvaluator.CreateExpressionEvaluatorState(); } infos[i] = new DbgExpressionEvaluationInfo(info.Expression, realNodeEvalOptions, realEvalOptions, info.ExpressionEvaluatorState); } var compRes = language.ValueNodeFactory.Create(context, frame, infos); Debug.Assert(compRes.Length == infos.Length); var res = new DbgValueNodeInfo[compRes.Length]; for (int i = 0; i < res.Length; i++) { var info = compRes[i]; if (info.ValueNode.Expression != expressions[i].Expression) { throw new InvalidOperationException(); } res[i] = new DbgValueNodeInfo(info.ValueNode, expressions[i].Id, info.CausesSideEffects); } return(new ValueNodesProviderResult(res, false)); }
public abstract DbgDotNetValueResult Execute(DbgEvaluationContext context, DbgStackFrame frame, DbgDotNetILInterpreterState state, string typeName, string methodName, DbgEvaluationOptions options, out DmdType expectedType, CancellationToken cancellationToken);
/// <summary> /// Gets all nodes /// </summary> /// <param name="evalOptions">Evaluation options</param> /// <param name="nodeEvalOptions">Value node evaluation options</param> /// <param name="nameFormatterOptions">Name formatter options</param> /// <returns></returns> public abstract GetNodesResult GetNodes(DbgEvaluationOptions evalOptions, DbgValueNodeEvaluationOptions nodeEvalOptions, DbgValueFormatterOptions nameFormatterOptions);
DbgDotNetCompilationResult CompileExpressionCore(DbgDotNetAlias[] aliases, string expression, DbgEvaluationOptions options, CSharpEvalContextState state, ImmutableArray <MetadataBlock> metadataBlocks, EvaluationContext evalCtx, CancellationToken cancellationToken) { state.MetadataContext = new CSharpMetadataContext(metadataBlocks, evalCtx); var compilationFlags = DkmEvaluationFlags.None; if ((options & DbgEvaluationOptions.Expression) != 0) { compilationFlags |= DkmEvaluationFlags.TreatAsExpression; } var compileResult = evalCtx.CompileExpression(expression, compilationFlags, CreateAliases(aliases), out var resultProperties, out var errorMessage); DbgDotNetText name; if ((options & DbgEvaluationOptions.NoName) != 0) { name = DbgDotNetText.Empty; } else if (compileResult == null || errorMessage != null) { name = CreateErrorName(expression); } else { name = GetExpressionText(state.MetadataContext.EvaluationContext, state.MetadataContext.Compilation, expression, cancellationToken); } return(CreateCompilationResult(expression, compileResult, resultProperties, errorMessage, name)); }
public override DbgEngineValueNodeAssignmentResult Assign(DbgEvaluationContext context, DbgStackFrame frame, string expression, DbgEvaluationOptions options, CancellationToken cancellationToken) => new DbgEngineValueNodeAssignmentResult(DbgEEAssignmentResultFlags.None, NullDbgEngineExpressionEvaluator.ERROR);
public override DbgDotNetCompilationResult CompileGetLocals(DbgEvaluationContext context, DbgStackFrame frame, DbgModuleReference[] references, DbgEvaluationOptions options, CancellationToken cancellationToken) { GetCompilationState <CSharpEvalContextState>(context, frame, references, out var langDebugInfo, out var method, out var methodToken, out var localVarSigTok, out var state, out var metadataBlocks, out var methodVersion); var getMethodDebugInfo = CreateGetMethodDebugInfo(state, langDebugInfo); var evalCtx = EvaluationContext.CreateMethodContext(state.MetadataContext, metadataBlocks, getMethodDebugInfo, method.Module.Mvid ?? Guid.Empty, methodToken, methodVersion, langDebugInfo.ILOffset, localVarSigTok); state.MetadataContext = new CSharpMetadataContext(metadataBlocks, evalCtx); var asmBytes = evalCtx.CompileGetLocals(false, ImmutableArray <Alias> .Empty, out var localsInfo, out var typeName, out var errorMessage); var res = CreateCompilationResult(state, asmBytes, typeName, localsInfo, errorMessage); if (!res.IsError) { return(res); } return(CompileGetLocals(state, method)); }
public override DbgEngineEvaluationResult Evaluate(DbgEvaluationContext context, DbgStackFrame frame, string expression, DbgEvaluationOptions options, object state, CancellationToken cancellationToken) => new DbgEngineEvaluationResult(ERROR);
/// <summary> /// Compiles an assignment /// </summary> /// <param name="context">Evaluation context</param> /// <param name="frame">Frame</param> /// <param name="references">.NET module references</param> /// <param name="aliases">Aliases</param> /// <param name="target">Target expression (lhs)</param> /// <param name="expression">Expression (rhs)</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public abstract DbgDotNetCompilationResult CompileAssignment(DbgEvaluationContext context, DbgStackFrame frame, DbgModuleReference[] references, DbgDotNetAlias[] aliases, string target, string expression, DbgEvaluationOptions options, CancellationToken cancellationToken);
public override DbgEngineEEAssignmentResult Assign(DbgEvaluationContext context, DbgStackFrame frame, string expression, string valueExpression, DbgEvaluationOptions options, CancellationToken cancellationToken) => new DbgEngineEEAssignmentResult(DbgEEAssignmentResultFlags.CompilerError, ERROR);
public override DbgEEAssignmentResult Assign(DbgEvaluationInfo evalInfo, string expression, string valueExpression, DbgEvaluationOptions options) { if (evalInfo == null) { throw new ArgumentNullException(nameof(evalInfo)); } if (!(evalInfo.Context is DbgEvaluationContextImpl)) { throw new ArgumentException(); } if (evalInfo.Context.Language != Language) { throw new ArgumentException(); } if (evalInfo.Context.Runtime.RuntimeKindGuid != runtimeKindGuid) { throw new ArgumentException(); } if (expression == null) { throw new ArgumentNullException(nameof(expression)); } if (valueExpression == null) { throw new ArgumentNullException(nameof(valueExpression)); } var result = engineExpressionEvaluator.Assign(evalInfo, expression, valueExpression, options); return(CreateResult(result)); }
public override DbgEngineValueNodeAssignmentResult Assign(DbgEvaluationInfo evalInfo, string expression, DbgEvaluationOptions options) { var dispatcher = evalInfo.Runtime.GetDotNetRuntime().Dispatcher; if (dispatcher.CheckAccess()) { return(AssignCore(evalInfo, expression, options)); } return(Assign(dispatcher, evalInfo, expression, options)); DbgEngineValueNodeAssignmentResult Assign(DbgDotNetDispatcher dispatcher2, DbgEvaluationInfo evalInfo2, string expression2, DbgEvaluationOptions options2) => dispatcher2.InvokeRethrow(() => AssignCore(evalInfo2, expression2, options2)); }