Ejemplo n.º 1
0
        private DkmEvaluationResult GetRootResult(DkmClrValue value, DkmClrType declaredType, string resultName)
        {
            var type = value.Type.GetLmrType();

            if (type.IsTypeVariables())
            {
                var expansion = new TypeVariablesExpansion(type);
                var dataItem  = new EvalResultDataItem(
                    resultName,
                    typeDeclaringMember: null,
                    declaredType: type,
                    value: value,
                    expansion: expansion,
                    childShouldParenthesize: false,
                    fullName: null,
                    childFullNamePrefixOpt: null,
                    formatSpecifiers: Formatter.NoFormatSpecifiers,
                    category: DkmEvaluationResultCategory.Data,
                    flags: DkmEvaluationResultFlags.ReadOnly,
                    editableValue: null);

                Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable));

                // Note: We're not including value.EvalFlags in Flags parameter
                // below (there shouldn't be a reason to do so).
                return(DkmSuccessEvaluationResult.Create(
                           InspectionContext: value.InspectionContext,
                           StackFrame: value.StackFrame,
                           Name: Resources.TypeVariablesName,
                           FullName: dataItem.FullName,
                           Flags: dataItem.Flags,
                           Value: "",
                           EditableValue: null,
                           Type: "",
                           Category: dataItem.Category,
                           Access: value.Access,
                           StorageType: value.StorageType,
                           TypeModifierFlags: value.TypeModifierFlags,
                           Address: value.Address,
                           CustomUIVisualizers: null,
                           ExternalModules: null,
                           DataItem: dataItem));
            }
            else
            {
                var inspectionContext = value.InspectionContext;
                if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0)
                {
                    return(ResultsViewExpansion.CreateResultsOnly(resultName, declaredType, value, null, this.Formatter));
                }

                ReadOnlyCollection <string> formatSpecifiers;
                var fullName = this.Formatter.TrimAndGetFormatSpecifiers(resultName, out formatSpecifiers);
                var dataItem = CreateDataItem(
                    inspectionContext,
                    resultName,
                    typeDeclaringMember: null,
                    declaredType: declaredType.GetLmrType(),
                    value: value,
                    parent: null,
                    expansionFlags: ExpansionFlags.All,
                    childShouldParenthesize: this.Formatter.NeedsParentheses(fullName),
                    fullName: fullName,
                    formatSpecifiers: formatSpecifiers,
                    category: DkmEvaluationResultCategory.Other,
                    flags: value.EvalFlags,
                    evalFlags: inspectionContext.EvaluationFlags);
                return(GetResult(dataItem, value.Type, declaredType, parent: null));
            }
        }
Ejemplo n.º 2
0
 public PassThroughVisualizer(DkmSuccessEvaluationResult successResult)
 {
     EvaluationResult = successResult;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns child elements of previous evaluation.
        /// </summary>
        public void GetItems(DkmVisualizedExpression visualizedExpression, DkmEvaluationResultEnumContext enumContext, int startIndex, int count, out DkmChildVisualizedExpression[] items)
        {
            // Check if we want to use passthrough visualizer
            PassThroughVisualizer passThroughVisualizer = enumContext.GetDataItem <PassThroughVisualizer>();

            if (passThroughVisualizer != null)
            {
                passThroughVisualizer.GetItems(visualizedExpression, enumContext, startIndex, count, out items);
                return;
            }

            // Execute our regular visualizer
            VSCustomVisualizerEvaluator evaluator = visualizedExpression.GetDataItem <VSCustomVisualizerEvaluator>();

            IResultVisualizer[] itemsAsResults = evaluator.ResultVisualizer.Children.Skip(startIndex).Take(count).ToArray();

            items = new DkmChildVisualizedExpression[itemsAsResults.Length];
            for (int i = 0; i < items.Length; i++)
            {
                IResultVisualizer           item = itemsAsResults[i];
                DkmEvaluationResultCategory category;

                switch (item.DataType)
                {
                case CompletionDataType.Class:
                    category = DkmEvaluationResultCategory.Class;
                    break;

                case CompletionDataType.Property:
                case CompletionDataType.StaticProperty:
                    category = DkmEvaluationResultCategory.Property;
                    break;

                case CompletionDataType.Event:
                    category = DkmEvaluationResultCategory.Event;
                    break;

                case CompletionDataType.Method:
                    category = DkmEvaluationResultCategory.Method;
                    break;

                case CompletionDataType.Enum:
                case CompletionDataType.EnumValue:
                case CompletionDataType.Keyword:
                case CompletionDataType.Namespace:
                case CompletionDataType.StaticClass:
                case CompletionDataType.StaticEvent:
                case CompletionDataType.StaticMethod:
                case CompletionDataType.StaticVariable:
                case CompletionDataType.Unknown:
                case CompletionDataType.Variable:
                default:
                    category = DkmEvaluationResultCategory.Data;
                    break;
                }

                DkmExpressionValueHome valueHome = visualizedExpression.ValueHome;
                ulong  address  = 0;
                string fullName = string.Empty;
                string typeName = null;

                try
                {
                    if (item.Value is Variable variable)
                    {
                        address   = variable.GetPointerAddress();
                        typeName  = variable.GetCodeType().Name;
                        fullName  = $"*(({typeName}*)0x{address:X})";
                        valueHome = DkmPointerValueHome.Create(address);
                    }
                }
                catch
                {
                }

                DkmEvaluationResult result;
                DkmDataItem         dataItem = null;

                if (item.ShouldForceDefaultVisualizer && !string.IsNullOrEmpty(fullName))
                {
                    using (DkmLanguageExpression languageExpression = DkmLanguageExpression.Create(visualizedExpression.InspectionContext.Language, DkmEvaluationFlags.TreatAsExpression, fullName, null))
                    {
                        visualizedExpression.EvaluateExpressionCallback(visualizedExpression.InspectionContext, languageExpression, visualizedExpression.StackFrame, out result);
                    }

                    if (result is DkmSuccessEvaluationResult successResult)
                    {
                        dataItem = new PassThroughVisualizer(successResult);
                        result   = DkmSuccessEvaluationResult.Create(
                            successResult.InspectionContext,
                            successResult.StackFrame,
                            item.Name, // Name - Left column
                            successResult.FullName,
                            successResult.Flags,
                            successResult.Value, // Value - Middle column
                            successResult.EditableValue,
                            successResult.Type,  // Type - Right column
                            category,
                            successResult.Access,
                            successResult.StorageType,
                            successResult.TypeModifierFlags,
                            successResult.Address,
                            successResult.CustomUIVisualizers,
                            successResult.ExternalModules,
                            successResult.RefreshButtonText,
                            dataItem);
                    }
                }
                else
                {
                    result = DkmSuccessEvaluationResult.Create(
                        visualizedExpression.InspectionContext,
                        visualizedExpression.StackFrame,
                        item.Name,        // Name - Left column
                        fullName,         // FullName - What is being copied when "Add to watch"
                        DkmEvaluationResultFlags.ReadOnly | (item.IsExpandable ? DkmEvaluationResultFlags.Expandable : DkmEvaluationResultFlags.None),
                        item.ValueString, // Value - Middle column
                        "",
                        item.Type ?? "",  // Type - Right column
                        category,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null,
                        VSUIVisualizerService.GetUIVisualizers(item),
                        null,
                        null);
                    dataItem = new VSCustomVisualizerEvaluator(result, item);
                }
                items[i] = DkmChildVisualizedExpression.Create(
                    visualizedExpression.InspectionContext,
                    visualizedExpression.VisualizerId,
                    visualizedExpression.SourceId,
                    visualizedExpression.StackFrame,
                    valueHome,
                    result,
                    visualizedExpression,
                    (uint)(startIndex + i),
                    dataItem);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Evaluates visual expression and converts it to result visualizer.
        /// </summary>
        private void Evaluate()
        {
            if (VisualizedExpression.TagValue == DkmVisualizedExpression.Tag.RootVisualizedExpression)
            {
                DkmRootVisualizedExpression rootVisualizedExpression = VisualizedExpression as DkmRootVisualizedExpression;
                int    processId  = rootVisualizedExpression.InspectionSession?.Process?.LivePart?.Id ?? 0;
                string moduleName = rootVisualizedExpression.Module?.Name;
                string typeString = rootVisualizedExpression.Type;
                ulong  address    = 0;
                bool   hasAddress = false;

                if (VisualizedExpression.ValueHome.TagValue == DkmExpressionValueHome.Tag.PointerValueHome)
                {
                    address    = (VisualizedExpression.ValueHome as DkmPointerValueHome).Address;
                    hasAddress = true;
                }

                if (string.IsNullOrEmpty(typeString) || string.IsNullOrEmpty(moduleName) || !hasAddress)
                {
                    string displayString = "{...SharpDebug failure...}";

                    EvaluationResult = DkmSuccessEvaluationResult.Create(
                        VisualizedExpression.InspectionContext,
                        VisualizedExpression.StackFrame,
                        rootVisualizedExpression.Name,
                        rootVisualizedExpression.FullName,
                        DkmEvaluationResultFlags.ReadOnly,
                        displayString,
                        "",
                        rootVisualizedExpression.Type,
                        DkmEvaluationResultCategory.Other,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null,
                        null,
                        null,
                        null);
                    return;
                }

                string title;

                try
                {
                    Process  process  = Process.All.First(p => p.SystemId == processId);
                    Module   module   = process.ModulesByName[System.IO.Path.GetFileNameWithoutExtension(moduleName)];
                    CodeType codeType = ResolveCodeType(process, module, typeString);

                    Variable         = codeType.IsPointer ? Variable.CreatePointer(codeType, address) : Variable.Create(codeType, address);
                    title            = Variable.ToString();
                    ResultVisualizer = SharpDebug.UI.ResultVisualizers.ResultVisualizer.Create(Variable, Variable.GetType(), "result", CompletionDataType.Unknown, dummyInteractiveResultVisualizer);
                }
                catch
                {
                    title = "{...SharpDebug...}";
                }

                DkmDataAddress dkmDataAddress = DkmDataAddress.Create(VisualizedExpression.RuntimeInstance, address, rootVisualizedExpression.StackFrame?.InstructionAddress);

                EvaluationResult = DkmSuccessEvaluationResult.Create(
                    VisualizedExpression.InspectionContext,
                    VisualizedExpression.StackFrame,
                    rootVisualizedExpression.Name,
                    rootVisualizedExpression.FullName,
                    DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable,
                    title,
                    "",
                    rootVisualizedExpression.Type,
                    DkmEvaluationResultCategory.Other,
                    DkmEvaluationResultAccessType.None,
                    DkmEvaluationResultStorageType.None,
                    DkmEvaluationResultTypeModifierFlags.None,
                    dkmDataAddress,
                    VSUIVisualizerService.GetUIVisualizers(ResultVisualizer),
                    null,
                    null);
                return;
            }

            // This should never happen...
            throw new NotImplementedException();
        }
Ejemplo n.º 5
0
 void IDkmClrResultProvider.GetResult(
     DkmClrValue clrValue,
     DkmWorkList workList,
     DkmClrType declaredType,
     DkmClrCustomTypeInfo customTypeInfo,
     DkmInspectionContext inspectionContext,
     ReadOnlyCollection <string> formatSpecifiers,
     string resultName,
     string resultFullName,
     DkmCompletionRoutine <DkmEvaluationAsyncResult> completionRoutine
     )
 {
     clrValue.GetResult(
         workList,
         declaredType,
         customTypeInfo,
         inspectionContext,
         formatSpecifiers,
         resultName,
         resultFullName,
         result =>
     {
         var type = declaredType.GetLmrType();
         if (type.IsPointer)
         {
             var r = (DkmSuccessEvaluationResult)result.Result;
             // TODO: Why aren't modopts for & properties included?
             r.GetChildren(
                 workList,
                 1,
                 inspectionContext,
                 children =>
             {
                 var c = (DkmSuccessEvaluationResult)children.InitialChildren[0];
                 r     = DkmSuccessEvaluationResult.Create(
                     c.InspectionContext,
                     c.StackFrame,
                     r.Name,
                     r.FullName,
                     c.Flags,
                     c.Value,
                     r.EditableValue,
                     r.Type,
                     r.Category,
                     r.Access,
                     r.StorageType,
                     r.TypeModifierFlags,
                     null,
                     r.CustomUIVisualizers,
                     null,
                     null
                     );
                 completionRoutine(new DkmEvaluationAsyncResult(r));
             }
                 );
         }
         else
         {
             completionRoutine(result);
         }
     }
         );
 }
Ejemplo n.º 6
0
        private void CreateEvaluationResultAndContinue(EvalResult result, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine <DkmEvaluationResult> completionRoutine)
        {
            switch (result.Kind)
            {
            case ExpansionKind.Error:
                completionRoutine(DkmFailedEvaluationResult.Create(
                                      inspectionContext,
                                      StackFrame: stackFrame,
                                      Name: result.Name,
                                      FullName: result.FullName,
                                      ErrorMessage: result.DisplayValue,
                                      Flags: DkmEvaluationResultFlags.None,
                                      Type: null,
                                      DataItem: null));
                break;

            case ExpansionKind.NativeView:
            {
                var value    = result.Value;
                var name     = Resources.NativeView;
                var fullName = result.FullName;
                var display  = result.Name;
                DkmEvaluationResult evalResult;
                if (value.IsError())
                {
                    evalResult = DkmFailedEvaluationResult.Create(
                        inspectionContext,
                        stackFrame,
                        Name: name,
                        FullName: fullName,
                        ErrorMessage: display,
                        Flags: result.Flags,
                        Type: null,
                        DataItem: result.ToDataItem());
                }
                else
                {
                    // For Native View, create a DkmIntermediateEvaluationResult.
                    // This will allow the C++ EE to take over expansion.
                    var process = inspectionContext.RuntimeInstance.Process;
                    var cpp     = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp));
                    evalResult = DkmIntermediateEvaluationResult.Create(
                        inspectionContext,
                        stackFrame,
                        Name: name,
                        FullName: fullName,
                        Expression: display,
                        IntermediateLanguage: cpp,
                        TargetRuntime: process.GetNativeRuntimeInstance(),
                        DataItem: result.ToDataItem());
                }
                completionRoutine(evalResult);
            }
            break;

            case ExpansionKind.NonPublicMembers:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      Name: Resources.NonPublicMembers,
                                      FullName: result.FullName,
                                      Flags: result.Flags,
                                      Value: null,
                                      EditableValue: null,
                                      Type: string.Empty,
                                      Category: DkmEvaluationResultCategory.Data,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: result.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: result.ToDataItem()));
                break;

            case ExpansionKind.StaticMembers:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      Name: StaticMembersString,
                                      FullName: result.FullName,
                                      Flags: result.Flags,
                                      Value: null,
                                      EditableValue: null,
                                      Type: string.Empty,
                                      Category: DkmEvaluationResultCategory.Class,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: result.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: result.ToDataItem()));
                break;

            case ExpansionKind.RawView:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      Name: Resources.RawView,
                                      FullName: result.FullName,
                                      Flags: result.Flags,
                                      Value: null,
                                      EditableValue: result.EditableValue,
                                      Type: string.Empty,
                                      Category: DkmEvaluationResultCategory.Data,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: result.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: result.ToDataItem()));
                break;

            case ExpansionKind.DynamicView:
            case ExpansionKind.ResultsView:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      result.Name,
                                      result.FullName,
                                      result.Flags,
                                      result.DisplayValue,
                                      EditableValue: null,
                                      Type: string.Empty,
                                      Category: DkmEvaluationResultCategory.Method,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: result.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: result.ToDataItem()));
                break;

            case ExpansionKind.TypeVariable:
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      result.Name,
                                      result.FullName,
                                      result.Flags,
                                      result.DisplayValue,
                                      EditableValue: null,
                                      Type: result.DisplayValue,
                                      Category: DkmEvaluationResultCategory.Data,
                                      Access: DkmEvaluationResultAccessType.None,
                                      StorageType: DkmEvaluationResultStorageType.None,
                                      TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None,
                                      Address: result.Value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: result.ToDataItem()));
                break;

            case ExpansionKind.PointerDereference:
            case ExpansionKind.Default:
                // This call will evaluate DebuggerDisplayAttributes.
                GetResultAndContinue(
                    result,
                    workList,
                    declaredType: result.DeclaredTypeAndInfo.ClrType,
                    declaredTypeInfo: result.DeclaredTypeAndInfo.Info,
                    inspectionContext: inspectionContext,
                    useDebuggerDisplay: result.UseDebuggerDisplay,
                    completionRoutine: completionRoutine);
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(result.Kind);
            }
        }
Ejemplo n.º 7
0
/*		public override DkmChildVisualizedExpression GetMostDerived()
 *              {
 *                      foreach (var child in MemberExpressions)
 *                      {
 *                              var eval = child.Value.EvaluationResult as DkmSuccessEvaluationResult;
 *                              if (eval != null && eval.Category == DkmEvaluationResultCategory.MostDerivedClass)
 *                              {
 *                                      return child.Value;
 *                              }
 *                      }
 *
 *                      return null;
 *              }
 */
        private void EvaluateChildren()
        {
            MemberExpressions = new Dictionary <string, DkmChildVisualizedExpression>();

            // @TODO: Am assuming that if expr_ is a child expression, it would be more
            // efficient to use its EvaluationResult property instead of invoking the default
            // evaluator again. However, doing this results in using child UObject expressions which
            // have been generated using the custom visualization (since ! specifier is not recursive).
            // We really don't want this since we just want the default expansion so we can navigate
            // through the members and bases of the class.
            // Problem is, don't know how to communicate to the 'UseDefaultEvaluationBehavior'
            // implementation to use a default expansion in this particular case. Setting the data
            // item on expr_ before calling GetItemsCallback doesn't work, since the expression that
            // gets passed through is not actually expr_, but a root visualized expression that was
            // created by the EE when visualizing the parent, which we don't have access to.

            // As it is, now that we inline the default expansion alongside the addition of the
            // 'UE4 Properties' child, this does seem to work. However, not obvious there is any
            // performance improvement, also not 100% sure it's safe to use the stored evaluation.
            DkmEvaluationResult uobj_eval = null;

            if (expr_.TagValue == DkmVisualizedExpression.Tag.ChildVisualizedExpression)
            {
                uobj_eval = ((DkmChildVisualizedExpression)expr_).EvaluationResult;
            }
            else
            {
                uobj_eval = DefaultEE.DefaultEval(callback_expr_, true);
            }
            eval_ = (DkmSuccessEvaluationResult)uobj_eval;

            DkmEvaluationResult[]          children;
            DkmEvaluationResultEnumContext enum_context;

            try
            {
                callback_expr_.GetChildrenCallback(uobj_eval, 0, callback_expr_.InspectionContext, out children, out enum_context);
                // @NOTE: Assuming count will not be large here!!
                callback_expr_.GetItemsCallback(enum_context, 0, enum_context.Count, out children);
            }
            catch
            {
                return;
            }

            uint idx = 0;

            foreach (var child_eval in children)
            {
                if (child_eval.TagValue == DkmEvaluationResult.Tag.SuccessResult)
                {
                    var success_eval = child_eval as DkmSuccessEvaluationResult;
                    Debug.Assert(success_eval != null);

                    DkmExpressionValueHome home;
                    if (success_eval.Address != null)
                    {
                        home = DkmPointerValueHome.Create(success_eval.Address.Value);
                    }
                    else
                    {
                        home = DkmFakeValueHome.Create(0);
                    }
                    DkmChildVisualizedExpression child = DkmChildVisualizedExpression.Create(
                        child_eval.InspectionContext,
                        callback_expr_.VisualizerId,
                        callback_expr_.SourceId,
                        child_eval.StackFrame,
                        home,
                        child_eval,
                        expr_,
                        idx,
                        null
                        );
                    MemberExpressions[child_eval.Name] = child;
                }

                ++idx;
            }
        }
Ejemplo n.º 8
0
        private void GetRootResultAndContinue(DkmClrValue value, WorkList workList, DkmClrType declaredType, DkmInspectionContext inspectionContext, string name, CompletionRoutine <DkmEvaluationResult> completionRoutine)
        {
            var type = value.Type.GetLmrType();

            if (type.IsTypeVariables())
            {
                var expansion = new TypeVariablesExpansion(type);
                var dataItem  = new EvalResultDataItem(
                    ExpansionKind.Default,
                    name,
                    typeDeclaringMember: null,
                    declaredType: type,
                    parent: null,
                    value: value,
                    displayValue: null,
                    expansion: expansion,
                    childShouldParenthesize: false,
                    fullName: null,
                    childFullNamePrefixOpt: null,
                    formatSpecifiers: Formatter.NoFormatSpecifiers,
                    category: DkmEvaluationResultCategory.Data,
                    flags: DkmEvaluationResultFlags.ReadOnly,
                    editableValue: null,
                    inspectionContext: inspectionContext);

                Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable));

                // Note: We're not including value.EvalFlags in Flags parameter
                // below (there shouldn't be a reason to do so).
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      InspectionContext: inspectionContext,
                                      StackFrame: value.StackFrame,
                                      Name: Resources.TypeVariablesName,
                                      FullName: dataItem.FullName,
                                      Flags: dataItem.Flags,
                                      Value: "",
                                      EditableValue: null,
                                      Type: "",
                                      Category: dataItem.Category,
                                      Access: value.Access,
                                      StorageType: value.StorageType,
                                      TypeModifierFlags: value.TypeModifierFlags,
                                      Address: value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: dataItem));
            }
            else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0)
            {
                CreateEvaluationResultAndContinue(
                    ResultsViewExpansion.CreateResultsOnlyRow(inspectionContext, name, declaredType, value, this.Formatter),
                    workList,
                    inspectionContext,
                    value.StackFrame,
                    completionRoutine);
            }
            else
            {
                var dataItem = ResultsViewExpansion.CreateResultsOnlyRowIfSynthesizedEnumerable(inspectionContext, name, declaredType, value, this.Formatter);
                if (dataItem != null)
                {
                    CreateEvaluationResultAndContinue(
                        dataItem,
                        workList,
                        inspectionContext,
                        value.StackFrame,
                        completionRoutine);
                }
                else
                {
                    ReadOnlyCollection <string> formatSpecifiers;
                    var fullName = this.Formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers);
                    dataItem = CreateDataItem(
                        inspectionContext,
                        name,
                        typeDeclaringMember: null,
                        declaredType: declaredType.GetLmrType(),
                        value: value,
                        parent: null,
                        expansionFlags: ExpansionFlags.All,
                        childShouldParenthesize: this.Formatter.NeedsParentheses(fullName),
                        fullName: fullName,
                        formatSpecifiers: formatSpecifiers,
                        category: DkmEvaluationResultCategory.Other,
                        flags: value.EvalFlags,
                        evalFlags: inspectionContext.EvaluationFlags);
                    GetResultAndContinue(dataItem, workList, declaredType, inspectionContext, parent: null, completionRoutine: completionRoutine);
                }
            }
        }
Ejemplo n.º 9
0
        private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine <DkmEvaluationResult> completionRoutine)
        {
            switch (dataItem.Kind)
            {
            case ExpansionKind.Error:
                completionRoutine(DkmFailedEvaluationResult.Create(
                                      inspectionContext,
                                      StackFrame: stackFrame,
                                      Name: dataItem.Name,
                                      FullName: dataItem.FullName,
                                      ErrorMessage: dataItem.DisplayValue,
                                      Flags: DkmEvaluationResultFlags.None,
                                      Type: null,
                                      DataItem: null));
                break;

            case ExpansionKind.NonPublicMembers:
            case ExpansionKind.StaticMembers:
                completionRoutine(CreateEvaluationResult(
                                      inspectionContext,
                                      dataItem.Value,
                                      dataItem.Name,
                                      typeName: string.Empty,
                                      display: null,
                                      dataItem: dataItem));
                break;

            case ExpansionKind.RawView:
                completionRoutine(CreateEvaluationResult(
                                      inspectionContext,
                                      dataItem.Value,
                                      Resources.RawView,
                                      typeName: string.Empty,
                                      display: null,
                                      dataItem: dataItem));
                break;

            case ExpansionKind.ResultsView:
                completionRoutine(CreateEvaluationResult(
                                      inspectionContext,
                                      dataItem.Value,
                                      dataItem.Name,
                                      typeName: string.Empty,
                                      display: Resources.ResultsViewValueWarning,
                                      dataItem: dataItem));
                break;

            case ExpansionKind.TypeVariables:
                var value = dataItem.Value;
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      inspectionContext,
                                      stackFrame,
                                      dataItem.Name,
                                      dataItem.FullName,
                                      dataItem.Flags,
                                      dataItem.DisplayValue,
                                      EditableValue: null,
                                      Type: dataItem.DisplayValue,
                                      Category: dataItem.Category,
                                      Access: value.Access,
                                      StorageType: value.StorageType,
                                      TypeModifierFlags: value.TypeModifierFlags,
                                      Address: value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: dataItem));
                break;

            default:
                Debug.Assert((dataItem.Kind == ExpansionKind.Default) || (dataItem.Kind == ExpansionKind.PointerDereference));
                // This call will evaluate DebuggerDisplayAttributes.
                GetResultAndContinue(
                    dataItem,
                    workList,
                    declaredType: DkmClrType.Create(dataItem.Value.Type.AppDomain, dataItem.DeclaredType),
                    inspectionContext: inspectionContext,
                    parent: dataItem.Parent,
                    completionRoutine: completionRoutine);
                break;
            }
        }
Ejemplo n.º 10
0
        protected void EvaluateExpressionResult()
        {
            // We're going to customize the unexpanded display string, as well as the expanded
            // view (if requested later).

            // @TODO: Really don't understand why, but when we invoke the default eval below, and we get
            // reentrant calls for child member UObjects, they are coming back as root expressions
            // with an empty FullName. This subsequently fails to evaluate if we pass it through to
            // default eval again. Perhaps this is somehow related to breaking the potential infinite
            // recursion of visualizing children in order to visualize the parent, but don't follow how it
            // it supposed to be dealt with.
            if (expression_.TagValue == DkmVisualizedExpression.Tag.RootVisualizedExpression)
            {
                var as_root = expression_ as DkmRootVisualizedExpression;
                if (as_root.FullName.Length == 0)
                {
                    string display_str = "{...}";
                    eval_ = DkmSuccessEvaluationResult.Create(
                        expression_.InspectionContext,
                        expression_.StackFrame,
                        as_root.Name,
                        as_root.Name,
                        DkmEvaluationResultFlags.ReadOnly,
                        display_str,
                        "",
#if !VS2013
                        as_root.Type,
#else
                        "Unknown",
#endif
                        DkmEvaluationResultCategory.Other,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null,
                        null,
                        null,
                        null
                        );
                    state_ = EvaluationState.MinimalEvaluation;
                    return;
                }
            }
            //

            string custom_display_str             = Resources.UE4PropVis.IDS_DISP_CONDENSED;
            DkmSuccessEvaluationResult proto_eval = null;
            bool   is_pointer;
            bool   is_null;
            string address_str = "";

            // @NOTE: Initially here we were executing the full default evaluation of our expression.
            // Problem is that this will call back into us for all UObject children of the expression,
            // because it needs to generate a visualization for them in order to construct its {member vals...} display string.
            // And then, we just ignore that anyway and display our own...

            // The following attempts to avoid that by casting our expression to void* and then evaluating that.
            // If it fails, we assume we are non-pointer. If it succeeds, we can determine from the result whether we are null or not.

            // @WARNING: This may not be so safe, since we can't determine whether evaluation failed because we tried to cast a non-pointer
            // to void*, or because the passed in expression was not valid in the first place. Believe we should be okay, since we should
            // only be receiving expressions that have already been determined to be suitable for our custom visualizer.

            // Ideally though, we'd be able to get a raw expression evaluation, without any visualization taking place.
            // Seems there must be a way to do this, but looks like it requires using a different API...
            const bool UseVoidCastOptimization = true;

            string default_expr_str = Utility.GetExpressionFullName(expression_);
            if (UseVoidCastOptimization)
            {
                default_expr_str = ExpressionManipulator.FromExpression(default_expr_str).PtrCast(Cpp.Void).Expression;
            }

            DkmEvaluationResult eval = DefaultEE.DefaultEval(default_expr_str, expression_, true);

            if (!UseVoidCastOptimization)
            {
                if (eval.TagValue != DkmEvaluationResult.Tag.SuccessResult)
                {
                    // Genuine failure to evaluate the passed in expression
                    eval_  = eval;
                    state_ = EvaluationState.Failed;
                    return;
                }
                else
                {
                    proto_eval         = (DkmSuccessEvaluationResult)eval;
                    custom_display_str = proto_eval.Value;

                    is_pointer = IsPointer(proto_eval);
                    is_null    = is_pointer && IsPointerNull(proto_eval);
                    // @TODO: need to extract address string
                }
            }
            else
            {
                DkmDataAddress address = null;
                if (eval.TagValue != DkmEvaluationResult.Tag.SuccessResult)
                {
                    // Assume the failure just implies the expression was non-pointer (thereby assuming that it was itself valid!)

                    // @TODO: Could actually fall back onto standard evaluation here, in order to determine for sure
                    // that the original expression is valid. Failure wouldn't be common since most of the time we are
                    // dealing with pointer expressions, so any potential optimization should still be gained.

                    is_pointer = false;
                    is_null    = false;
                }
                else
                {
                    var success = (DkmSuccessEvaluationResult)eval;
                    Debug.Assert(IsPointer(success));
                    is_pointer  = true;
                    is_null     = is_pointer && IsPointerNull(success);
                    address     = success.Address;
                    address_str = success.Value;
                }

                proto_eval = DkmSuccessEvaluationResult.Create(
                    expression_.InspectionContext,
                    expression_.StackFrame,
                    "",
                    "",
                    DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable,
                    "",
                    "",
#if !VS2013
                    Utility.GetExpressionType(expression_),
#else
                    is_pointer ? "UObject *" : "UObject",
#endif
                    DkmEvaluationResultCategory.Other,
                    DkmEvaluationResultAccessType.None,
                    DkmEvaluationResultStorageType.None,
                    DkmEvaluationResultTypeModifierFlags.None,
                    address,
                    null,
                    null,
                    null
                    );
            }

            string obj_expression_str = Utility.GetExpressionFullName(expression_);
            var    obj_em             = ExpressionManipulator.FromExpression(obj_expression_str);

            // Store pointer flags on the expression
            expression_.SetDataItem(
                DkmDataCreationDisposition.CreateAlways,
                new UObjectDataItem(is_pointer, is_null)
                );

            if (!is_pointer)
            {
                // All subsequent manipulations of the expression assume it starts as a pointer to a
                // UObject-derived class, so if our expression is to a dereferenced UObject, just
                // prefix an 'address of' to the expression string.
                obj_em = obj_em.AddressOf();
            }

            // Generate the condensed display string.
            if (is_null)
            {
                if (Config.CustomNullObjectPreview)
                {
                    custom_display_str = "<NULL> UObject";
                }
                else
                {
                    var null_eval = DefaultEE.DefaultEval("(void*)0", expression_, true) as DkmSuccessEvaluationResult;
                    custom_display_str = null_eval.Value + " <NULL>";
                }
            }
            else if (Config.DisplayUObjectPreview)
            {
                // Prefix the address, if this is a pointer expression
                string address_prefix_str = "";
                if (is_pointer)
                {
                    address_prefix_str = address_str + " ";
                }

                // Specialized display for UClass?
                bool uclass_specialized = false;
                if (Config.DisplaySpecializedUClassPreview)
                {
                    var    uclass_em = obj_em.PtrCast(Typ.UObjectBase).PtrMember(Memb.ObjClass);
                    var    _uclass_fname_expr_str = uclass_em.PtrCast(Typ.UObjectBase).PtrMember(Memb.ObjName).Expression;
                    string _obj_uclass_name_str   = UE4Utility.GetFNameAsString(_uclass_fname_expr_str, expression_);
                    // @TODO: To simplify and for performance reasons, just hard coding known UClass variants
                    if (_obj_uclass_name_str == "Class" ||
                        _obj_uclass_name_str == "BlueprintGeneratedClass" ||
                        _obj_uclass_name_str == "WidgetBlueprintGeneratedClass")
                    {
                        var    fname_expr_str = obj_em.PtrCast(Typ.UObjectBase).PtrMember(Memb.ObjName).Expression;
                        string obj_name_str   = UE4Utility.GetFNameAsString(fname_expr_str, expression_);

                        var parent_uclass_fname_expr_str = obj_em.PtrCast(Typ.UStruct).PtrMember(Memb.SuperStruct).PtrCast(Typ.UObjectBase).PtrMember(Memb.ObjName).Expression;
                        // This will return null if lookup failed for any reason.
                        // We'll assume this meant no super class exists (ie. we're dealing with UClass itself)
                        string parent_uclass_name_str = UE4Utility.GetFNameAsString(parent_uclass_fname_expr_str, expression_);
                        if (parent_uclass_name_str == null)
                        {
                            parent_uclass_name_str = "None";
                        }

                        custom_display_str = String.Format(
                            "{0}{{ClassName='{1}', Parent='{2}'}}",
                            address_prefix_str,
                            obj_name_str,
                            parent_uclass_name_str
                            );
                        uclass_specialized = true;
                    }
                }

                if (!uclass_specialized)
                {
                    // For standard UObject condensed display string, show the object FName and its UClass.
                    // @TODO: The evaluations required for this may be a performance issue, since they'll be done for all UObject children of any default visualized
                    // aggregate type, even when it is not expanded (the default behaviour is to create a {...} display list of child member visualizations).
                    var    fname_expr_str = obj_em.PtrCast(Typ.UObjectBase).PtrMember(Memb.ObjName).Expression;
                    string obj_name_str   = UE4Utility.GetFNameAsString(fname_expr_str, expression_);

                    var    uclass_fname_expr_str = obj_em.PtrCast(Typ.UObjectBase).PtrMember(Memb.ObjClass).PtrCast(Typ.UObjectBase).PtrMember(Memb.ObjName).Expression;
                    string obj_uclass_name_str   = UE4Utility.GetFNameAsString(uclass_fname_expr_str, expression_);

                    custom_display_str = String.Format(
                        "{0}{{Name='{1}', Class='{2}'}}",
                        address_prefix_str,
                        obj_name_str,
                        obj_uclass_name_str
                        );
                }
            }

            eval_ = DkmSuccessEvaluationResult.Create(
                proto_eval.InspectionContext,
                proto_eval.StackFrame,
                // Override the eval name with the original expression name, since it will
                // have inherited the ",!" suffix.
                Utility.GetExpressionName(expression_),
                Utility.GetExpressionFullName(expression_),
                proto_eval.Flags,
                custom_display_str,                //success_eval.Value,
                proto_eval.EditableValue,
                proto_eval.Type,
                proto_eval.Category,
                proto_eval.Access,
                proto_eval.StorageType,
                proto_eval.TypeModifierFlags,
                proto_eval.Address,
                proto_eval.CustomUIVisualizers,
                proto_eval.ExternalModules,
                null
                );
            state_ = EvaluationState.Evaluated;
        }
Ejemplo n.º 11
0
        private static DkmEvaluationResult CreateEvaluationResult(
            DkmInspectionContext inspectionContext,
            DkmClrValue value,
            string name,
            string typeName,
            string display,
            EvalResultDataItem dataItem)
        {
            if (value.IsError())
            {
                // Evaluation failed
                return(DkmFailedEvaluationResult.Create(
                           InspectionContext: inspectionContext,
                           StackFrame: value.StackFrame,
                           Name: name,
                           FullName: dataItem.FullName,
                           ErrorMessage: display,
                           Flags: dataItem.Flags,
                           Type: typeName,
                           DataItem: dataItem));
            }
            else if (dataItem.Kind == ExpansionKind.NativeView)
            {
                // For Native View, create a DkmIntermediateEvaluationResult.  This will allow the C++ EE
                // to take over expansion.
                DkmProcess  process = inspectionContext.RuntimeInstance.Process;
                DkmLanguage cpp     = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp));
                return(DkmIntermediateEvaluationResult.Create(
                           InspectionContext: inspectionContext,
                           StackFrame: value.StackFrame,
                           Name: Resources.NativeView,
                           FullName: dataItem.FullName,
                           Expression: dataItem.Name,
                           IntermediateLanguage: cpp,
                           TargetRuntime: process.GetNativeRuntimeInstance(),
                           DataItem: dataItem));
            }
            else
            {
                ReadOnlyCollection <DkmCustomUIVisualizerInfo> customUIVisualizers = null;

                if (!value.IsNull)
                {
                    DkmCustomUIVisualizerInfo[] customUIVisualizerInfo = value.Type.GetDebuggerCustomUIVisualizerInfo();
                    if (customUIVisualizerInfo != null)
                    {
                        customUIVisualizers = new ReadOnlyCollection <DkmCustomUIVisualizerInfo>(customUIVisualizerInfo);
                    }
                }

                // If the EvalResultData item doesn't specify a particular category, we'll just propagate DkmClrValue.Category,
                // which typically appears to be set to the default value ("Other").
                var category = (dataItem.Category != DkmEvaluationResultCategory.Other) ? dataItem.Category : value.Category;

                // Valid value
                return(DkmSuccessEvaluationResult.Create(
                           InspectionContext: inspectionContext,
                           StackFrame: value.StackFrame,
                           Name: name,
                           FullName: dataItem.FullName,
                           Flags: dataItem.Flags,
                           Value: display,
                           EditableValue: dataItem.EditableValue,
                           Type: typeName,
                           Category: category,
                           Access: value.Access,
                           StorageType: value.StorageType,
                           TypeModifierFlags: value.TypeModifierFlags,
                           Address: value.Address,
                           CustomUIVisualizers: customUIVisualizers,
                           ExternalModules: null,
                           DataItem: dataItem));
            }
        }
Ejemplo n.º 12
0
 // Assumes already confirmed that we are dealing with a pointer
 protected bool IsPointerNull(DkmSuccessEvaluationResult eval)
 {
     return(eval.Address.Value == 0);
 }
Ejemplo n.º 13
0
 protected bool IsPointer(DkmSuccessEvaluationResult eval)
 {
     // @TODO: Confirm reliable. Alternative is to check for '*' within Type property.
     return(eval.Flags.HasFlag(DkmEvaluationResultFlags.Address));
 }
Ejemplo n.º 14
0
        public override void GetChildItems(DkmEvaluationResultEnumContext enumContext, int start, int count, out DkmChildVisualizedExpression[] items)
        {
            // Cap the requested number to the total remaining from startIndex
            count = Math.Min(count, enumContext.Count - start);
            items = new DkmChildVisualizedExpression[count];
            uint idx = 0;

            // Retrieve the default expansion enum context
            var default_data = enumContext.GetDataItem <DefaultEnumContextDataItem>();

            if (start < default_data.Context.Count)
            {
                // Requesting default children

                int default_count = Math.Min(count, default_data.Context.Count - start);
                DkmEvaluationResult[] default_evals;
                expression_.GetItemsCallback(default_data.Context, start, default_count, out default_evals);
                for (int dft_idx = 0; dft_idx < default_count; ++dft_idx, ++idx)
                {
                    DkmSuccessEvaluationResult success_eval = default_evals[dft_idx] as DkmSuccessEvaluationResult;
                    DkmExpressionValueHome     home         = null;
                    if (success_eval != null && success_eval.Address != null)
                    {
                        home = DkmPointerValueHome.Create(success_eval.Address.Value);
                    }
                    else
                    {
                        home = DkmFakeValueHome.Create(0);
                    }

                    items[idx] = DkmChildVisualizedExpression.Create(
                        enumContext.InspectionContext,
                        expression_.VisualizerId,                               // @TODO: Check this is what we want. Will we get callbacks for it, regardless of its type?
                        expression_.SourceId,
                        enumContext.StackFrame,
                        home,
                        default_evals[dft_idx],
                        expression_,
                        (uint)start,
                        null
                        );
                }
            }

            if (start + count > default_data.Context.Count)
            {
                // Requesting custom children
                // @NOTE: Currently just assuming only 1 custom child (prop list) and hard coding as such.

                // DkmSuccessEvaluationResult.ExtractFromProperty(IDebugProperty3!!!!!!!) ...............................................

                // @NOTE: Had thought could just create an expression with a null evaluation
                // inside it, and by giving it a visualizer guid, the system would call back
                // to us to evaluate the expression. Seems not to work though, I guess because the
                // visualizer guid identifies the visualizer but not the containing component,
                // and since the expression itself doesn't have a type, it can't know that it
                // should call our component.
                DkmEvaluationResult eval = DkmSuccessEvaluationResult.Create(
                    enumContext.InspectionContext,
                    enumContext.StackFrame,
                    Resources.UE4PropVis.IDS_DISP_BLUEPRINTPROPERTIES,
                    Resources.UE4PropVis.IDS_DISP_BLUEPRINTPROPERTIES,
                    DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable,
                    "",                         // @TODO: something like "[<count> properties]"
                    null,
                    "",                         // Type column
                    DkmEvaluationResultCategory.Other,
                    DkmEvaluationResultAccessType.None,
                    DkmEvaluationResultStorageType.None,
                    DkmEvaluationResultTypeModifierFlags.None,
                    null,
                    null,
                    null,
                    null
                    );

                // This child is just for organization and does not correspond to anything in memory.
                DkmExpressionValueHome valueHome = DkmFakeValueHome.Create(0);

                var prop_list_expr = DkmChildVisualizedExpression.Create(
                    enumContext.InspectionContext,
                    Guids.Visualizer.PropertyList,
                    // Associate the expression with ourselves, since we created it
                    Guids.Component.VisualizerComponent,
                    enumContext.StackFrame,
                    valueHome,
                    eval,
                    expression_,
                    idx,
                    null
                    );

                // Create a visualizer for the property list, and attach it to the expression.
                var prop_list_visualizer = new PropertyListVisualizer(prop_list_expr, access_ctx_);
                prop_list_expr.SetDataItem(DkmDataCreationDisposition.CreateAlways, new ExpressionDataItem(prop_list_visualizer));

                items[idx] = prop_list_expr;
            }
        }
Ejemplo n.º 15
0
 DkmClrValue IDkmClrResultProvider.GetClrValue(DkmSuccessEvaluationResult successResult)
 {
     return(successResult.GetClrValue());
 }
        public void EvaluateVisualizedExpression(DkmVisualizedExpression visualizedExpression, out DkmEvaluationResult resultObject)
        {
            var rootExpr = visualizedExpression as DkmRootVisualizedExpression;

            if (rootExpr == null)
            {
                Debug.Fail("PythonViewNativeVisualizer.EvaluateVisualizedExpression was given a visualized expression that is not a DkmRootVisualizedExpression.");
                throw new NotSupportedException();
            }

            DkmEvaluationResult       rawResult;
            RawEvaluationResultHolder rawResultHolder;

            using (var rawExpr = DkmLanguageExpression.Create(CppExpressionEvaluator.CppLanguage, DkmEvaluationFlags.ShowValueRaw, rootExpr.FullName + ",!", null)) {
                rootExpr.EvaluateExpressionCallback(rootExpr.InspectionContext, rawExpr, rootExpr.StackFrame, out rawResult);
                rawResultHolder = new RawEvaluationResultHolder {
                    RawResult = rawResult
                };
                rootExpr.SetDataItem(DkmDataCreationDisposition.CreateAlways, rawResultHolder);
            }

            var rawSuccessResult = rawResult as DkmSuccessEvaluationResult;

            if (rawSuccessResult != null)
            {
                resultObject = DkmSuccessEvaluationResult.Create(
                    rawResult.InspectionContext,
                    rawResult.StackFrame,
                    rootExpr.Name,
                    rawSuccessResult.FullName,
                    rawSuccessResult.Flags,
                    rawSuccessResult.Value,
                    rawSuccessResult.EditableValue,
                    rawSuccessResult.Type,
                    rawSuccessResult.Category,
                    rawSuccessResult.Access,
                    rawSuccessResult.StorageType,
                    rawSuccessResult.TypeModifierFlags,
                    rawSuccessResult.Address,
                    rawSuccessResult.CustomUIVisualizers,
                    rawSuccessResult.ExternalModules,
                    rawResultHolder);
                return;
            }

            var rawFailedResult = rawResult as DkmFailedEvaluationResult;

            if (rawFailedResult != null)
            {
                resultObject = DkmFailedEvaluationResult.Create(
                    rawResult.InspectionContext,
                    rawResult.StackFrame,
                    rootExpr.Name,
                    rootExpr.FullName,
                    rawFailedResult.ErrorMessage,
                    rawFailedResult.Flags,
                    rawResultHolder);
                return;
            }

            Debug.Fail("Raw evaluation result was neither DkmSuccessEvaluationResult nor DkmFailedEvaluationResult.");
            throw new NotSupportedException();
        }
Ejemplo n.º 17
0
 public DkmClrValue GetClrValue(DkmSuccessEvaluationResult successResult)
 {
     return(successResult.GetClrValue());
 }
Ejemplo n.º 18
0
        protected DkmEvaluationResult GeneratePropertyValueEval(string container_expr_str, string uprop_expr_str, uint index, DkmVisualizedExpression context_expr)
        {
            Debug.Print("UE4PV: Trying to generate property value for property #{0}", index + 1);

            var uprop_em = ExpressionManipulator.FromExpression(uprop_expr_str);

            // Get name of property
            string prop_name_expr_str = uprop_em.PtrCast(Typ.UObjectBase).PtrMember(Memb.ObjName).Expression;
            string prop_name          = UE4Utility.GetFNameAsString(prop_name_expr_str, context_expr);

            // And the property type
            string prop_type = GetPropertyType(uprop_em.Expression, context_expr);

            // Now, determine address of the actual property value
            // First requires container address
            // Cast to void* first, so that expression evaluation is simplified and faster
            container_expr_str = ExpressionManipulator.FromExpression(container_expr_str).PtrCast(Cpp.Void).Expression;
            var container_eval = DefaultEE.DefaultEval(container_expr_str, context_expr, true) as DkmSuccessEvaluationResult;

            Debug.Assert(container_eval != null && container_eval.Address != null);
            string address_str = container_eval.Address.Value.ToString();

            // Next need offset in container (which is an int32 property of the UProperty class)
            var    offset_expr_str = uprop_em.PtrMember(Memb.PropOffset).Expression;
            var    offset_eval     = DefaultEE.DefaultEval(offset_expr_str, context_expr, true) as DkmSuccessEvaluationResult;
            string offset_str      = offset_eval.Value;

            // Then need to create an expression which adds on the offset
            address_str = String.Format("((uint8*){0} + {1})", address_str, offset_str);

            // Next, we need to cast this expression depending on the type of property we have.
            // Retrieve a list of possible cast expressions.
            var cpp_type_info_list = GetCppTypeForPropertyType(prop_type, uprop_em.Expression, context_expr);
            // Accept the first one that is successfully evaluated
            DkmSuccessEvaluationResult success_eval = null;
            string display_type = null;

            foreach (var cpp_type_info in cpp_type_info_list)
            {
                string prop_value_expr_str = AdjustPropertyExpressionStringForType(address_str, prop_type, uprop_em.Expression, context_expr, cpp_type_info);

                Debug.Print("UE4PV: Attempting exp eval as: '{0}'", prop_value_expr_str);

                // Attempt to evaluate the expression
                DkmEvaluationResult raw_eval = DefaultEE.DefaultEval(prop_value_expr_str, context_expr, false);
                if (raw_eval.TagValue == DkmEvaluationResult.Tag.SuccessResult)
                {
                    // Success
                    success_eval = raw_eval as DkmSuccessEvaluationResult;
                    display_type = cpp_type_info.Display;
                    break;
                }
            }

            if (success_eval == null)
            {
                // Was not able to find an evaluatable expression.
                return(null);
            }

            return(DkmSuccessEvaluationResult.Create(
                       expression_.InspectionContext,
                       expression_.StackFrame,
                       prop_name,
                       success_eval.FullName,         //prop_value_expr_str,
                       success_eval.Flags,
                       success_eval.Value,
                       // @TODO: Perhaps need to disable for some stuff, like bitfield bool?
                       success_eval.EditableValue,
                       display_type,         //success_eval.Type,
                       success_eval.Category,
                       success_eval.Access,
                       success_eval.StorageType,
                       success_eval.TypeModifierFlags,
                       success_eval.Address,
                       success_eval.CustomUIVisualizers,
                       success_eval.ExternalModules,
                       null
                       ));
        }
Ejemplo n.º 19
0
        private void GetRootResultAndContinue(
            DkmClrValue value,
            WorkList workList,
            DkmClrType declaredType,
            DkmClrCustomTypeInfo declaredTypeInfo,
            DkmInspectionContext inspectionContext,
            string name,
            string fullName,
            ReadOnlyCollection <string> formatSpecifiers,
            CompletionRoutine <DkmEvaluationResult> completionRoutine)
        {
            Debug.Assert(formatSpecifiers != null);

            var type = value.Type.GetLmrType();

            if (type.IsTypeVariables())
            {
                Debug.Assert(type.Equals(declaredType.GetLmrType()));
                var declaredTypeAndInfo = new TypeAndCustomInfo(declaredType, declaredTypeInfo);
                var expansion           = new TypeVariablesExpansion(declaredTypeAndInfo);
                var dataItem            = new EvalResult(
                    ExpansionKind.Default,
                    name,
                    typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                    declaredTypeAndInfo: declaredTypeAndInfo,
                    useDebuggerDisplay: false,
                    value: value,
                    displayValue: null,
                    expansion: expansion,
                    childShouldParenthesize: false,
                    fullName: null,
                    childFullNamePrefixOpt: null,
                    formatSpecifiers: Formatter.NoFormatSpecifiers,
                    category: DkmEvaluationResultCategory.Data,
                    flags: DkmEvaluationResultFlags.ReadOnly,
                    editableValue: null,
                    inspectionContext: inspectionContext);

                Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable));

                // Note: We're not including value.EvalFlags in Flags parameter
                // below (there shouldn't be a reason to do so).
                completionRoutine(DkmSuccessEvaluationResult.Create(
                                      InspectionContext: inspectionContext,
                                      StackFrame: value.StackFrame,
                                      Name: Resources.TypeVariablesName,
                                      FullName: dataItem.FullName,
                                      Flags: dataItem.Flags,
                                      Value: "",
                                      EditableValue: null,
                                      Type: "",
                                      Category: dataItem.Category,
                                      Access: value.Access,
                                      StorageType: value.StorageType,
                                      TypeModifierFlags: value.TypeModifierFlags,
                                      Address: value.Address,
                                      CustomUIVisualizers: null,
                                      ExternalModules: null,
                                      DataItem: dataItem.ToDataItem()));
            }
            else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0)
            {
                var dataItem = ResultsViewExpansion.CreateResultsOnlyRow(
                    inspectionContext,
                    name,
                    fullName,
                    formatSpecifiers,
                    declaredType,
                    declaredTypeInfo,
                    value,
                    this);
                CreateEvaluationResultAndContinue(
                    dataItem,
                    workList,
                    inspectionContext,
                    value.StackFrame,
                    completionRoutine);
            }
            else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.DynamicView) != 0)
            {
                var dataItem = DynamicViewExpansion.CreateMembersOnlyRow(
                    inspectionContext,
                    name,
                    value,
                    this);
                CreateEvaluationResultAndContinue(
                    dataItem,
                    workList,
                    inspectionContext,
                    value.StackFrame,
                    completionRoutine);
            }
            else
            {
                var dataItem = ResultsViewExpansion.CreateResultsOnlyRowIfSynthesizedEnumerable(
                    inspectionContext,
                    name,
                    fullName,
                    formatSpecifiers,
                    declaredType,
                    declaredTypeInfo,
                    value,
                    this);
                if (dataItem != null)
                {
                    CreateEvaluationResultAndContinue(
                        dataItem,
                        workList,
                        inspectionContext,
                        value.StackFrame,
                        completionRoutine);
                }
                else
                {
                    var useDebuggerDisplay = (inspectionContext.EvaluationFlags & NotRoot) != 0;
                    var expansionFlags     = (inspectionContext.EvaluationFlags & NoResults) != 0 ?
                                             ExpansionFlags.IncludeBaseMembers :
                                             ExpansionFlags.All;
                    dataItem = CreateDataItem(
                        inspectionContext,
                        name,
                        typeDeclaringMemberAndInfo: default(TypeAndCustomInfo),
                        declaredTypeAndInfo: new TypeAndCustomInfo(declaredType, declaredTypeInfo),
                        value: value,
                        useDebuggerDisplay: useDebuggerDisplay,
                        expansionFlags: expansionFlags,
                        childShouldParenthesize: (fullName == null) ? false : FullNameProvider.ClrExpressionMayRequireParentheses(inspectionContext, fullName),
                        fullName: fullName,
                        formatSpecifiers: formatSpecifiers,
                        category: DkmEvaluationResultCategory.Other,
                        flags: value.EvalFlags,
                        evalFlags: inspectionContext.EvaluationFlags);
                    GetResultAndContinue(dataItem, workList, declaredType, declaredTypeInfo, inspectionContext, useDebuggerDisplay, completionRoutine);
                }
            }
        }
        PointCloudVisualizationData parseMembers(DkmSuccessEvaluationResult eval)
        {
            PointCloudVisualizationData members = new PointCloudVisualizationData();

            {
                Regex pattern = new Regex(@"\[size\]=(\d+)");
                Match match   = pattern.Match(eval.Value);
                if (match.Groups.Count > 1)
                {
                    members.size = int.Parse(match.Groups[1].Value);
                }
                else
                {
                    members.size = 0;
                }
            }
            {
                Regex pattern = new Regex(@"\[positions\]=(0x[0-9A-Fa-f]+)");
                Match match   = pattern.Match(eval.Value);

                if (match.Groups.Count > 1)
                {
                    members.positionPtr = match.Groups[1].Value;
                }
                else
                {
                    members.positionPtr = null;
                }
            }
            {
                Regex pattern = new Regex(@"\[normals\]=(0x[0-9A-Fa-f]+)");
                Match match   = pattern.Match(eval.Value);

                if (match.Groups.Count > 1)
                {
                    members.normalPtr = match.Groups[1].Value;
                }
                else
                {
                    members.normalPtr = null;
                }
            }
            {
                Regex pattern = new Regex(@"\[precision\]=(\w+)");
                Match match   = pattern.Match(eval.Value);

                if (match.Groups.Count > 1)
                {
                    if (match.Groups[1].Value == "float")
                    {
                        members.precision = PointCloudPrecisionType.Float;
                    }
                    else if (match.Groups[1].Value == "double")
                    {
                        members.precision = PointCloudPrecisionType.Double;
                    }
                    else
                    {
                        members.precision = PointCloudPrecisionType.Unknown;
                    }
                }
                else
                {
                    members.precision = PointCloudPrecisionType.Float;
                }
            }
            {
                Regex pattern = new Regex(@"\[dimension\]=(\d+)");
                Match match   = pattern.Match(eval.Value);

                if (match.Groups.Count > 1)
                {
                    members.dimension = int.Parse(match.Groups[1].Value);
                    if (members.dimension != 3 && members.dimension != 2)
                    {
                        members.dimension = 0;
                    }
                }
                else
                {
                    members.dimension = 3;
                }
            }


            return(members);
        }