Example #1
0
        DbgDotNetValueResult?Box_CorDebug(DbgEvaluationInfo evalInfo)
        {
            engine.VerifyCorDebugThread();
            evalInfo.CancellationToken.ThrowIfCancellationRequested();
            var corValue = TryGetCorValue();

            if (corValue == null)
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }
            if (!ILDbgEngineStackFrame.TryGetEngineStackFrame(evalInfo.Frame, out var ilFrame))
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }
            // 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.GetDereferencedValue(out int hr);
                if (corValue == null)
                {
                    return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
                }
            }
            if (corValue.IsBox)
            {
                corValue = corValue.GetBoxedValue(out int hr);
                if (corValue == null)
                {
                    return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
                }
            }
            return(engine.Box_CorDebug(evalInfo, ilFrame.GetCorAppDomain(), corValue, Type));
        }
        public static DebugViewNoResultsValueNode TryCreate(DbgEvaluationInfo evalInfo, string expression, DbgDotNetValueResult valueResult)
        {
            DbgDotNetValueResult getterResult = default;

            try {
                if (!valueResult.ValueIsException)
                {
                    return(null);
                }
                var appDomain     = valueResult.Value.Type.AppDomain;
                var emptyProperty = valueResult.Value.Type.GetProperty(EmptyPropertyName, DmdSignatureCallingConvention.HasThis | DmdSignatureCallingConvention.Property, 0, appDomain.System_String, Array.Empty <DmdType>(), throwOnError: false);
                var emptyGetter   = emptyProperty?.GetGetMethod(DmdGetAccessorOptions.All);
                if ((object)emptyGetter == null)
                {
                    return(null);
                }

                var runtime = evalInfo.Runtime.GetDotNetRuntime();
                getterResult = runtime.Call(evalInfo, valueResult.Value, emptyGetter, Array.Empty <object>(), DbgDotNetInvokeOptions.None);
                if (!getterResult.IsNormalResult)
                {
                    return(null);
                }
                var rawValue = getterResult.Value.GetRawValue();
                if (!rawValue.HasRawValue || rawValue.ValueType != DbgSimpleValueType.StringUtf16 || !(rawValue.RawValue is string emptyMessage))
                {
                    return(null);
                }
                return(new DebugViewNoResultsValueNode(expression, emptyMessage));
            }
            finally {
                getterResult.Value?.Dispose();
            }
        }
        internal DbgDotNetValueResult CreateValue_CorDebug(DbgEvaluationInfo evalInfo, ILDbgEngineStackFrame ilFrame, object?value)
        {
            debuggerThread.VerifyAccess();
            evalInfo.CancellationToken.ThrowIfCancellationRequested();
            if (value is DbgDotNetValueImpl)
            {
                return(DbgDotNetValueResult.Create((DbgDotNetValueImpl)value));
            }
            var tmp = CheckFuncEval(evalInfo);

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

            var      dnThread        = GetThread(evalInfo.Frame.Thread);
            var      createdValues   = new List <CorValue>();
            CorValue?createdCorValue = null;

            try {
                var appDomain           = ilFrame.GetCorAppDomain();
                var reflectionAppDomain = ilFrame.GetReflectionModule().AppDomain;
                using (var dnEval = dnDebugger.CreateEval(evalInfo.CancellationToken, suspendOtherThreads: (evalInfo.Context.Options & DbgEvaluationContextOptions.RunAllThreads) == 0)) {
                    dnEval.SetThread(dnThread);
                    dnEval.SetTimeout(evalInfo.Context.FuncEvalTimeout);
                    dnEval.EvalEvent += (s, e) => DnEval_EvalEvent(dnEval, evalInfo);

                    var converter = new EvalArgumentConverter(this, dnEval, appDomain, reflectionAppDomain, createdValues);
                    var evalRes   = converter.Convert(value, reflectionAppDomain.System_Object, out var newValueType);
                    if (!(evalRes.ErrorMessage is null))
                    {
                        return(DbgDotNetValueResult.CreateError(evalRes.ErrorMessage));
                    }

                    var resultValue = CreateDotNetValue_CorDebug(evalRes.CorValue !, reflectionAppDomain, tryCreateStrongHandle: true);
                    createdCorValue = evalRes.CorValue;
                    return(DbgDotNetValueResult.Create(resultValue));
                }
            }
            catch (TimeoutException) {
                return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
            }
            catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex))
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }
            finally {
                foreach (var v in createdValues)
                {
                    if (!v.Equals(createdCorValue))
                    {
                        dnDebugger.DisposeHandle(v);
                    }
                }
            }
        }
        bool TryFormatKeyValuePair(DbgDotNetValue value)
        {
            var info = KeyValuePairTypeUtils.TryGetFields(value.Type);

            if ((object)info.keyField == null)
            {
                return(false);
            }
            var runtime = evalInfo.Runtime.GetDotNetRuntime();
            DbgDotNetValueResult keyResult = default, valueResult = default;
Example #5
0
        /// <summary>
        /// Gets the builder instance. It's assumed to be stored in a field in the current 'this' instance.
        ///
        /// The decompiler should already know the field. If that info isn't available, we'll try to find
        /// the field by name, and if that fails, by field type.
        ///
        /// null is returned if we couldn't find the field or if we failed to read the field.
        /// </summary>
        /// <param name="evalInfo">Evaluation info</param>
        /// <param name="builderFieldModule">Module of builder field or null if unknown</param>
        /// <param name="builderFieldToken">Token of builder field or 0 if unknown</param>
        /// <returns></returns>
        public static DbgDotNetValue?TryGetBuilder(DbgEvaluationInfo evalInfo, DmdModule?builderFieldModule, uint builderFieldToken)
        {
            DbgDotNetValueResult thisArg   = default;
            DbgDotNetValueResult tmpResult = default;

            try {
                var runtime = evalInfo.Runtime.GetDotNetRuntime();
                thisArg = runtime.GetParameterValue(evalInfo, 0);
                if (!thisArg.IsNormalResult || thisArg.Value !.IsNull)
                {
                    return(null);
                }
                if (thisArg.Value.Type.IsByRef)
                {
                    tmpResult = thisArg.Value.LoadIndirect();
                    if (!tmpResult.IsNormalResult || tmpResult.Value !.IsNull)
                    {
                        return(null);
                    }
                    thisArg.Value?.Dispose();
                    thisArg   = tmpResult;
                    tmpResult = default;
                }

                DmdFieldInfo?builderField = null;
                if (builderFieldModule is not null && builderFieldToken != 0)
                {
                    builderField = thisArg.Value.Type.GetField(builderFieldModule, (int)builderFieldToken);
                }
                if (builderField is null)
                {
                    builderField = TryGetBuilderField(thisArg.Value.Type);
                }
                if (builderField is null)
                {
                    return(null);
                }
                Debug.Assert((object)builderField == TryGetBuilderFieldByType(thisArg.Value.Type));
                Debug2.Assert(TryGetBuilderFieldByname(thisArg.Value.Type) is null ||
                              (object?)TryGetBuilderFieldByname(thisArg.Value.Type) == TryGetBuilderFieldByType(thisArg.Value.Type));
                tmpResult = runtime.LoadField(evalInfo, thisArg.Value, builderField);
                if (!tmpResult.IsNormalResult || tmpResult.Value !.IsNull)
                {
                    return(null);
                }
                var fieldValue = tmpResult.Value;
                tmpResult = default;
                return(fieldValue);
            }
            finally {
                thisArg.Value?.Dispose();
                tmpResult.Value?.Dispose();
            }
        }
Example #6
0
        DbgDotNetValueResult GetArrayElementAt_MonoDebug(uint index)
        {
            Debug.Assert(Type.IsArray);
            engine.VerifyMonoDebugThread();
            var info = GetArrayElementValueLocation_MonoDebug(index);

            if (!(info.errorMessage is null))
            {
                return(DbgDotNetValueResult.CreateError(info.errorMessage));
            }
            return(DbgDotNetValueResult.Create(engine.CreateDotNetValue_MonoDebug(info.valueLocation !)));
        }
        public override DbgDotNetValueNode[] GetChildren(LanguageValueNodeFactory valueNodeFactory, DbgEvaluationInfo evalInfo, ulong index, int count, DbgValueNodeEvaluationOptions options, ReadOnlyCollection <string>?formatSpecifiers)
        {
            var runtime      = evalInfo.Runtime.GetDotNetRuntime();
            var res          = count == 0 ? Array.Empty <DbgDotNetValueNode>() : new DbgDotNetValueNode[count];
            var valueResults = new List <DbgDotNetValueResult>();
            DbgDotNetValueResult valueResult = default;

            try {
                for (int i = 0; i < res.Length; i++)
                {
                    evalInfo.CancellationToken.ThrowIfCancellationRequested();
                    ref readonly var info     = ref tupleFields[(int)index + i];
Example #8
0
		DbgDotNetValue RecordValue(DbgDotNetValueResult result) {
			if (result.HasError)
				throw new InterpreterMessageException(result.ErrorMessage);
			if (result.ValueIsException)
				throw new InterpreterThrownExceptionException(result.Value);

			var dnValue = result.Value;
			if (dnValue == null)
				throw new InterpreterMessageException(PredefinedEvaluationErrorMessages.InternalDebuggerError);

			return RecordValue(dnValue);
		}
Example #9
0
        DbgDotNetValueResult CreateInstanceCore(DmdConstructorInfo ctor, ILValue[] arguments)
        {
            if (ctor.IsStatic)
            {
                return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.InternalDebuggerError));
            }

            const DotNetClassHookCallOptions options = DotNetClassHookCallOptions.None;

            foreach (var anyHook in anyClassHooks)
            {
                var res = anyHook.CreateInstance(options, ctor, arguments);
                if (res != null)
                {
                    return(DbgDotNetValueResult.Create(res));
                }
            }

            var type = ctor.DeclaringType;

            if (type.IsConstructedGenericType)
            {
                type = type.GetGenericTypeDefinition();
            }
            var typeName = DmdTypeName.Create(type);

            if (classHooks.TryGetValue(typeName, out var hook))
            {
                if (DmdWellKnownTypeUtils.TryGetWellKnownType(typeName, out var wellKnownType))
                {
                    if (type != type.AppDomain.GetWellKnownType(wellKnownType, isOptional: true))
                    {
                        hook = null;
                    }
                }
                if (hook != null)
                {
                    var res = hook.CreateInstance(options, ctor, arguments);
                    if (res != null)
                    {
                        return(DbgDotNetValueResult.Create(res));
                    }
                }
            }

            if (!canFuncEval)
            {
                throw new InterpreterMessageException(PredefinedEvaluationErrorMessages.FuncEvalDisabled);
            }
            return(runtime.CreateInstance(evalInfo, ctor, Convert(arguments, ctor.GetMethodSignature().GetParameterTypes()), DbgDotNetInvokeOptions.None));
        }
Example #10
0
        DbgDotNetValueResult Dereference_CorDebug()
        {
            Debug.Assert((Type.IsByRef && !IsNullByRef) || (Type.IsPointer && !IsNull));
            engine.VerifyCorDebugThread();
            int hr = -1;
            var dereferencedValue = TryGetCorValue()?.GetDereferencedValue(out hr);

            // We sometimes get 0x80131C49 = CORDBG_E_READVIRTUAL_FAILURE
            if (dereferencedValue is null)
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
            }
            return(DbgDotNetValueResult.Create(engine.CreateDotNetValue_CorDebug(dereferencedValue, Type.AppDomain, tryCreateStrongHandle: true)));
        }
        // 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(DbgEvaluationInfo evalInfo, CorAppDomain appDomain, DmdType elementType, int length)
        {
            debuggerThread.VerifyAccess();
            evalInfo.CancellationToken.ThrowIfCancellationRequested();
            var tmp = CheckFuncEval(evalInfo);

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

            var dnThread = GetThread(evalInfo.Frame.Thread);

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

                    var corType = GetType(appDomain, elementType);
                    var res     = dnEval.CreateSZArray(corType, length, out int hr);
                    if (res is null)
                    {
                        return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
                    }
                    Debug.Assert(!res.Value.WasException, "Shouldn't throw " + nameof(ArgumentOutOfRangeException));
                    if (res.Value.WasCustomNotification)
                    {
                        return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.FuncEvalRequiresAllThreadsToRun));
                    }
                    if (res.Value.WasCancelled)
                    {
                        return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
                    }
                    if (res.Value.WasException)
                    {
                        return(DbgDotNetValueResult.CreateException(CreateDotNetValue_CorDebug(res.Value.ResultOrException !, elementType.AppDomain, tryCreateStrongHandle: true)));
                    }
                    return(DbgDotNetValueResult.Create(CreateDotNetValue_CorDebug(res.Value.ResultOrException !, elementType.AppDomain, tryCreateStrongHandle: true)));
                }
            }
            catch (TimeoutException) {
                return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
            }
            catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex))
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }
        }
        internal DbgDotNetValueResult FuncEvalCall_AnyThread_MonoDebug(DmdMethodBase method, DbgDotNetValue obj, object[] arguments, DbgDotNetInvokeOptions invokeOptions, bool newObj)
        {
            debuggerThread.VerifyAccess();
            var cancellationToken = CancellationToken.None;

            foreach (var thread in GetFuncEvalCallThreads(method.AppDomain))
            {
                var res = FuncEvalCallCore_MonoDebug(null, null, thread, method, obj, arguments, invokeOptions, newObj, cancellationToken);
                if (!res.HasError)
                {
                    return(res);
                }
            }
            return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.InternalDebuggerError));
        }
Example #13
0
        internal DbgDotNetValueResult FuncEvalCreateInstanceNoCtor_CorDebug(DbgEvaluationInfo evalInfo, CorAppDomain appDomain, DmdType typeToCreate)
        {
            debuggerThread.VerifyAccess();
            evalInfo.CancellationToken.ThrowIfCancellationRequested();
            var tmp = CheckFuncEval(evalInfo);

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

            var dnThread = GetThread(evalInfo.Frame.Thread);

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

                    var corType = GetType(appDomain, typeToCreate);
                    var res     = dnEval.CreateDontCallConstructor(corType, out int hr);
                    if (res == null)
                    {
                        return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
                    }
                    if (res.Value.WasCustomNotification)
                    {
                        return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.FuncEvalRequiresAllThreadsToRun));
                    }
                    if (res.Value.WasCancelled)
                    {
                        return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
                    }
                    if (res.Value.WasException)
                    {
                        return(DbgDotNetValueResult.CreateException(CreateDotNetValue_CorDebug(res.Value.ResultOrException, typeToCreate.AppDomain, tryCreateStrongHandle: true)));
                    }
                    return(DbgDotNetValueResult.Create(CreateDotNetValue_CorDebug(res.Value.ResultOrException, typeToCreate.AppDomain, tryCreateStrongHandle: true)));
                }
            }
            catch (TimeoutException) {
                return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
            }
            catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex))
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }
        }
Example #14
0
        DbgDotNetValueResult CallCore(DbgDotNetValue obj, bool isCallvirt, DmdMethodBase method, ILValue[] arguments)
        {
            var options = isCallvirt ? DotNetClassHookCallOptions.IsCallvirt : DotNetClassHookCallOptions.None;

            foreach (var anyHook in anyClassHooks)
            {
                var res = anyHook.Call(options, obj, method, arguments);
                if (res != null)
                {
                    return(DbgDotNetValueResult.Create(res));
                }
            }

            var type = method.DeclaringType;

            if (type.IsConstructedGenericType)
            {
                type = type.GetGenericTypeDefinition();
            }
            var typeName = DmdTypeName.Create(type);

            if (classHooks.TryGetValue(typeName, out var hook))
            {
                if (DmdWellKnownTypeUtils.TryGetWellKnownType(typeName, out var wellKnownType))
                {
                    if (type != type.AppDomain.GetWellKnownType(wellKnownType, isOptional: true))
                    {
                        hook = null;
                    }
                }
                if (hook != null)
                {
                    var res = hook.Call(options, obj, method, arguments);
                    if (res != null)
                    {
                        return(DbgDotNetValueResult.Create(res));
                    }
                }
            }

            if (!canFuncEval)
            {
                throw new InterpreterMessageException(PredefinedEvaluationErrorMessages.FuncEvalDisabled);
            }
            var invokeOptions = isCallvirt ? DbgDotNetInvokeOptions.None : DbgDotNetInvokeOptions.NonVirtual;

            return(runtime.Call(evalInfo, obj, method, Convert(arguments, method.GetMethodSignature().GetParameterTypes()), invokeOptions));
        }
Example #15
0
 public override DbgDotNetValueResult LoadIndirect()
 {
     if (!Type.IsByRef)
     {
         return(base.LoadIndirect());
     }
     if (IsNullByRef)
     {
         return(DbgDotNetValueResult.Create(new SyntheticNullValue(Type.GetElementType())));
     }
     if (engine.CheckMonoDebugThread())
     {
         return(Dereference_MonoDebug());
     }
     return(engine.InvokeMonoDebugThread(() => Dereference_MonoDebug()));
 }
        bool InitializeListDebugView(DbgEvaluationInfo evalInfo)
        {
            var info = EnumerableDebugViewHelper.GetListEnumerableMethods(instanceValue.Type, enumerableType);

            if ((object)info.ctor == null)
            {
                return(false);
            }

            DbgDotNetValueResult collTypeResult = default;
            DbgDotNetValueResult toArrayResult  = default;
            bool error = true;

            try {
                var runtime = evalInfo.Runtime.GetDotNetRuntime();

                collTypeResult = runtime.CreateInstance(evalInfo, info.ctor, new[] { instanceValue }, DbgDotNetInvokeOptions.None);
                if (!collTypeResult.IsNormalResult)
                {
                    return(false);
                }
                var expr = valueNodeProviderFactory.GetNewObjectExpression(info.ctor, valueExpression, expectedType);

                toArrayResult = runtime.Call(evalInfo, collTypeResult.Value, info.toArrayMethod, Array.Empty <object>(), DbgDotNetInvokeOptions.None);
                if (toArrayResult.HasError)
                {
                    return(false);
                }
                expr = valueNodeProviderFactory.GetCallExpression(info.toArrayMethod, expr);

                var result = valueNodeProviderFactory.Create(evalInfo, false, toArrayResult.Value.Type, new DbgDotNetValueNodeInfo(toArrayResult.Value, expr), evalOptions);
                if (result.Provider == null)
                {
                    return(false);
                }
                realProvider = result.Provider;
                error        = false;
                return(true);
            }
            finally {
                collTypeResult.Value?.Dispose();
                if (error)
                {
                    toArrayResult.Value?.Dispose();
                }
            }
        }
        internal DbgDotNetValueResult Box_CorDebug(DbgEvaluationInfo evalInfo, CorAppDomain appDomain, CorValue value, DmdType type)
        {
            debuggerThread.VerifyAccess();
            evalInfo.CancellationToken.ThrowIfCancellationRequested();
            var tmp = CheckFuncEval(evalInfo);

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

            var      dnThread      = GetThread(evalInfo.Frame.Thread);
            var      createdValues = new List <CorValue>();
            CorValue?boxedValue    = null;

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

                    boxedValue = BoxIfNeeded(dnEval, appDomain, createdValues, value, type.AppDomain.System_Object, type);
                    if (boxedValue is null)
                    {
                        return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(-1)));
                    }
                    return(DbgDotNetValueResult.Create(CreateDotNetValue_CorDebug(boxedValue, type.AppDomain, tryCreateStrongHandle: true)));
                }
            }
            catch (TimeoutException) {
                return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
            }
            catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex))
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }
            finally {
                foreach (var v in createdValues)
                {
                    if (!v.Equals(boxedValue))
                    {
                        dnDebugger.DisposeHandle(v);
                    }
                }
            }
        }
 public override DbgDotNetValueResult GetVariable(int index)
 {
     if ((uint)index < (uint)realLocalVariables.Count)
     {
         return(localsProvider.GetVariable(index));
     }
     if ((uint)index < (uint)localVariables.Count)
     {
         var type = localVariables[index].LocalType;
         if (!extraLocals.TryGetValue(index, out var localValue))
         {
             localValue = runtime.GetDefaultValue(type);
             extraLocals.Add(index, localValue);
         }
         return(DbgDotNetValueResult.Create(localValue));
     }
     return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.InternalDebuggerError));
 }
Example #19
0
        DbgDotNetValueResult GetArrayElementAt_CorDebug(uint index)
        {
            Debug.Assert(Type.IsArray);
            engine.VerifyCorDebugThread();
            var corValue = TryGetCorValue();

            if (corValue == null || corValue.IsNull)
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }
            using (var obj = new ArrayObjectValue(engine, corValue)) {
                int hr        = -1;
                var elemValue = obj.Value?.GetElementAtPosition(index, out hr);
                if (elemValue == null)
                {
                    return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
                }
                return(DbgDotNetValueResult.Create(engine.CreateDotNetValue_CorDebug(elemValue, Type.AppDomain, tryCreateStrongHandle: true)));
            }
        }
Example #20
0
        ILValue CreateILValue(DbgDotNetValueResult result)
        {
            if (result.HasError)
            {
                throw new InterpreterMessageException(result.ErrorMessage);
            }
            if (result.ValueIsException)
            {
                throw new InterpreterThrownExceptionException(result.Value);
            }

            var dnValue = result.Value;

            if (dnValue == null)
            {
                throw new InterpreterMessageException(PredefinedEvaluationErrorMessages.InternalDebuggerError);
            }

            return(CreateILValue(dnValue));
        }
 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);
 }
Example #22
0
        bool FormatValue(uint index, bool needSpace)
        {
            var runtime = evalInfo.Runtime.GetDotNetRuntime();
            DbgDotNetValueResult parameterValue    = default;
            DbgDotNetValue       dereferencedValue = null;

            try {
                parameterValue = runtime.GetParameterValue(evalInfo, index);
                if (parameterValue.IsNormalResult)
                {
                    if (needSpace)
                    {
                        WriteSpace();
                        OutputWrite("=", BoxedTextColor.Operator);
                        WriteSpace();
                    }
                    needSpace = true;

                    var valueFormatter = new CSharpValueFormatter(output, evalInfo, languageFormatter, valueOptions, cultureInfo);
                    var value          = parameterValue.Value;
                    if (value.Type.IsByRef)
                    {
                        value = dereferencedValue = value.LoadIndirect().Value;
                    }
                    if (value == null)
                    {
                        OutputWrite("???", BoxedTextColor.Error);
                    }
                    else
                    {
                        valueFormatter.Format(value);
                    }
                }
            }
            finally {
                parameterValue.Value?.Dispose();
                dereferencedValue?.Dispose();
            }
            return(needSpace);
        }
        bool FormatValue(DbgStackFrame frame, uint index, bool needSpace)
        {
            var runtime = context.Runtime.GetDotNetRuntime();
            DbgDotNetValueResult parameterValue    = default;
            DbgDotNetValue       dereferencedValue = null;

            try {
                parameterValue = runtime.GetParameterValue(context, frame, index, cancellationToken);
                if (parameterValue.IsNormalResult)
                {
                    if (needSpace)
                    {
                        WriteSpace();
                        OutputWrite("=", BoxedTextColor.Operator);
                        WriteSpace();
                    }
                    needSpace = true;

                    var valueFormatter = new VisualBasicValueFormatter(output, context, frame, languageFormatter, valueOptions, cultureInfo, cancellationToken);
                    var value          = parameterValue.Value;
                    if (value.Type.IsByRef)
                    {
                        value = dereferencedValue = value.LoadIndirect();
                    }
                    if (value == null)
                    {
                        OutputWrite("???", BoxedTextColor.Error);
                    }
                    else
                    {
                        valueFormatter.Format(value);
                    }
                }
            }
            finally {
                parameterValue.Value?.Dispose();
                dereferencedValue?.Dispose();
            }
            return(needSpace);
        }
 DbgDotNetValueResult FuncEvalCallCore_MonoDebug(DbgEvaluationContext contextOpt, DbgStackFrame frameOpt, DbgThread thread, DmdMethodBase method, DbgDotNetValue obj, object[] arguments, DbgDotNetInvokeOptions invokeOptions, bool newObj, CancellationToken cancellationToken)
 {
     // ReturnOutThis is only available since 2.35 so we'll special case the common case where a struct ctor
     // is called (CALL/CALLVIRT). We'll change it to a NEWOBJ and then copy the result to the input 'this' value.
     if (!newObj && obj is DbgDotNetValueImpl objImpl && method is DmdConstructorInfo ctor && ctor.ReflectedType.IsValueType)
     {
         var res = FuncEvalCallCoreReal_MonoDebug(contextOpt, frameOpt, thread, method, null, arguments, invokeOptions, true, cancellationToken);
         if (res.IsNormalResult)
         {
             try {
                 var error = objImpl.ValueLocation.Store(((DbgDotNetValueImpl)res.Value).Value);
                 if (error != null)
                 {
                     res.Value?.Dispose();
                     return(DbgDotNetValueResult.CreateError(error));
                 }
             }
             catch {
                 res.Value?.Dispose();
                 throw;
             }
         }
         return(res);
     }
        internal DbgDotNetValueResult FuncEvalCall_CorDebug(DbgEvaluationInfo evalInfo, CorAppDomain appDomain, DmdMethodBase method, DbgDotNetValue?obj, object?[] arguments, bool newObj)
        {
            debuggerThread.VerifyAccess();
            evalInfo.CancellationToken.ThrowIfCancellationRequested();
            var tmp = CheckFuncEval(evalInfo);

            if (!(tmp is null))
            {
                return(tmp.Value);
            }
            Debug.Assert(!newObj || method.IsConstructor);

            Debug.Assert(method.SpecialMethodKind == DmdSpecialMethodKind.Metadata, "Methods not defined in metadata should be emulated by other code (i.e., the caller)");
            if (method.SpecialMethodKind != DmdSpecialMethodKind.Metadata)
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }

            var reflectionAppDomain = method.AppDomain;
            var methodDbgModule     = method.Module.GetDebuggerModule() ?? throw new InvalidOperationException();

            if (!TryGetDnModule(methodDbgModule, out var methodModule))
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }
            var func = methodModule.CorModule.GetFunctionFromToken((uint)method.MetadataToken) ?? throw new InvalidOperationException();

            int hr;
            var dnThread      = GetThread(evalInfo.Frame.Thread);
            var createdValues = new List <CorValue>();

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

                    var converter = new EvalArgumentConverter(this, dnEval, appDomain, reflectionAppDomain, createdValues);

                    var genTypeArgs  = method.DeclaringType !.GetGenericArguments();
                    var methTypeArgs = method.GetGenericArguments();
                    var typeArgs     = genTypeArgs.Count == 0 && methTypeArgs.Count == 0 ? Array.Empty <CorType>() : new CorType[genTypeArgs.Count + methTypeArgs.Count];
                    int w            = 0;
                    for (int i = 0; i < genTypeArgs.Count; i++)
                    {
                        typeArgs[w++] = GetType(appDomain, genTypeArgs[i]);
                    }
                    for (int i = 0; i < methTypeArgs.Count; i++)
                    {
                        typeArgs[w++] = GetType(appDomain, methTypeArgs[i]);
                    }
                    if (typeArgs.Length != w)
                    {
                        throw new InvalidOperationException();
                    }

                    var paramTypes = GetAllMethodParameterTypes(method.GetMethodSignature());
                    if (paramTypes.Count != arguments.Length)
                    {
                        throw new InvalidOperationException();
                    }

                    bool hiddenThisArg = !method.IsStatic && !newObj;
                    int  argsCount     = arguments.Length + (hiddenThisArg ? 1 : 0);
                    var  args          = argsCount == 0 ? Array.Empty <CorValue>() : new CorValue[argsCount];
                    w = 0;
                    DmdType origType;
                    var     declType = method.DeclaringType;
                    if (hiddenThisArg)
                    {
                        if (method is DmdMethodInfo m)
                        {
                            declType = m.GetBaseDefinition().DeclaringType !;
                        }
                        var val = converter.Convert(obj, declType, out origType);
                        if (!(val.ErrorMessage is null))
                        {
                            return(DbgDotNetValueResult.CreateError(val.ErrorMessage));
                        }
                        args[w++] = BoxIfNeeded(dnEval, appDomain, createdValues, val.CorValue !, declType, origType);
                    }
                    for (int i = 0; i < arguments.Length; i++)
                    {
                        var paramType = paramTypes[i];
                        var val       = converter.Convert(arguments[i], paramType, out origType);
                        if (!(val.ErrorMessage is null))
                        {
                            return(DbgDotNetValueResult.CreateError(val.ErrorMessage));
                        }
                        var valType = origType ?? new ReflectionTypeCreator(this, method.AppDomain).Create(val.CorValue !.ExactType);
                        args[w++] = BoxIfNeeded(dnEval, appDomain, createdValues, val.CorValue !, paramType, valType);
                    }
                    if (args.Length != w)
                    {
                        throw new InvalidOperationException();
                    }

                    // Derefence/unbox the values here now that they can't get neutered
                    for (int i = 0; i < args.Length; i++)
                    {
                        DmdType argType;
                        if (!hiddenThisArg)
                        {
                            argType = paramTypes[i];
                        }
                        else if (i == 0)
                        {
                            argType = declType;
                        }
                        else
                        {
                            argType = paramTypes[i - 1];
                        }
                        CorValue?arg = args[i];
                        if (argType.IsValueType || argType.IsPointer || argType.IsFunctionPointer)
                        {
                            if (arg.IsReference)
                            {
                                if (arg.IsNull)
                                {
                                    throw new InvalidOperationException();
                                }
                                arg = arg.GetDereferencedValue(out hr);
                                if (arg is null)
                                {
                                    return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
                                }
                            }
                            if (arg.IsBox)
                            {
                                arg = arg.GetBoxedValue(out hr);
                                if (arg is null)
                                {
                                    return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
                                }
                            }
                            args[i] = arg;
                        }
                    }

                    var res = newObj ?
                              dnEval.CallConstructor(func, typeArgs, args, out hr) :
                              dnEval.Call(func, typeArgs, args, out hr);
                    if (res is null)
                    {
                        return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
                    }
                    if (res.Value.WasCustomNotification)
                    {
                        return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.FuncEvalRequiresAllThreadsToRun));
                    }
                    if (res.Value.WasCancelled)
                    {
                        return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
                    }
                    if (res.Value.WasException)
                    {
                        return(DbgDotNetValueResult.CreateException(CreateDotNetValue_CorDebug(res.Value.ResultOrException !, reflectionAppDomain, tryCreateStrongHandle: true)));
                    }
                    return(DbgDotNetValueResult.Create(CreateDotNetValue_CorDebug(res.Value.ResultOrException !, reflectionAppDomain, tryCreateStrongHandle: true)));
                }
            }
            catch (TimeoutException) {
                return(DbgDotNetValueResult.CreateError(PredefinedEvaluationErrorMessages.FuncEvalTimedOut));
            }
            catch (Exception ex) when(ExceptionUtils.IsInternalDebuggerError(ex))
            {
                return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.InternalError));
            }
            finally {
                foreach (var value in createdValues)
                {
                    dnDebugger.DisposeHandle(value);
                }
            }
        }
 protected override (DbgDotNetValueNode node, bool canHide) TryCreateInstanceValueNode(DbgDotNetValueResult valueResult)
 {
     if (!valueResult.ValueIsException)
     {
         return(null, false);
     }
     if (valueResult.Value.Type != valueResult.Value.Type.AppDomain.GetWellKnownType(DmdWellKnownType.System_Linq_SystemCore_EnumerableDebugViewEmptyException, isOptional: true))
     {
         return(null, false);
     }
     valueResult.Value?.Dispose();
     return(new ResultsViewNoResultsValueNode(Expression), false);
 }
Example #27
0
        protected override (DbgDotNetValueNode node, bool canHide) CreateValueNode(DbgEvaluationContext context, DbgStackFrame frame, int index, DbgValueNodeEvaluationOptions options, CancellationToken cancellationToken)
        {
            var runtime = context.Runtime.GetDotNetRuntime();
            DbgDotNetValueResult valueResult = default;

            try {
                ref var info = ref membersCollection.Members[index];
                var     typeExpression = GetExpression(info.Member.DeclaringType);
                string  expression, imageName;
                bool    isReadOnly;
                DmdType expectedType;
                switch (info.Member.MemberType)
                {
                case DmdMemberTypes.Field:
                    var field = (DmdFieldInfo)info.Member;
                    expression   = valueNodeFactory.GetFieldExpression(typeExpression, field.Name, null, addParens: false);
                    expectedType = field.FieldType;
                    imageName    = ImageNameUtils.GetImageName(field);
                    valueResult  = runtime.LoadField(context, frame, null, field, cancellationToken);
                    // We should be able to change read only fields (we're a debugger), but since the
                    // compiler will complain, we have to prevent the user from editing the value.
                    isReadOnly = field.IsLiteral || field.IsInitOnly;
                    break;

                case DmdMemberTypes.Property:
                    var property = (DmdPropertyInfo)info.Member;
                    expression   = valueNodeFactory.GetPropertyExpression(typeExpression, property.Name, null, addParens: false);
                    expectedType = property.PropertyType;
                    imageName    = ImageNameUtils.GetImageName(property);
                    if ((options & DbgValueNodeEvaluationOptions.NoFuncEval) != 0)
                    {
                        isReadOnly  = true;
                        valueResult = new DbgDotNetValueResult(PredefinedEvaluationErrorMessages.FuncEvalDisabled);
                    }
                    else
                    {
                        var getter = property.GetGetMethod(DmdGetAccessorOptions.All) ?? throw new InvalidOperationException();
                        valueResult = runtime.Call(context, frame, null, getter, Array.Empty <object>(), cancellationToken);
                        isReadOnly  = (object)property.GetSetMethod(DmdGetAccessorOptions.All) == null;
                    }
                    break;

                default:
                    throw new InvalidOperationException();
                }

                DbgDotNetValueNode newNode;
                if (valueResult.HasError)
                {
                    newNode = valueNodeFactory.CreateError(context, frame, info.Name, valueResult.ErrorMessage, expression, false, cancellationToken);
                }
                else if (valueResult.ValueIsException)
                {
                    newNode = valueNodeFactory.Create(context, frame, info.Name, valueResult.Value, options, expression, PredefinedDbgValueNodeImageNames.Error, true, false, expectedType, false, cancellationToken);
                }
                else
                {
                    newNode = valueNodeFactory.Create(context, frame, info.Name, valueResult.Value, options, expression, imageName, isReadOnly, false, expectedType, false, cancellationToken);
                }

                valueResult = default;
                return(newNode, true);
            }
Example #28
0
        public override TypeMirror?Load(AssemblyMirror assembly, string typeFullName)
        {
            var res = engine.CheckFuncEval(evalInfo.Context);

            if (!(res is null))
            {
                return(null);
            }
            var appDomain = evalInfo.Frame.AppDomain;

            if (appDomain is null)
            {
                return(null);
            }
            var state = appDomain.GetOrCreateData <LoaderState>();

            if (!state.LoadedTypes.Add(typeFullName))
            {
                return(null);
            }

            var reflectionAppDomain = appDomain.GetReflectionAppDomain() ?? throw new InvalidOperationException();
            var runtime             = engine.DotNetRuntime;

            DbgDotNetValue?      asmTypeValue = null;
            DbgDotNetValueResult result1      = default;
            DbgDotNetValueResult result2      = default;

            try {
                if (state.Method_System_Reflection_Assembly_GetType_String is null)
                {
                    var assemblyType = reflectionAppDomain.GetWellKnownType(DmdWellKnownType.System_Reflection_Assembly);
                    state.Method_System_Reflection_Assembly_GetType_String =
                        assemblyType.GetMethod(nameof(System.Reflection.Assembly.GetType), DmdSignatureCallingConvention.HasThis,
                                               0, reflectionAppDomain.System_Type, new[] { reflectionAppDomain.System_String }, throwOnError: false);
                    Debug.Assert(!(state.Method_System_Reflection_Assembly_GetType_String is null));
                    if (state.Method_System_Reflection_Assembly_GetType_String is null)
                    {
                        return(null);
                    }

                    state.Method_System_Array_CreateInstance_Type_Int32 =
                        reflectionAppDomain.System_Array.GetMethod(nameof(Array.CreateInstance), DmdSignatureCallingConvention.Default,
                                                                   0, reflectionAppDomain.System_Array, new[] { reflectionAppDomain.System_Type, reflectionAppDomain.System_Int32 }, throwOnError: false);
                    Debug.Assert(!(state.Method_System_Array_CreateInstance_Type_Int32 is null));
                    if (state.Method_System_Array_CreateInstance_Type_Int32 is null)
                    {
                        return(null);
                    }
                }

                if (state.Method_System_Reflection_Assembly_GetType_String is null || state.Method_System_Array_CreateInstance_Type_Int32 is null)
                {
                    return(null);
                }

                asmTypeValue = engine.CreateDotNetValue_MonoDebug(reflectionAppDomain, assembly.GetAssemblyObject(), null);
                result1      = runtime.Call(evalInfo, asmTypeValue, state.Method_System_Reflection_Assembly_GetType_String,
                                            new[] { typeFullName }, DbgDotNetInvokeOptions.None);
                if (result1.IsNormalResult)
                {
                    result2 = runtime.Call(evalInfo, null, state.Method_System_Array_CreateInstance_Type_Int32,
                                           new object[2] {
                        result1.Value !, 0
                    }, DbgDotNetInvokeOptions.None);
                    if (result2.IsNormalResult)
                    {
                        var arrayType = result2.Value !.Type;
                        Debug.Assert(arrayType.IsSZArray);
                        if (arrayType.IsSZArray)
                        {
                            return(MonoDebugTypeCreator.TryGetType(arrayType.GetElementType() !));
                        }
                    }
                }
        public override DbgDotNetValueNode[] GetChildren(LanguageValueNodeFactory valueNodeFactory, DbgEvaluationInfo evalInfo, ulong index, int count, DbgValueNodeEvaluationOptions options, ReadOnlyCollection <string>?formatSpecifiers)
        {
            var res = count == 0 ? Array.Empty <DbgDotNetValueNode>() : new DbgDotNetValueNode[count];
            DbgDotNetValueResult newValue = default;

            try {
                var output      = ObjectCache.AllocDotNetTextOutput();
                var elementType = valueInfo.Value.Type.GetElementType() !;
                var castType    = NeedCast(slotType, valueInfo.Value.Type) ? valueInfo.Value.Type : null;
                for (int i = 0; i < res.Length; i++)
                {
                    evalInfo.CancellationToken.ThrowIfCancellationRequested();

                    string expression;
                    uint   arrayIndex = (uint)index + (uint)i;
                    newValue = valueInfo.Value.GetArrayElementAt(arrayIndex);

                    if (dimensionInfos.Length == 1)
                    {
                        int baseIndex = (int)arrayIndex + dimensionInfos[0].BaseIndex;
                        expression = valueNodeFactory.GetExpression(valueInfo.Expression, baseIndex, castType, addParens);
                        owner.FormatArrayName(output, baseIndex);
                    }
                    else
                    {
                        uint indexLeft = arrayIndex;
                        Debug2.Assert(indexes is not null);
                        for (int j = dimensionInfos.Length - 1; j >= 0; j--)
                        {
                            indexes[j] = (int)(indexLeft % dimensionInfos[j].Length) + dimensionInfos[j].BaseIndex;
                            indexLeft  = indexLeft / dimensionInfos[j].Length;
                        }
                        expression = valueNodeFactory.GetExpression(valueInfo.Expression, indexes, castType, addParens);
                        owner.FormatArrayName(output, indexes);
                    }

                    var name = output.CreateAndReset();
                    DbgDotNetValueNode?newNode;
                    if (newValue.HasError)
                    {
                        newNode = valueNodeFactory.CreateError(evalInfo, name, newValue.ErrorMessage !, expression, false);
                    }
                    else
                    {
                        newNode = null;
                        if (CSharpDynamicPropertyHelper.IsCSharpDynamicProperty(newValue.Value !.Type))
                        {
                            var info = CSharpDynamicPropertyHelper.GetRealValue(evalInfo, newValue.Value);
                            if (info.name is not null)
                            {
                                newValue.Value.Dispose();
                                name       = new DbgDotNetText(new DbgDotNetTextPart(DbgTextColor.DebugViewPropertyName, info.name));
                                expression = valueNodeFactory.GetFieldExpression(expression, info.valueField.Name, null, false);
                                newNode    = valueNodeFactory.Create(evalInfo, name, info.value, formatSpecifiers, options, expression, PredefinedDbgValueNodeImageNames.DynamicViewElement, true, false, info.valueField.FieldType, false);
                            }
                        }
                        if (newNode is null)
                        {
                            newNode = valueNodeFactory.Create(evalInfo, name, newValue.Value, formatSpecifiers, options, expression, PredefinedDbgValueNodeImageNames.ArrayElement, false, false, elementType, false);
                        }
                    }
                    newValue = default;
                    res[i]   = newNode;
                }
                ObjectCache.Free(ref output);
            }
            catch {
                evalInfo.Context.Process.DbgManager.Close(res.Where(a => a is not null));
                newValue.Value?.Dispose();
                throw;
            }
            return(res);
        }
        bool TryFormatTuple(DbgDotNetValue value, int tupleArity)
        {
            Debug.Assert(TypeFormatterUtils.GetTupleArity(value.Type) == tupleArity && tupleArity > 0);
            OutputWrite(TupleTypeOpenParen, DbgTextColor.Punctuation);

            var values  = ObjectCache.AllocDotNetValueList();
            var runtime = evalInfo.Runtime.GetDotNetRuntime();
            int index   = 0;

            foreach (var info in TupleTypeUtils.GetTupleFields(value.Type, tupleArity))
            {
                if (index++ > 0)
                {
                    OutputWrite(",", DbgTextColor.Punctuation);
                    WriteSpace();
                }
                if (info.tupleIndex < 0)
                {
                    OutputWrite("???", DbgTextColor.Error);
                    break;
                }
                else
                {
                    var objValue = value;
                    DbgDotNetValueResult valueResult = default;
                    try {
                        foreach (var field in info.fields)
                        {
                            valueResult = runtime.LoadField(evalInfo, objValue, field);
                            if (valueResult.Value != null)
                            {
                                values.Add(valueResult.Value);
                            }
                            if (valueResult.HasError || valueResult.ValueIsException)
                            {
                                objValue = null;
                                break;
                            }
                            objValue = valueResult.Value;
                        }
                        valueResult = default;
                        if (objValue == null)
                        {
                            OutputWrite("???", DbgTextColor.Error);
                            break;
                        }
                        Format(objValue);
                    }
                    finally {
                        valueResult.Value?.Dispose();
                        foreach (var v in values)
                        {
                            v?.Dispose();
                        }
                        values.Clear();
                    }
                }
            }
            ObjectCache.Free(ref values);

            OutputWrite(TupleTypeCloseParen, DbgTextColor.Punctuation);
            return(true);
        }