Beispiel #1
0
        void Format(DmdMethodBase method)
        {
            if (StateMachineUtils.TryGetKickoffMethod(method, out var kickoffMethod))
            {
                method = kickoffMethod;
            }

            var sig = method.GetMethodSignature();

            string[] operatorInfo;
            if (method is DmdConstructorInfo)
            {
                operatorInfo = null;
            }
            else
            {
                operatorInfo = Operators.TryGetOperatorInfo(method.Name);
            }

            if (operatorInfo != null)
            {
                for (int i = 0; i < operatorInfo.Length - 1; i++)
                {
                    WriteOperatorInfoString(operatorInfo[i]);
                    WriteSpace();
                }
            }
            else
            {
                bool isSub = method.GetMethodSignature().ReturnType == method.AppDomain.System_Void;
                OutputWrite(isSub ? Keyword_Sub : Keyword_Function, DbgTextColor.Keyword);
                WriteSpace();
            }

            if (DeclaringTypes)
            {
                FormatType(method.DeclaringType);
                WritePeriod();
            }
            if (method is DmdConstructorInfo)
            {
                OutputWrite(Keyword_New, DbgTextColor.Keyword);
            }
            else
            {
                if (TypeFormatterUtils.TryGetMethodName(method.Name, out var containingMethodName, out var localFunctionName))
                {
                    var methodColor = TypeFormatterUtils.GetColor(method, canBeModule: true);
                    WriteIdentifier(containingMethodName, methodColor);
                    WritePeriod();
                    WriteIdentifier(localFunctionName, methodColor);
                }
Beispiel #2
0
        bool Call(DbgDotNetValue objValue, bool isCallvirt, DmdMethodBase method, ILValue[] arguments, out ILValue returnValue)
        {
            if (method.SpecialMethodKind != DmdSpecialMethodKind.Metadata)
            {
                throw new InvalidOperationException();
            }
            var res = runtime.Call(context, frame, objValue, method, Convert(arguments, method.GetMethodSignature().GetParameterTypes()), cancellationToken);

            try {
                if (res.HasError)
                {
                    throw new InterpreterMessageException(res.ErrorMessage);
                }
                if (res.ValueIsException)
                {
                    var value = res.Value;
                    res = default;
                    throw new InterpreterThrownExceptionException(value);
                }
                if (method.GetMethodSignature().ReturnType == method.AppDomain.System_Void)
                {
                    returnValue = null;
                    res.Value?.Dispose();
                }
                else
                {
                    returnValue = CreateILValue(res);
                }
                return(true);
            }
            catch {
                res.Value?.Dispose();
                throw;
            }
        }
        void Format(DmdMethodBase method)
        {
            if (StateMachineUtils.TryGetKickoffMethod(method, out var kickoffMethod))
            {
                method = kickoffMethod;
            }

            var sig = method.GetMethodSignature();

            string[]? operatorInfo;
            if (method is DmdConstructorInfo)
            {
                operatorInfo = null;
            }
            else
            {
                operatorInfo = Operators.TryGetOperatorInfo(method.Name);
            }

            if (!(operatorInfo is null))
            {
                for (int i = 0; i < operatorInfo.Length - 1; i++)
                {
                    WriteOperatorInfoString(operatorInfo[i]);
                    WriteSpace();
                }
            }
Beispiel #4
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 new DbgDotNetValueResult(res, valueIsException: false);
			}

			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 new DbgDotNetValueResult(res, valueIsException: false);
				}
			}

			if (!canFuncEval)
				throw new InterpreterMessageException(PredefinedEvaluationErrorMessages.FuncEvalDisabled);
			return runtime.Call(context, frame, obj, method, Convert(arguments, method.GetMethodSignature().GetParameterTypes()), cancellationToken);
		}
Beispiel #5
0
		bool Call(DbgDotNetValue objValue, bool isCallvirt, DmdMethodBase method, ILValue[] arguments, out ILValue returnValue) {
			if (method.SpecialMethodKind != DmdSpecialMethodKind.Metadata)
				throw new InvalidOperationException();
			var res = CallCore(objValue, isCallvirt, method, arguments);
			try {
				if (res.HasError)
					throw new InterpreterMessageException(res.ErrorMessage);
				if (res.ValueIsException) {
					var value = res.Value;
					res = default;
					throw new InterpreterThrownExceptionException(value);
				}
				if (method.GetMethodSignature().ReturnType == method.AppDomain.System_Void) {
					returnValue = null;
					res.Value?.Dispose();
				}
				else
					returnValue = CreateILValue(res);
				return true;
			}
			catch {
				res.Value?.Dispose();
				throw;
			}
		}
Beispiel #6
0
        bool Call(DbgDotNetValue objValue, bool isCallvirt, DmdMethodBase method, ILValue[] arguments, out ILValue returnValue)
        {
            if (method.SpecialMethodKind != DmdSpecialMethodKind.Metadata)
            {
                throw new InvalidOperationException();
            }
            var res = runtime.Call(context, frame, objValue, method, Convert(arguments, method.GetMethodSignature().GetParameterTypes()), cancellationToken);

            try {
                if (res.HasError)
                {
                    throw new InterpreterMessageException(res.ErrorMessage);
                }
                if (res.ValueIsException)
                {
                    throw new InterpreterMessageException(string.Format(dnSpy_Debugger_DotNet_Resources.Method_X_ThrewAnExceptionOfType_Y, method.DeclaringType + "." + method.Name, res.Value.Type.FullName));
                }
                if (method.GetMethodSignature().ReturnType == method.AppDomain.System_Void)
                {
                    returnValue = null;
                    res.Value?.Dispose();
                }
                else
                {
                    returnValue = CreateILValue(res);
                }
                return(true);
            }
            catch {
                res.Value?.Dispose();
                throw;
            }
        }
Beispiel #7
0
        void Format(DmdMethodBase method)
        {
            if (StateMachineUtils.TryGetKickoffMethod(method, out var kickoffMethod))
            {
                method = kickoffMethod;
            }

            var sig = method.GetMethodSignature();

            string[] operatorInfo;
            if (method is DmdConstructorInfo)
            {
                operatorInfo = null;
            }
            else
            {
                operatorInfo = Operators.TryGetOperatorInfo(method.Name);
            }
            bool isExplicitOrImplicit = operatorInfo != null && (operatorInfo[0] == "explicit" || operatorInfo[0] == "implicit");

            if (!isExplicitOrImplicit)
            {
                if (ReturnTypes && !(method is DmdConstructorInfo))
                {
                    FormatReturnType(sig.ReturnType, TypeFormatterUtils.IsReadOnlyMethod(method));
                    WriteSpace();
                }
            }

            if (DeclaringTypes)
            {
                FormatType(method.DeclaringType);
                WritePeriod();
            }
            if (method is DmdConstructorInfo)
            {
                WriteIdentifier(TypeFormatterUtils.RemoveGenericTick(method.DeclaringType.MetadataName), TypeFormatterUtils.GetColor(method, canBeModule: false));
            }
            else
            {
                if (TypeFormatterUtils.TryGetMethodName(method.Name, out var containingMethodName, out var localFunctionName))
                {
                    var methodColor = TypeFormatterUtils.GetColor(method, canBeModule: false);
                    WriteIdentifier(containingMethodName, methodColor);
                    WritePeriod();
                    WriteIdentifier(localFunctionName, methodColor);
                }
Beispiel #8
0
 void WriteMethodParameterList(DmdMethodBase method, string openParen, string closeParen) =>
 WriteMethodParameterListCore(method, GetAllMethodParameterTypes(method.GetMethodSignature()), openParen, closeParen, ParameterTypes, ParameterNames, ParameterValues);
Beispiel #9
0
 public static bool IsMatch(DmdMethodBase method, IList <DmdType> types) =>
 IsMatch(method.GetMethodSignature().GetParameterTypes(), types ?? Array.Empty <DmdType>());
        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);
                }
            }
        }