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); }
internal ILValue CreateILValue(DbgDotNetValue value) { try { valuesToDispose.Add(value); return(CreateILValueCore(value)); } catch { value.Dispose(); throw; } }
internal ILValue CreateILValue(DbgDotNetValue value) { try { Debug.Assert(value != null); valuesToDispose.Add(value); return CreateILValueCore(value); } catch { value.Dispose(); throw; } }
internal DbgDotNetValue RecordValue(DbgDotNetValue value) { try { cancellationToken.ThrowIfCancellationRequested(); valuesToDispose.Add(value); return(value); } catch { value.Dispose(); throw; } }
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); }
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();
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(); } }
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(); } }