Пример #1
0
 public DbgEngineValueNode CreateValueNode(ref DbgDotNetILInterpreterState?ilInterpreterState, ref DbgDotNetCompiledExpressionResult compExprInfo)
 {
     if (compExprInfo.ErrorMessage is not null)
     {
         return(valueNodeFactory.CreateError(evalInfo, compExprInfo.Name, compExprInfo.ErrorMessage, compExprInfo.Expression, (compExprInfo.Flags & DbgEvaluationResultFlags.SideEffects) != 0));
     }
     else
     {
         if (ilInterpreterState is null)
         {
             ilInterpreterState = dnILInterpreter.CreateState(assemblyBytes);
         }
         var res = dnILInterpreter.Execute(evalInfo, ilInterpreterState, compExprInfo.TypeName, compExprInfo.MethodName, options, out var expectedType);
         try {
             if (res.ErrorMessage is not null)
             {
                 return(valueNodeFactory.CreateError(evalInfo, compExprInfo.Name, res.ErrorMessage, compExprInfo.Expression, (compExprInfo.Flags & DbgEvaluationResultFlags.SideEffects) != 0));
             }
             //TODO: Pass in compExprInfo.CustomTypeInfo, or attach it to the DbgDotNetValueNode
             return(valueNodeFactory.Create(evalInfo, compExprInfo.Name, res.Value !, compExprInfo.FormatSpecifiers, nodeOptions, compExprInfo.Expression, compExprInfo.ImageName, (compExprInfo.Flags & DbgEvaluationResultFlags.ReadOnly) != 0, (compExprInfo.Flags & DbgEvaluationResultFlags.SideEffects) != 0, expectedType));
         }
         catch {
             res.Value?.Dispose();
             throw;
         }
     }
 }
Пример #2
0
        DbgEngineValueNode[] CreateCore(DbgEvaluationContext context, DbgStackFrame frame, DbgExpressionEvaluationInfo[] expressions, CancellationToken cancellationToken)
        {
            var res = expressions.Length == 0 ? Array.Empty <DbgEngineValueNode>() : new DbgEngineValueNode[expressions.Length];

            try {
                for (int i = 0; i < res.Length; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    ref var            info              = ref expressions[i];
                    var                evalRes           = expressionEvaluator.EvaluateImpl(context, frame, info.Expression, info.Options, info.ExpressionEvaluatorState, cancellationToken);
                    bool               causesSideEffects = (evalRes.Flags & DbgEvaluationResultFlags.SideEffects) != 0;
                    DbgEngineValueNode newNode;
                    if (evalRes.Error != null)
                    {
                        newNode = valueNodeFactory.CreateError(context, frame, evalRes.Name, evalRes.Error, info.Expression, causesSideEffects, cancellationToken);
                    }
                    else
                    {
                        bool isReadOnly = (evalRes.Flags & DbgEvaluationResultFlags.ReadOnly) != 0;
                        newNode = valueNodeFactory.Create(context, frame, evalRes.Name, evalRes.Value, info.NodeOptions, info.Expression, evalRes.ImageName, isReadOnly, causesSideEffects, evalRes.Type, cancellationToken);
                    }
                    res[i] = newNode;
                }
            }
 public static DbgEngineValueNode[] CreateInternalErrorResult(this DbgDotNetEngineValueNodeFactory valueNodeFactory, DbgEvaluationInfo evalInfo)
 {
     return(new DbgEngineValueNode[] {
         valueNodeFactory.CreateError(evalInfo, errorName, PredefinedEvaluationErrorMessages.InternalDebuggerError, "<expression>", false),
     });
 }
Пример #4
0
        DbgEngineLocalsValueNodeInfo[] GetNodesCore(DbgEvaluationContext context, DbgStackFrame frame, DbgValueNodeEvaluationOptions options, DbgLocalsValueNodeEvaluationOptions localsOptions, CancellationToken cancellationToken)
        {
            DbgEngineLocalsValueNodeInfo[] valueNodes = null;
            try {
                var refsResult = dbgModuleReferenceProvider.GetModuleReferences(context.Runtime, frame);
                if (refsResult.ErrorMessage != null)
                {
                    return(Array.Empty <DbgEngineLocalsValueNodeInfo>());
                }

                var languageDebugInfo = context.TryGetLanguageDebugInfo();
                if (languageDebugInfo == null)
                {
                    return(Array.Empty <DbgEngineLocalsValueNodeInfo>());
                }
                var methodDebugInfo = languageDebugInfo.MethodDebugInfo;
                var module          = frame.Module ?? throw new InvalidOperationException();

                // Since we attach this to the module, the module doesn't have to be part of Key
                var state = StateWithKey <GetNodesState> .GetOrCreate(module, this);

                var localsOptionsKey = localsOptions & ~(DbgLocalsValueNodeEvaluationOptions.ShowCompilerGeneratedVariables | DbgLocalsValueNodeEvaluationOptions.ShowDecompilerGeneratedVariables);
                var key = new GetNodesState.Key(methodDebugInfo.DecompilerOptionsVersion,
                                                methodDebugInfo.Method.MDToken.ToInt32(), languageDebugInfo.MethodVersion,
                                                refsResult.ModuleReferences, MethodDebugScopeUtils.GetScope(methodDebugInfo.Scope, languageDebugInfo.ILOffset),
                                                options, localsOptionsKey);

                var evalOptions = DbgEvaluationOptions.None;
                if ((options & DbgValueNodeEvaluationOptions.NoFuncEval) != 0)
                {
                    evalOptions |= DbgEvaluationOptions.NoFuncEval;
                }

                ValueInfo[] valueInfos;
                byte[]      assemblyBytes;
                int         compilerGeneratedCount;
                int         decompilerGeneratedCount;
                if (key.Equals(state.CachedKey))
                {
                    valueInfos               = state.CachedValueInfos;
                    assemblyBytes            = state.CachedAssemblyBytes;
                    decompilerGeneratedCount = state.CachedDecompilerGeneratedCount;
                    compilerGeneratedCount   = state.CachedCompilerGeneratedCount;
                }
                else
                {
                    var compilationResult = expressionCompiler.CompileGetLocals(context, frame, refsResult.ModuleReferences, evalOptions, cancellationToken);
                    cancellationToken.ThrowIfCancellationRequested();
                    if (compilationResult.IsError)
                    {
                        return new[] { CreateInternalErrorNode(context, frame, compilationResult.ErrorMessage, cancellationToken) }
                    }
                    ;

                    decompilerGeneratedCount = GetDecompilerGeneratedVariablesCount(methodDebugInfo.Scope, languageDebugInfo.ILOffset);

                    valueInfos = new ValueInfo[compilationResult.CompiledExpressions.Length + decompilerGeneratedCount];
                    int valueInfosIndex = 0;
                    compilerGeneratedCount = 0;
                    for (int i = 0; i < compilationResult.CompiledExpressions.Length; i++, valueInfosIndex++)
                    {
                        if ((compilationResult.CompiledExpressions[i].ResultFlags & DbgDotNetCompiledExpressionResultFlags.CompilerGenerated) != 0)
                        {
                            compilerGeneratedCount++;
                        }
                        valueInfos[valueInfosIndex] = new CompiledExpressionValueInfo(compilationResult.CompiledExpressions, i);
                    }

                    if (decompilerGeneratedCount > 0)
                    {
                        var scope = methodDebugInfo.Scope;
                        for (;;)
                        {
                            foreach (var local in scope.Locals)
                            {
                                if (local.IsDecompilerGenerated)
                                {
                                    valueInfos[valueInfosIndex] = new DecompilerGeneratedVariableValueInfo(local.Name);
                                    valueInfosIndex++;
                                }
                            }

                            bool found = false;
                            foreach (var childScope in scope.Scopes)
                            {
                                if (childScope.Span.Start <= languageDebugInfo.ILOffset && languageDebugInfo.ILOffset < childScope.Span.End)
                                {
                                    found = true;
                                    scope = childScope;
                                    break;
                                }
                            }
                            if (!found)
                            {
                                break;
                            }
                        }
                    }

                    if (valueInfos.Length != valueInfosIndex)
                    {
                        throw new InvalidOperationException();
                    }

                    assemblyBytes                        = compilationResult.Assembly;
                    state.CachedKey                      = key;
                    state.CachedValueInfos               = valueInfos;
                    state.CachedAssemblyBytes            = assemblyBytes;
                    state.CachedILInterpreterState       = null;
                    state.CachedDecompilerGeneratedCount = decompilerGeneratedCount;
                    state.CachedCompilerGeneratedCount   = compilerGeneratedCount;
                }

                int count = valueInfos.Length;
                if ((localsOptions & DbgLocalsValueNodeEvaluationOptions.ShowCompilerGeneratedVariables) == 0)
                {
                    count -= compilerGeneratedCount;
                }
                if ((localsOptions & DbgLocalsValueNodeEvaluationOptions.ShowDecompilerGeneratedVariables) == 0)
                {
                    count -= decompilerGeneratedCount;
                }
                valueNodes = count == 0 ? Array.Empty <DbgEngineLocalsValueNodeInfo>() : new DbgEngineLocalsValueNodeInfo[count];
                var valueCreator = new DbgDotNetValueCreator(valueNodeFactory, dnILInterpreter, context, frame, options, evalOptions, assemblyBytes, cancellationToken);
                int w            = 0;
                for (int i = 0; i < valueInfos.Length; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    var valueInfo = valueInfos[i];

                    DbgEngineLocalsValueNodeInfo valueNodeInfo;
                    switch (valueInfo.Kind)
                    {
                    case ValueInfoKind.CompiledExpression:
                        var compExpr = (CompiledExpressionValueInfo)valueInfo;
                        if ((localsOptions & DbgLocalsValueNodeEvaluationOptions.ShowCompilerGeneratedVariables) == 0 && compExpr.IsCompilerGenerated)
                        {
                            continue;
                        }
                        valueNodeInfo = new DbgEngineLocalsValueNodeInfo(
                            compExpr.IsParameter ? DbgLocalsValueNodeKind.Parameter : DbgLocalsValueNodeKind.Local,
                            valueCreator.CreateValueNode(ref state.CachedILInterpreterState, ref compExpr.CompiledExpressionResult));
                        break;

                    case ValueInfoKind.DecompilerGeneratedVariable:
                        if ((localsOptions & DbgLocalsValueNodeEvaluationOptions.ShowDecompilerGeneratedVariables) == 0)
                        {
                            continue;
                        }
                        var decGen = (DecompilerGeneratedVariableValueInfo)valueInfo;
                        valueNodeInfo = new DbgEngineLocalsValueNodeInfo(DbgLocalsValueNodeKind.Local,
                                                                         valueNodeFactory.CreateError(context, frame,
                                                                                                      new DbgDotNetText(new DbgDotNetTextPart(BoxedTextColor.Local, decGen.Name)),
                                                                                                      dnSpy_Debugger_DotNet_Resources.DecompilerGeneratedVariablesCanNotBeEvaluated,
                                                                                                      decGen.Name, false, cancellationToken));
                        break;

                    default:
                        throw new InvalidOperationException();
                    }

                    valueNodes[w++] = valueNodeInfo;
                }
                if (w != valueNodes.Length)
                {
                    throw new InvalidOperationException();
                }

                return(valueNodes);
            }
            catch (Exception ex) {
                if (valueNodes != null)
                {
                    frame.Process.DbgManager.Close(valueNodes.Select(a => a.ValueNode).Where(a => a != null));
                }
                if (!ExceptionUtils.IsInternalDebuggerError(ex))
                {
                    throw;
                }
                return(new[] { CreateInternalErrorNode(context, frame, PredefinedEvaluationErrorMessages.InternalDebuggerError, cancellationToken) });
            }
        }
Пример #5
0
 public DbgEngineValueNode CreateValueNode(ref DbgDotNetILInterpreterState?ilInterpreterState, ref DbgDotNetCompiledExpressionResult compExprInfo)
 {
     if (!(compExprInfo.ErrorMessage is null))
     {
         return(valueNodeFactory.CreateError(evalInfo, compExprInfo.Name, compExprInfo.ErrorMessage, compExprInfo.Expression, (compExprInfo.Flags & DbgEvaluationResultFlags.SideEffects) != 0));
     }
 public static DbgEngineValueNode[] CreateInternalErrorResult(this DbgDotNetEngineValueNodeFactory valueNodeFactory, DbgEvaluationContext context, DbgStackFrame frame, CancellationToken cancellationToken)
 {
     return(new DbgEngineValueNode[] {
         valueNodeFactory.CreateError(context, frame, errorName, PredefinedEvaluationErrorMessages.InternalDebuggerError, "<expression>", false, cancellationToken),
     });
 }