//TODO: If decompiler settings change, we need to invalidate the cached data in DbgEvaluationContext, see decompiler.Settings.VersionChanged
        DbgLanguageDebugInfo?GetOrCreateDebugInfo(DbgEvaluationContext context, RuntimeState state, IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            DbgLanguageDebugInfoKey key;

            if (location.DbgModule is DbgModule dbgModule)
            {
                key = new DbgLanguageDebugInfoKey(dbgModule, location.Token);
            }
            else
            {
                key = new DbgLanguageDebugInfoKey(location.Module, location.Token);
            }

            var debugInfos = state.DebugInfos;

            lock (state.LockObj) {
                if (debugInfos.Count > 0 && debugInfos[0].debugInfo.MethodDebugInfo.DebugInfoVersion != decompiler.Settings.Version)
                {
                    debugInfos.Clear();
                }
                for (int i = debugInfos.Count - 1; i >= 0; i--)
                {
                    var info = debugInfos[i];
                    if (info.key.Equals(key))
                    {
                        if (i != debugInfos.Count - 1)
                        {
                            debugInfos.RemoveAt(i);
                            debugInfos.Add(info);
                        }
                        return(info.debugInfo);
                    }
                }
            }

            var debugInfo = CreateDebugInfo(context, location, cancellationToken);

            if (debugInfo is null)
            {
                return(null);
            }
            lock (state.LockObj) {
                if (debugInfos.Count == RuntimeState.MAX_CACHED_DEBUG_INFOS)
                {
                    debugInfos.RemoveAt(0);
                }
                debugInfos.Add((key, debugInfo));
            }
            return(debugInfo);
        }
Beispiel #2
0
 public void Clear(DbgDotNetValue returnValue)
 {
     context           = null;
     frame             = null;
     cancellationToken = default;
     foreach (var v in valuesToDispose)
     {
         if (v != returnValue)
         {
             v.Dispose();
         }
     }
     valuesToDispose.Clear();
 }
Beispiel #3
0
 public override void Initialize(DbgEvaluationContext context, DbgStackFrame frame, DmdMethodBody realMethodBody, VariablesProvider argumentsProvider, VariablesProvider localsProvider, bool canFuncEval, CancellationToken cancellationToken)
 {
     Debug.Assert(this.context == null);
     if (this.context != null)
     {
         throw new InvalidOperationException();
     }
     this.context           = context;
     this.frame             = frame;
     this.cancellationToken = cancellationToken;
     this.canFuncEval       = canFuncEval;
     this.argumentsProvider = argumentsProvider ?? DefaultArgumentsProvider;
     interpreterLocalsProvider.Initialize(realMethodBody, localsProvider ?? DefaultLocalsProvider);
     Debug.Assert(valuesToDispose.Count == 0);
 }
Beispiel #4
0
        protected void GetTypeCompilationState <T>(DbgEvaluationContext context, DbgStackFrame frame, DbgModuleReference[] references, out T state, out ImmutableArray <MetadataBlock> metadataBlocks) where T : EvalContextState, new()
        {
            state = GetEvalContextState <T>(frame);

            if (state.LastModuleReferences == references && !state.LastMetadataBlocks.IsDefault)
            {
                metadataBlocks = state.LastMetadataBlocks;
            }
            else
            {
                metadataBlocks             = CreateMetadataBlock(references);
                state.LastModuleReferences = references;
                state.LastMetadataBlocks   = metadataBlocks;
            }
        }
Beispiel #5
0
        public override DbgValueNode[] Create(DbgEvaluationContext context, DbgStackFrame frame, DbgObjectId[] objectIds, DbgValueNodeEvaluationOptions options, CancellationToken cancellationToken)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (!(context is DbgEvaluationContextImpl))
            {
                throw new ArgumentException();
            }
            if (context.Language != Language)
            {
                throw new ArgumentException();
            }
            if (context.Runtime.RuntimeKindGuid != runtimeKindGuid)
            {
                throw new ArgumentException();
            }
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }
            if (frame.Runtime.RuntimeKindGuid != runtimeKindGuid)
            {
                throw new ArgumentException();
            }
            if (objectIds == null)
            {
                throw new ArgumentNullException(nameof(objectIds));
            }
            if (objectIds.Length == 0)
            {
                return(Array.Empty <DbgValueNode>());
            }
            var runtime = objectIds[0].Runtime;

            if (runtime.RuntimeKindGuid != runtimeKindGuid)
            {
                throw new ArgumentException();
            }
            var engineObjectIds = new DbgEngineObjectId[objectIds.Length];

            for (int i = 0; i < objectIds.Length; i++)
            {
                engineObjectIds[i] = ((DbgObjectIdImpl)objectIds[i]).EngineObjectId;
            }
            return(CreateResult(runtime, engineValueNodeFactory.Create(context, frame, engineObjectIds, options, cancellationToken), engineObjectIds.Length));
        }
Beispiel #6
0
        public override DbgDotNetValueNode[] GetChildren(DbgEvaluationContext context, DbgStackFrame frame, ulong index, int count, DbgValueNodeEvaluationOptions options, CancellationToken cancellationToken)
        {
            var res = new DbgDotNetValueNode[count];

            try {
                for (int i = 0, j = (int)index; i < count; i++, j++)
                {
                    res[i] = new TypeVariableValueNode(valueNodeFactory, typeVariableInfos[j]);
                }
            }
            catch {
                context.Process.DbgManager.Close(res.Where(a => a != null));
                throw;
            }
            return(res);
        }
        string StoreIndirect_MonoDebug(DbgEvaluationContext context, DbgStackFrame frame, object value, CancellationToken cancellationToken)
        {
            engine.VerifyMonoDebugThread();
            cancellationToken.ThrowIfCancellationRequested();
            if (!Type.IsByRef)
            {
                return(PredefinedEvaluationErrorMessages.InternalDebuggerError);
            }
            var res = engine.CreateMonoValue_MonoDebug(context, frame, value, Type.GetElementType(), cancellationToken);

            if (res.ErrorMessage != null)
            {
                return(res.ErrorMessage);
            }
            return(valueLocation.Store(res.Value));
        }
Beispiel #8
0
        public override void Format(DbgEvaluationContext context, DbgStackFrame frame, IDbgValueNodeFormatParameters options, CultureInfo cultureInfo, CancellationToken cancellationToken)
        {
            var dispatcher = context.Runtime.GetDotNetRuntime().Dispatcher;

            if (dispatcher.CheckAccess())
            {
                FormatCore(context, frame, options, cultureInfo, cancellationToken);
            }
            else
            {
                Format2(dispatcher, context, frame, options, cultureInfo, cancellationToken);
            }

            void Format2(DbgDotNetDispatcher dispatcher2, DbgEvaluationContext context2, DbgStackFrame frame2, IDbgValueNodeFormatParameters options2, CultureInfo cultureInfo2, CancellationToken cancellationToken2) =>
            dispatcher2.InvokeRethrow(() => FormatCore(context2, frame2, options2, cultureInfo2, cancellationToken2));
        }
Beispiel #9
0
		public override void Clear(DbgDotNetValue returnValue) {
			context = null;
			frame = null;
			cancellationToken = default;
			canFuncEval = false;
			foreach (var v in valuesToDispose) {
				if (v != returnValue && argumentsProvider.CanDispose(v) && localsProvider.CanDispose(v))
					v.Dispose();
			}
			valuesToDispose.Clear();
			argumentsProvider.Clear();
			localsProvider.Clear();
			argumentsProvider = null;
			localsProvider = null;
			reflectionAppDomain = null;
		}
Beispiel #10
0
        public override DbgValueNodeInfo[] GetNodes(DbgEvaluationContext context, DbgLanguage language, DbgStackFrame frame, DbgEvaluationOptions evalOptions, DbgValueNodeEvaluationOptions nodeEvalOptions)
        {
            if (expressions.Count == 0)
            {
                return(Array.Empty <DbgValueNodeInfo>());
            }

            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;
                infos[i]       = new DbgExpressionEvaluationInfo(info.Expression, realNodeEvalOptions, realEvalOptions);
            }

            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(res);
        }
        internal DbgDotNetValueResult Box_CorDebug(DbgEvaluationContext context, DbgThread thread, CorAppDomain appDomain, CorValue value, DmdType type, CancellationToken cancellationToken)
        {
            debuggerThread.VerifyAccess();
            cancellationToken.ThrowIfCancellationRequested();
            var tmp = CheckFuncEval(context);

            if (tmp != null)
            {
                return(tmp.Value);
            }

            var      dnThread      = GetThread(thread);
            var      createdValues = new List <CorValue>();
            CorValue boxedValue    = null;

            try {
                using (var dnEval = dnDebugger.CreateEval(cancellationToken, suspendOtherThreads: (context.Options & DbgEvaluationContextOptions.RunAllThreads) == 0)) {
                    dnEval.SetThread(dnThread);
                    dnEval.SetTimeout(context.FuncEvalTimeout);
                    dnEval.EvalEvent += (s, e) => DnEval_EvalEvent(dnEval, context);

                    boxedValue = BoxIfNeeded(dnEval, appDomain, createdValues, value, type.AppDomain.System_Object, type);
                    if (boxedValue == null)
                    {
                        return(new DbgDotNetValueResult(CordbgErrorHelper.GetErrorMessage(-1)));
                    }
                    return(new DbgDotNetValueResult(CreateDotNetValue_CorDebug(boxedValue, type.AppDomain, tryCreateStrongHandle: true), valueIsException: false));
                }
            }
            catch (TimeoutException) {
                return(new DbgDotNetValueResult(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
            }
            catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex))
            {
                return(new DbgDotNetValueResult(CordbgErrorHelper.InternalError));
            }
            finally {
                foreach (var v in createdValues)
                {
                    if (boxedValue != v)
                    {
                        dnDebugger.DisposeHandle(v);
                    }
                }
            }
        }
Beispiel #12
0
        string StoreIndirect_CorDebug(DbgEvaluationContext context, DbgStackFrame frame, object value, CancellationToken cancellationToken)
        {
            engine.VerifyCorDebugThread();
            cancellationToken.ThrowIfCancellationRequested();
            if (!ILDbgEngineStackFrame.TryGetEngineStackFrame(frame, out var ilFrame))
            {
                return(CordbgErrorHelper.InternalError);
            }
            if (!Type.IsByRef)
            {
                return(CordbgErrorHelper.InternalError);
            }
            Func <CreateCorValueResult> createTargetValue = () => {
                var objValue = TryGetCorValue();
                if (objValue == null)
                {
                    return(new CreateCorValueResult(null, -1));
                }
                Debug.Assert(objValue.ElementType == CorElementType.ByRef);
                if (objValue.ElementType == CorElementType.ByRef)
                {
                    var derefencedValue = objValue.DereferencedValue;
                    if (derefencedValue == null)
                    {
                        return(new CreateCorValueResult(null, -1));
                    }
                    if (!derefencedValue.IsReference)
                    {
                        if (derefencedValue.IsGeneric)
                        {
                            return(new CreateCorValueResult(derefencedValue, 0, canDispose: true));
                        }
                        engine.DisposeHandle_CorDebug(derefencedValue);
                        return(new CreateCorValueResult(null, -1));
                    }
                    return(new CreateCorValueResult(derefencedValue, 0, canDispose: true));
                }
                else
                {
                    return(new CreateCorValueResult(null, -1));
                }
            };

            return(engine.StoreValue_CorDebug(context, frame.Thread, ilFrame, createTargetValue, Type.GetElementType(), value, cancellationToken));
        }
        protected override string InitializeCore(DbgEvaluationContext context, DbgStackFrame frame, CancellationToken cancellationToken)
        {
            if ((evalOptions & DbgValueNodeEvaluationOptions.NoFuncEval) != 0)
            {
                return(PredefinedEvaluationErrorMessages.FuncEvalDisabled);
            }

            var proxyCtor = EnumerableDebugViewHelper.GetEnumerableDebugViewConstructor(enumerableType);

            if ((object)proxyCtor == null)
            {
                var loadState = enumerableType.AppDomain.GetOrCreateData <ForceLoadAssemblyState>();
                if (Interlocked.Exchange(ref loadState.Counter, 1) == 0)
                {
                    var loader = new ReflectionAssemblyLoader(context, frame, enumerableType.AppDomain, cancellationToken);
                    if (loader.TryLoadAssembly(GetRequiredAssemblyFullName(context.Runtime)))
                    {
                        proxyCtor = EnumerableDebugViewHelper.GetEnumerableDebugViewConstructor(enumerableType);
                    }
                }
                if ((object)proxyCtor == null)
                {
                    var asmFilename = GetRequiredAssemblyFilename(context.Runtime);
                    var asm         = enumerableType.AppDomain.GetAssembly(Path.GetFileNameWithoutExtension(asmFilename));
                    if (asm == null)
                    {
                        return(string.Format(dnSpy_Roslyn_Shared_Resources.SystemCoreDllNotLoaded, asmFilename));
                    }
                    return(string.Format(dnSpy_Roslyn_Shared_Resources.TypeDoesNotExistInAssembly, EnumerableDebugViewHelper.GetDebugViewTypeDisplayName(enumerableType), asmFilename));
                }
            }

            var runtime         = context.Runtime.GetDotNetRuntime();
            var proxyTypeResult = runtime.CreateInstance(context, frame, proxyCtor, new[] { instanceValue }, DbgDotNetInvokeOptions.None, cancellationToken);

            if (proxyTypeResult.HasError)
            {
                return(proxyTypeResult.ErrorMessage);
            }

            resultsViewProxyExpression = valueNodeProviderFactory.GetNewObjectExpression(proxyCtor, valueExpression);
            getResultsViewValue        = proxyTypeResult.Value;
            valueNodeProviderFactory.GetMemberCollections(getResultsViewValue.Type, evalOptions, out membersCollection, out _);
            return(null);
        }
Beispiel #14
0
        // This method calls ICorDebugEval2.NewParameterizedArray() which doesn't support creating SZ arrays
        // with any element type. See the caller of this method (CreateSZArrayCore) for more info.
        internal DbgDotNetValueResult CreateSZArray_CorDebug(DbgEvaluationContext context, DbgThread thread, CorAppDomain appDomain, DmdType elementType, int length, CancellationToken cancellationToken)
        {
            debuggerThread.VerifyAccess();
            cancellationToken.ThrowIfCancellationRequested();
            var tmp = CheckFuncEval(context);

            if (tmp != null)
            {
                return(tmp.Value);
            }

            var dnThread = GetThread(thread);

            try {
                using (var dnEval = dnDebugger.CreateEval(cancellationToken, suspendOtherThreads: (context.Options & DbgEvaluationContextOptions.RunAllThreads) == 0)) {
                    dnEval.SetThread(dnThread);
                    dnEval.SetTimeout(context.FuncEvalTimeout);
                    dnEval.EvalEvent += (s, e) => DnEval_EvalEvent(dnEval, context);

                    var corType = GetType(appDomain, elementType);
                    var res     = dnEval.CreateSZArray(corType, length, out int hr);
                    if (res == null)
                    {
                        return(new DbgDotNetValueResult(CordbgErrorHelper.GetErrorMessage(hr)));
                    }
                    Debug.Assert(!res.Value.WasException, "Shouldn't throw " + nameof(ArgumentOutOfRangeException));
                    if (res.Value.WasCustomNotification)
                    {
                        return(new DbgDotNetValueResult(CordbgErrorHelper.FuncEvalRequiresAllThreadsToRun));
                    }
                    if (res.Value.WasCancelled)
                    {
                        return(new DbgDotNetValueResult(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
                    }
                    return(new DbgDotNetValueResult(CreateDotNetValue_CorDebug(res.Value.ResultOrException, elementType.AppDomain, tryCreateStrongHandle: true), valueIsException: res.Value.WasException));
                }
            }
            catch (TimeoutException) {
                return(new DbgDotNetValueResult(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
            }
            catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex))
            {
                return(new DbgDotNetValueResult(CordbgErrorHelper.InternalError));
            }
        }
        public override DbgDotNetCompilationResult CompileGetLocals(DbgEvaluationContext context, DbgStackFrame frame, DbgModuleReference[] references, DbgEvaluationOptions options, CancellationToken cancellationToken)
        {
            GetCompilationState <VisualBasicEvalContextState>(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, null, getMethodDebugInfo, method.Module.Mvid ?? Guid.Empty, methodToken, methodVersion, langDebugInfo.ILOffset, localVarSigTok);

            state.MetadataContext = new VisualBasicMetadataContext(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));
        }
Beispiel #16
0
 public void Clear(DbgDotNetValue returnValue)
 {
     context           = null;
     frame             = null;
     cancellationToken = default;
     foreach (var v in valuesToDispose)
     {
         if (v != returnValue && argumentsProvider.CanDispose(v) && localsProvider.CanDispose(v))
         {
             v.Dispose();
         }
     }
     valuesToDispose.Clear();
     argumentsProvider.Clear();
     localsProvider.Clear();
     argumentsProvider = null;
     localsProvider    = null;
 }
Beispiel #17
0
 public override DbgValueNodeAssignmentResult Assign(DbgEvaluationContext context, DbgStackFrame frame, string expression, DbgEvaluationOptions options, CancellationToken cancellationToken)
 {
     if (context == null)
     {
         throw new ArgumentNullException(nameof(context));
     }
     if (!(context is DbgEvaluationContextImpl))
     {
         throw new ArgumentException();
     }
     if (context.Language != Language)
     {
         throw new ArgumentException();
     }
     if (context.Runtime != Runtime)
     {
         throw new ArgumentException();
     }
     if (frame == null)
     {
         throw new ArgumentNullException(nameof(frame));
     }
     if (!(frame is DbgStackFrameImpl))
     {
         throw new ArgumentException();
     }
     if (frame.Runtime != Runtime)
     {
         throw new ArgumentException();
     }
     if (expression == null)
     {
         throw new ArgumentNullException(nameof(expression));
     }
     if (IsReadOnly)
     {
         throw new InvalidOperationException();
     }
     if (engineValueNode.ErrorMessage != null)
     {
         throw new NotSupportedException();
     }
     return(CreateResult(engineValueNode.Assign(context, frame, expression, options, cancellationToken)));
 }
Beispiel #18
0
 public override void Format(DbgEvaluationContext context, DbgStackFrame frame, ITextColorWriter output, DbgValue value, DbgValueFormatterOptions options, CultureInfo cultureInfo, CancellationToken cancellationToken)
 {
     if (context == null)
     {
         throw new ArgumentNullException(nameof(context));
     }
     if (!(context is DbgEvaluationContextImpl))
     {
         throw new ArgumentException();
     }
     if (context.Language != Language)
     {
         throw new ArgumentException();
     }
     if (context.Runtime.RuntimeKindGuid != runtimeKindGuid)
     {
         throw new ArgumentException();
     }
     if (frame == null)
     {
         throw new ArgumentNullException(nameof(frame));
     }
     if (frame.Runtime.RuntimeKindGuid != runtimeKindGuid)
     {
         throw new ArgumentException();
     }
     if (output == null)
     {
         throw new ArgumentNullException(nameof(output));
     }
     if (value == null)
     {
         throw new ArgumentNullException(nameof(value));
     }
     if (!(value is DbgValueImpl valueImpl))
     {
         throw new ArgumentException();
     }
     if (value.Runtime.RuntimeKindGuid != runtimeKindGuid)
     {
         throw new ArgumentException();
     }
     engineValueFormatter.Format(context, frame, output, valueImpl.EngineValue, options, cultureInfo, cancellationToken);
 }
        public override DbgValueNodeInfo[] GetNodes(DbgEvaluationContext context, DbgLanguage language, DbgStackFrame frame, DbgEvaluationOptions evalOptions, DbgValueNodeEvaluationOptions nodeEvalOptions)
        {
            var returnValues = language.ReturnValuesProvider.GetNodes(context, frame, nodeEvalOptions);
            var variables    = language.AutosProvider.GetNodes(context, frame, 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);
            }

            return(res);
        }
Beispiel #20
0
        DbgLanguageDebugInfo?CreateDebugInfo(DbgEvaluationContext context, IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            var result = dbgMethodDebugInfoProvider.GetMethodDebugInfo(context.Runtime, decompiler, location, cancellationToken);

            if (result.DebugInfo is null)
            {
                return(null);
            }

            var runtime = context.Runtime.GetDotNetRuntime();

            if (location.DbgModule is null || !runtime.TryGetMethodToken(location.DbgModule, (int)location.Token, out int methodToken, out int localVarSigTok))
            {
                methodToken    = (int)location.Token;
                localVarSigTok = (int)((result.StateMachineDebugInfo ?? result.DebugInfo)?.Method.Body?.LocalVarSigTok ?? 0);
            }

            return(new DbgLanguageDebugInfo(result.DebugInfo, methodToken, localVarSigTok, result.MethodVersion, location.Offset));
        }
        public override void InitializeContext(DbgEvaluationContext context, DbgCodeLocation location, CancellationToken cancellationToken)
        {
            Debug.Assert(context.Runtime.GetDotNetRuntime() != null);

            IDebuggerDisplayAttributeEvaluatorUtils.Initialize(context, debuggerDisplayAttributeEvaluator);
            // Needed by DebuggerRuntimeImpl (calls expressionCompiler.TryGetAliasInfo())
            context.GetOrCreateData(() => expressionCompiler);

            if ((context.Options & DbgEvaluationContextOptions.NoMethodBody) == 0 && location is IDbgDotNetCodeLocation loc)
            {
                var state = StateWithKey <RuntimeState> .GetOrCreate(context.Runtime, decompiler);

                var debugInfo = GetOrCreateDebugInfo(context, state, loc, cancellationToken);
                if (debugInfo != null)
                {
                    DbgLanguageDebugInfoExtensions.SetLanguageDebugInfo(context, debugInfo);
                }
            }
        }
Beispiel #22
0
 public sealed override void Format(DbgEvaluationContext context, DbgStackFrame frame, IDbgValueNodeFormatParameters options, CultureInfo cultureInfo)
 {
     if (options.NameOutput != null)
     {
         FormatName(context, frame, options.NameOutput, cultureInfo);
     }
     if (options.ValueOutput != null)
     {
         FormatValue(context, frame, options.ValueOutput, options.ValueFormatterOptions, cultureInfo);
     }
     if (options.ExpectedTypeOutput != null)
     {
         WriteTo(options.ExpectedTypeOutput, CachedExpectedType);
     }
     if (options.ActualTypeOutput != null)
     {
         WriteTo(options.ActualTypeOutput, CachedActualType);
     }
 }
Beispiel #23
0
        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 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, method.MDToken.ToInt32(), methodVersion, langDebugInfo.ILOffset, localVarSigTok);

            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);

            return(CreateCompilationResult(expression, compileResult, resultProperties, errorMessage, GetExpressionText(expression)));
        }
Beispiel #24
0
        DbgDotNetValue Box_CorDebug(DbgEvaluationContext context, DbgStackFrame frame, CancellationToken cancellationToken)
        {
            engine.VerifyCorDebugThread();
            cancellationToken.ThrowIfCancellationRequested();
            var corValue = TryGetCorValue();

            if (corValue == null)
            {
                return(null);
            }
            if (!ILDbgEngineStackFrame.TryGetEngineStackFrame(frame, out var ilFrame))
            {
                return(null);
            }
            // Even if it's boxed, box the unboxed value. This code path should only be called if
            // the compiler thinks it's an unboxed value, so we must make a new boxed value.
            if (corValue.IsReference)
            {
                corValue = corValue.DereferencedValue;
                if (corValue == null)
                {
                    return(null);
                }
            }
            if (corValue.IsBox)
            {
                corValue = corValue.BoxedValue;
                if (corValue == null)
                {
                    return(null);
                }
            }
            var res = engine.Box_CorDebug(context, frame.Thread, ilFrame.GetCorAppDomain(), corValue, Type, cancellationToken);

            if (res.IsNormalResult)
            {
                return(res.Value);
            }
            res.Value?.Dispose();
            return(null);
        }
        DbgEngineEEAssignmentResult AssignCore(DbgEvaluationContext context, DbgStackFrame frame, string expression, string valueExpression, DbgEvaluationOptions options, CancellationToken cancellationToken)
        {
            var resultFlags = DbgEEAssignmentResultFlags.None;

            try {
                var refsResult = dbgModuleReferenceProvider.GetModuleReferences(context.Runtime, frame);
                if (refsResult.ErrorMessage != null)
                {
                    return(new DbgEngineEEAssignmentResult(resultFlags, refsResult.ErrorMessage));
                }

                var aliases = GetAliases(context, frame, cancellationToken);
                var compRes = expressionCompiler.CompileAssignment(context, frame, refsResult.ModuleReferences, aliases, expression, valueExpression, options, cancellationToken);
                cancellationToken.ThrowIfCancellationRequested();
                if (compRes.IsError)
                {
                    return(new DbgEngineEEAssignmentResult(resultFlags | DbgEEAssignmentResultFlags.CompilerError, compRes.ErrorMessage));
                }

                var     state    = dnILInterpreter.CreateState(compRes.Assembly);
                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(context, frame, state, exprInfo.TypeName, exprInfo.MethodName, options, out _, cancellationToken);
                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());
            }
 internal DbgDotNetValueResult?CheckFuncEval(DbgEvaluationContext context)
 {
     debuggerThread.VerifyAccess();
     if (!IsPaused)
     {
         return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.CanFuncEvalOnlyWhenPaused));
     }
     if (isUnhandledException)
     {
         return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.CantFuncEvalWhenUnhandledExceptionHasOccurred));
     }
     if (context.ContinueContext.HasData <EvalTimedOut>())
     {
         return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOutNowDisabled));
     }
     if (IsEvaluating)
     {
         return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.CantFuncEval));
     }
     return(null);
 }
Beispiel #27
0
        public override void InitializeContext(DbgEvaluationContext context, DbgCodeLocation location, CancellationToken cancellationToken)
        {
            Debug.Assert(context.Runtime.GetDotNetRuntime() != null);
            var loc = location as IDbgDotNetCodeLocation;

            if (loc == null)
            {
                // Could be a special frame, eg. managed to native frame
                return;
            }

            var state = StateWithKey <RuntimeState> .GetOrCreate(context.Runtime, decompiler);

            var debugInfo = GetOrCreateDebugInfo(state, loc, cancellationToken);

            if (debugInfo == null)
            {
                return;
            }
            DbgLanguageDebugInfoExtensions.SetLanguageDebugInfo(context, debugInfo);
        }
Beispiel #28
0
        protected void GetCompilationState <T>(DbgEvaluationContext context, DbgStackFrame frame, DbgModuleReference[] references, out DbgLanguageDebugInfo langDebugInfo, out MethodDef method, out int localVarSigTok, out T state, out ImmutableArray <MetadataBlock> metadataBlocks, out int methodVersion) where T : EvalContextState, new()
        {
            langDebugInfo  = context.GetLanguageDebugInfo();
            method         = langDebugInfo.MethodDebugInfo.Method;
            localVarSigTok = (int)(method.Body?.LocalVarSigTok ?? 0);

            state = GetEvalContextState <T>(frame);

            if (state.LastModuleReferences == references && !state.LastMetadataBlocks.IsDefault)
            {
                metadataBlocks = state.LastMetadataBlocks;
            }
            else
            {
                metadataBlocks             = CreateMetadataBlock(references);
                state.LastModuleReferences = references;
                state.LastMetadataBlocks   = metadataBlocks;
            }

            methodVersion = langDebugInfo.MethodVersion;
        }
        DbgLanguageDebugInfo CreateDebugInfo(DbgEvaluationContext context, IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            var result = dbgMethodDebugInfoProvider.GetMethodDebugInfo(context.Runtime, decompiler, location, cancellationToken);

            if (result.DebugInfoOrNull == null)
            {
                return(null);
            }

            var runtime = context.Runtime.GetDotNetRuntime();

            if (location.DbgModule == null || !runtime.TryGetMethodToken(location.DbgModule, (int)location.Token, out int methodToken, out int localVarSigTok))
            {
                methodToken    = (int)location.Token;
                localVarSigTok = (int)result.LocalVarSigTok;
            }

            // We don't support EnC so the version is always 1
            const int methodVersion = 1;

            return(new DbgLanguageDebugInfo(result.DebugInfoOrNull, methodToken, localVarSigTok, methodVersion, location.Offset));
        }
        protected override string InitializeCore(DbgEvaluationContext context, DbgStackFrame frame, CancellationToken cancellationToken)
        {
            if ((evalOptions & DbgValueNodeEvaluationOptions.NoFuncEval) != 0)
            {
                return(PredefinedEvaluationErrorMessages.FuncEvalDisabled);
            }

            var proxyCtor = EnumerableDebugViewHelper.GetEnumerableDebugViewConstructor(enumerableType);

            if ((object)proxyCtor == null)
            {
                var loadState = enumerableType.AppDomain.GetOrCreateData <ForceLoadAssemblyState>();
                if (Interlocked.Increment(ref loadState.Counter) == 1)
                {
                    var loader = new ReflectionAssemblyLoader(context, frame, enumerableType.AppDomain, cancellationToken);
                    if (loader.TryLoadAssembly(GetRequiredAssemblyFullName(context.Runtime)))
                    {
                        proxyCtor = EnumerableDebugViewHelper.GetEnumerableDebugViewConstructor(enumerableType);
                    }
                }
                if ((object)proxyCtor == null)
                {
                    return(string.Format(dnSpy_Roslyn_Shared_Resources.SystemCoreDllNotLoaded, GetRequiredAssemblyFileName(context.Runtime)));
                }
            }

            var runtime         = context.Runtime.GetDotNetRuntime();
            var proxyTypeResult = runtime.CreateInstance(context, frame, proxyCtor, new[] { instanceValue }, cancellationToken);

            if (proxyTypeResult.HasError)
            {
                return(proxyTypeResult.ErrorMessage);
            }

            getResultsViewValue = proxyTypeResult.Value;
            valueNodeProviderFactory.GetMemberCollections(getResultsViewValue.Type, evalOptions, out membersCollection, out _);
            return(null);
        }