Beispiel #1
0
        public override DbgDotNetValueNode[] GetChildren(LanguageValueNodeFactory valueNodeFactory, DbgEvaluationContext context, DbgStackFrame frame, ulong index, int count, DbgValueNodeEvaluationOptions options, CancellationToken cancellationToken)
        {
            var            res      = count == 0 ? Array.Empty <DbgDotNetValueNode>() : new DbgDotNetValueNode[count];
            DbgDotNetValue newValue = null;

            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++)
                {
                    cancellationToken.ThrowIfCancellationRequested();

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

                    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;
                        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();
                    const bool         isReadOnly = false;
                    DbgDotNetValueNode newNode;
                    if (newValue == null)
                    {
                        newNode = valueNodeFactory.CreateError(context, frame, name, PredefinedEvaluationErrorMessages.InternalDebuggerError, expression, false, cancellationToken);
                    }
                    else
                    {
                        newNode = valueNodeFactory.Create(context, frame, name, newValue, options, expression, PredefinedDbgValueNodeImageNames.ArrayElement, isReadOnly, false, elementType, false, cancellationToken);
                    }
                    newValue = null;
                    res[i]   = newNode;
                }
                ObjectCache.Free(ref output);
            }
            catch {
                context.Process.DbgManager.Close(res.Where(a => a != null));
                newValue?.Dispose();
                throw;
            }
            return(res);
        }
Beispiel #2
0
 internal ILValue CreateILValue(DbgDotNetValue value)
 {
     try {
         valuesToDispose.Add(value);
         return(CreateILValueCore(value));
     }
     catch {
         value.Dispose();
         throw;
     }
 }
Beispiel #3
0
		internal ILValue CreateILValue(DbgDotNetValue value) {
			try {
				Debug.Assert(value != null);
				valuesToDispose.Add(value);
				return CreateILValueCore(value);
			}
			catch {
				value.Dispose();
				throw;
			}
		}
Beispiel #4
0
 internal DbgDotNetValue RecordValue(DbgDotNetValue value)
 {
     try {
         cancellationToken.ThrowIfCancellationRequested();
         valuesToDispose.Add(value);
         return(value);
     }
     catch {
         value.Dispose();
         throw;
     }
 }
Beispiel #5
0
 internal DbgDotNetValue RecordValue(DbgDotNetValue value)
 {
     try {
         evalInfo.CancellationToken.ThrowIfCancellationRequested();
         Debug.Assert(value != null);
         valuesToDispose.Add(value);
         return(value);
     }
     catch {
         value.Dispose();
         throw;
     }
 }
        DbgDotNetValueNode CreateValue(DbgEvaluationInfo evalInfo, DbgDotNetText name, DbgDotNetValue value, ReadOnlyCollection <string>?formatSpecifiers, DbgValueNodeEvaluationOptions options, string expression, string imageName, bool isReadOnly, bool causesSideEffects, DmdType expectedType, bool isRootExpression, ColumnFormatter?columnFormatter)
        {
            // Could be a by-ref property, local, or parameter.
            if (expectedType.IsByRef)
            {
                if (value.Type.IsByRef)
                {
                    var newValue = value.LoadIndirect();
                    value.Dispose();
                    if (newValue.HasError)
                    {
                        return(CreateError(evalInfo, name, newValue.ErrorMessage !, expression, causesSideEffects));
                    }
                    value = newValue.Value !;
                }
                expectedType = expectedType.GetElementType() !;
            }

            options = PredefinedFormatSpecifiers.GetValueNodeEvaluationOptions(formatSpecifiers, options);
            var  nodeInfo  = new DbgDotNetValueNodeInfo(value, expression);
            bool addParens = isRootExpression && NeedsParentheses(expression);
            DbgDotNetValueNodeProviderResult info;
            bool useProvider        = false;
            var  specialViewOptions = (options & ~(DbgValueNodeEvaluationOptions.ResultsView | DbgValueNodeEvaluationOptions.DynamicView));

            if ((options & DbgValueNodeEvaluationOptions.ResultsView) != 0)
            {
                info        = valueNodeProviderFactory.CreateResultsView(evalInfo, addParens, expectedType, nodeInfo, specialViewOptions);
                useProvider = !(info.ErrorMessage is null);
            }
            else if ((options & DbgValueNodeEvaluationOptions.DynamicView) != 0)
            {
                info        = valueNodeProviderFactory.CreateDynamicView(evalInfo, addParens, expectedType, nodeInfo, specialViewOptions);
                useProvider = true;
            }
            else
            {
                info = valueNodeProviderFactory.Create(evalInfo, addParens, expectedType, nodeInfo, options);
            }
            if (useProvider)
            {
                if (!(info.ErrorMessage is null))
                {
                    return(new DbgDotNetValueNodeImpl(this, info.Provider, name, nodeInfo, expression, PredefinedDbgValueNodeImageNames.Error, true, false, null, null, info.ErrorMessage, new DbgDotNetText(new DbgDotNetTextPart(DbgTextColor.Error, info.ErrorMessage)), formatSpecifiers, columnFormatter));
                }
                Debug2.Assert(!(info.Provider is null));
                return(new DbgDotNetValueNodeImpl(this, info.Provider, name, nodeInfo, expression, info.Provider?.ImageName ?? imageName, true, false, null, null, info.ErrorMessage, info.Provider?.ValueText ?? default, formatSpecifiers, columnFormatter));
            }
            return(new DbgDotNetValueNodeImpl(this, info.Provider, name, nodeInfo, expression, imageName, isReadOnly, causesSideEffects, expectedType, value.Type, info.ErrorMessage, default, formatSpecifiers, columnFormatter));
        DbgDotNetRawValue?ReadField_CorDebug(DbgDotNetValueImpl obj, string fieldName1, string?fieldName2)
        {
            const DmdBindingFlags fieldFlags = DmdBindingFlags.Public | DmdBindingFlags.NonPublic | DmdBindingFlags.Instance;
            var field = obj.Type.GetField(fieldName1, fieldFlags);

            if (field is null && !(fieldName2 is null))
            {
                field = obj.Type.GetField(fieldName2, fieldFlags);
            }
            Debug2.Assert(!(field is null));
            if (field is null)
            {
                return(null);
            }

            var dnAppDomain      = ((DbgCorDebugInternalAppDomainImpl)obj.Type.AppDomain.GetDebuggerAppDomain().InternalAppDomain).DnAppDomain;
            var corFieldDeclType = GetType(dnAppDomain.CorAppDomain, field.DeclaringType !);
            var objValue         = DbgCorDebugInternalRuntimeImpl.TryGetObjectOrPrimitiveValue(obj.TryGetCorValue(), out int hr);

            if (objValue is null)
            {
                return(null);
            }
            if (objValue.IsObject)
            {
                // This isn't a generic read-field method, so we won't try to load any classes by calling cctors.

                var fieldValue = objValue.GetFieldValue(corFieldDeclType.Class, (uint)field.MetadataToken, out hr);
                if (fieldValue is null)
                {
                    return(null);
                }
                DbgDotNetValue?dnValue = null;
                try {
                    dnValue = CreateDotNetValue_CorDebug(fieldValue, field.AppDomain, tryCreateStrongHandle: false);
                    return(dnValue.GetRawValue());
                }
                finally {
                    dnValue?.Dispose();
                }
            }
            return(null);
        }
Beispiel #8
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);
        }
 protected override void DisposeCore() => getResultsViewValue?.Dispose();
 protected override void DisposeCore() => getDynamicViewValue?.Dispose();
Beispiel #12
0
        public override TypeMirror Load(AssemblyMirror assembly, string typeFullName)
        {
            var res = engine.CheckFuncEval(evalInfo.Context);

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

            if (appDomain == 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 ((object)state.Method_System_Reflection_Assembly_GetType_String == 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((object)state.Method_System_Reflection_Assembly_GetType_String != null);
                    if ((object)state.Method_System_Reflection_Assembly_GetType_String == 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((object)state.Method_System_Array_CreateInstance_Type_Int32 != null);
                    if ((object)state.Method_System_Array_CreateInstance_Type_Int32 == null)
                    {
                        return(null);
                    }
                }

                if ((object)state.Method_System_Reflection_Assembly_GetType_String == null || (object)state.Method_System_Array_CreateInstance_Type_Int32 == 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()));
                        }
                    }
                }

                return(null);
            }
            finally {
                asmTypeValue?.Dispose();
                result1.Value?.Dispose();
                result2.Value?.Dispose();
            }
        }
Beispiel #13
0
        public void Format(DmdType type, DbgDotNetValue value)
        {
            if ((object)type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            List <(DmdType type, DbgDotNetValue value)> arrayTypesList = null;
            DbgDotNetValue disposeThisValue = null;

            try {
                if (recursionCounter++ >= MAX_RECURSION)
                {
                    return;
                }

                switch (type.TypeSignatureKind)
                {
                case DmdTypeSignatureKind.SZArray:
                case DmdTypeSignatureKind.MDArray:
                    // Array types are shown in reverse order
                    arrayTypesList = new List <(DmdType type, DbgDotNetValue value)>();
                    do
                    {
                        arrayTypesList.Add((type, arrayTypesList.Count == 0 ? value : null));
                        type = type.GetElementType();
                    } while (type.IsArray);
                    var t = arrayTypesList[arrayTypesList.Count - 1];
                    Format(t.type.GetElementType(), null);
                    foreach (var tuple in arrayTypesList)
                    {
                        var  aryType  = tuple.type;
                        var  aryValue = tuple.value;
                        uint elementCount;
                        if (aryType.IsVariableBoundArray)
                        {
                            OutputWrite(ARRAY_OPEN_PAREN, BoxedTextColor.Punctuation);
                            int rank = Math.Min(aryType.GetArrayRank(), MAX_ARRAY_RANK);
                            if (rank <= 0)
                            {
                                OutputWrite("???", BoxedTextColor.Error);
                            }
                            else
                            {
                                if (aryValue == null || aryValue.IsNull || !aryValue.GetArrayInfo(out elementCount, out var dimensionInfos))
                                {
                                    dimensionInfos = null;
                                }
                                if (ShowArrayValueSizes && dimensionInfos != null && dimensionInfos.Length == rank)
                                {
                                    for (int i = 0; i < rank; i++)
                                    {
                                        if (i > 0)
                                        {
                                            OutputWrite(",", BoxedTextColor.Punctuation);
                                            WriteSpace();
                                        }
                                        if (dimensionInfos[i].BaseIndex == 0)
                                        {
                                            WriteUInt32(dimensionInfos[i].Length);
                                        }
                                        else
                                        {
                                            WriteInt32(dimensionInfos[i].BaseIndex);
                                            OutputWrite("..", BoxedTextColor.Operator);
                                            WriteInt32(dimensionInfos[i].BaseIndex + (int)dimensionInfos[i].Length - 1);
                                        }
                                    }
                                }
                                else
                                {
                                    if (rank == 1)
                                    {
                                        OutputWrite("*", BoxedTextColor.Operator);
                                    }
                                    OutputWrite(TypeFormatterUtils.GetArrayCommas(rank), BoxedTextColor.Punctuation);
                                }
                            }
                            OutputWrite(ARRAY_CLOSE_PAREN, BoxedTextColor.Punctuation);
                        }
                        else
                        {
                            Debug.Assert(aryType.IsSZArray);
                            OutputWrite(ARRAY_OPEN_PAREN, BoxedTextColor.Punctuation);
                            if (ShowArrayValueSizes && aryValue != null && !aryValue.IsNull)
                            {
                                if (aryValue.GetArrayCount(out elementCount))
                                {
                                    WriteUInt32(elementCount);
                                }
                            }
                            OutputWrite(ARRAY_CLOSE_PAREN, BoxedTextColor.Punctuation);
                        }
                    }
                    break;

                case DmdTypeSignatureKind.Pointer:
                    Format(type.GetElementType(), null);
                    OutputWrite("*", BoxedTextColor.Operator);
                    break;

                case DmdTypeSignatureKind.ByRef:
                    OutputWrite(BYREF_KEYWORD, BoxedTextColor.Keyword);
                    WriteSpace();
                    Format(type.GetElementType(), disposeThisValue = value?.LoadIndirect().Value);
                    break;

                case DmdTypeSignatureKind.TypeGenericParameter:
                    WriteIdentifier(type.MetadataName, BoxedTextColor.TypeGenericParameter);
                    break;

                case DmdTypeSignatureKind.MethodGenericParameter:
                    WriteIdentifier(type.MetadataName, BoxedTextColor.MethodGenericParameter);
                    break;

                case DmdTypeSignatureKind.Type:
                case DmdTypeSignatureKind.GenericInstance:
                    if (type.IsNullable)
                    {
                        Format(type.GetNullableElementType(), null);
                        OutputWrite("?", BoxedTextColor.Operator);
                    }
                    else if (TypeFormatterUtils.IsTupleType(type))
                    {
                        OutputWrite(TUPLE_OPEN_PAREN, BoxedTextColor.Punctuation);
                        var tupleType  = type;
                        int tupleIndex = 0;
                        for (;;)
                        {
                            tupleType = WriteTupleFields(tupleType, ref tupleIndex);
                            if ((object)tupleType != null)
                            {
                                WriteCommaSpace();
                            }
                            else
                            {
                                break;
                            }
                        }
                        OutputWrite(TUPLE_CLOSE_PAREN, BoxedTextColor.Punctuation);
                    }
                    else
                    {
                        var         genericArgs      = type.GetGenericArguments();
                        int         genericArgsIndex = 0;
                        KeywordType keywordType;
                        if ((object)type.DeclaringType == null)
                        {
                            keywordType = GetKeywordType(type);
                            if (keywordType == KeywordType.NoKeyword)
                            {
                                WriteNamespace(type);
                            }
                            WriteTypeName(type, keywordType);
                            WriteGenericArguments(type, genericArgs, ref genericArgsIndex);
                        }
                        else
                        {
                            var typesList = new List <DmdType>();
                            typesList.Add(type);
                            while ((object)type.DeclaringType != null)
                            {
                                type = type.DeclaringType;
                                typesList.Add(type);
                            }
                            keywordType = GetKeywordType(type);
                            if (keywordType == KeywordType.NoKeyword)
                            {
                                WriteNamespace(type);
                            }
                            for (int i = typesList.Count - 1; i >= 0; i--)
                            {
                                WriteTypeName(typesList[i], i == 0 ? keywordType : KeywordType.NoKeyword);
                                WriteGenericArguments(typesList[i], genericArgs, ref genericArgsIndex);
                                if (i != 0)
                                {
                                    OutputWrite(".", BoxedTextColor.Operator);
                                }
                            }
                        }
                    }
                    break;

                case DmdTypeSignatureKind.FunctionPointer:
                    var sig = type.GetFunctionPointerMethodSignature();
                    Format(sig.ReturnType, null);
                    WriteSpace();
                    OutputWrite(METHOD_OPEN_PAREN, BoxedTextColor.Punctuation);
                    var types = sig.GetParameterTypes();
                    for (int i = 0; i < types.Count; i++)
                    {
                        if (i > 0)
                        {
                            WriteCommaSpace();
                        }
                        Format(types[i], null);
                    }
                    types = sig.GetVarArgsParameterTypes();
                    if (types.Count > 0)
                    {
                        if (sig.GetParameterTypes().Count > 0)
                        {
                            WriteCommaSpace();
                        }
                        OutputWrite("...", BoxedTextColor.Punctuation);
                        for (int i = 0; i < types.Count; i++)
                        {
                            WriteCommaSpace();
                            Format(types[i], null);
                        }
                    }
                    OutputWrite(METHOD_CLOSE_PAREN, BoxedTextColor.Punctuation);
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }
            finally {
                recursionCounter--;
                if (arrayTypesList != null)
                {
                    foreach (var info in arrayTypesList)
                    {
                        if (info.value != value)
                        {
                            info.value?.Dispose();
                        }
                    }
                }
                disposeThisValue?.Dispose();
            }
        }