예제 #1
0
        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);
                    }
                }
            }
        }
예제 #2
0
        DbgDotNetValueResult GetArrayElementAt_MonoDebug(uint index)
        {
            Debug.Assert(Type.IsArray);
            engine.VerifyMonoDebugThread();
            var info = GetArrayElementValueLocation_MonoDebug(index);

            if (info.errorMessage != null)
            {
                return(DbgDotNetValueResult.CreateError(info.errorMessage));
            }
            return(DbgDotNetValueResult.Create(engine.CreateDotNetValue_MonoDebug(info.valueLocation)));
        }
예제 #3
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));
        }
예제 #4
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)));
        }
예제 #5
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(DbgEvaluationInfo evalInfo, CorAppDomain appDomain, DmdType elementType, int length)
        {
            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, elementType);
                    var res     = dnEval.CreateSZArray(corType, length, out int hr);
                    if (res == 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));
            }
        }
예제 #6
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));
        }
예제 #7
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()));
 }
예제 #8
0
        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);
                    }
                }
            }
        }
예제 #9
0
 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));
 }
예제 #10
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)));
            }
        }
예제 #11
0
 DbgDotNetValueResult Dereference_MonoDebug()
 {
     Debug.Assert(Type.IsByRef && !IsNullByRef);
     engine.VerifyMonoDebugThread();
     return(DbgDotNetValueResult.Create(engine.CreateDotNetValue_MonoDebug(valueLocation.Dereference())));
 }
예제 #12
0
        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 != 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;
                    if (hiddenThisArg)
                    {
                        var declType = method.DeclaringType;
                        if (method is DmdMethodInfo m)
                        {
                            declType = m.GetBaseDefinition().DeclaringType;
                        }
                        var val = converter.Convert(obj, declType, out origType);
                        if (val.ErrorMessage != 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 != 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 = method.DeclaringType;
                        }
                        else
                        {
                            argType = paramTypes[i - 1];
                        }
                        var 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 == null)
                                {
                                    return(DbgDotNetValueResult.CreateError(CordbgErrorHelper.GetErrorMessage(hr)));
                                }
                            }
                            if (arg.IsBox)
                            {
                                arg = arg.GetBoxedValue(out hr);
                                if (arg == 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 == 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);
                }
            }
        }