Пример #1
0
 public IChildAdapter CreateForTesting(RemoteValue remoteValue,
                                       IRemoteValueFormat remoteValueFormat,
                                       VarInfoBuilder varInfoBuilder,
                                       string formatSpecifier, int maxCountPerRange) =>
 RemoteValueRangedAdapter.First(
     maxCountPerRange, new RemoteValueChildAdapter(remoteValue, remoteValueFormat,
                                                   varInfoBuilder, formatSpecifier));
Пример #2
0
        public void SetUp()
        {
            mockFrame = Substitute.For <RemoteFrame>();

            var childAdapterFactory = new RemoteValueChildAdapter.Factory();
            var varInfoFactory      = new LLDBVariableInformationFactory(childAdapterFactory);
            var varInfoBuilder      = new VarInfoBuilder(varInfoFactory);

            varInfoFactory.SetVarInfoBuilder(varInfoBuilder);
            var registerSetsBuilderFactory = new RegisterSetsBuilder.Factory(varInfoFactory);

            registerSetsBuilder = registerSetsBuilderFactory.Create(mockFrame);

            generalPurposeRegisters = Substitute.For <RemoteValue>();
            generalPurposeRegisters.GetName().Returns("General Purpose Registers");
            generalPurposeRegisters.GetNumChildren().Returns(0u);

            floatingPointRegisters = Substitute.For <RemoteValue>();
            floatingPointRegisters.GetName().Returns("Floating Point Registers");
            floatingPointRegisters.GetNumChildren().Returns(3u);
            xmm0 = Substitute.For <RemoteValue>();
            xmm0.GetName().Returns("xmm0");
            xmm8 = Substitute.For <RemoteValue>();
            xmm8.GetName().Returns("xmm8");
            other = Substitute.For <RemoteValue>();
            other.GetName().Returns("other");
            floatingPointRegisters.GetChildren(0, 3).Returns(
                new List <RemoteValue>()
            {
                xmm0, xmm8, other
            });
        }
Пример #3
0
        private IEnumerable <IVariableInformation> BuildSyntheticSets()
        {
            RemoteValue floatingPointRegs = frame.GetRegisters()
                                            .Where(r => r.GetName() == floatingPointRegistersSetName)
                                            .FirstOrDefault();

            if (floatingPointRegs == null)
            {
                return(Enumerable.Empty <IVariableInformation>());
            }

            var sets = new List <IVariableInformation>();

            // A preset Natvis entry for CustomVisualizer.SSE shows the registers xmm<0-7>
            // contained in the floating point register set as VectorOfFloat32.
            sets.Add(varInfoFactory.Create(floatingPointRegs, "SSE",
                                           customVisualizer: CustomVisualizer.SSE));

            // A preset Natvis entry for CustomVisualizer.SSE2 shows the registers xmm<0-15>
            // contained in the floating point register set as VectorOfFloat64, and xmm<8-15> as
            // VectorOfFloat32.
            sets.Add(varInfoFactory.Create(floatingPointRegs, "SSE2",
                                           customVisualizer: CustomVisualizer.SSE2));

            return(sets);
        }
        public async Task LldbEvalWithContextVarsAsync()
        {
            _optionPageGrid.ExpressionEvaluationEngine =
                ExpressionEvaluationEngineFlag.LLDB_EVAL_WITH_FALLBACK;

            RemoteValue mockVariable = CreateMockVariable();

            var natvisScope = new NatvisScope();
            var contextVar  = RemoteValueFakeUtil.CreateSimpleInt("var", 14);

            natvisScope.AddScopedName("var", "$var_0");
            natvisScope.AddContextVariable("$var_0", contextVar);

            await _evaluator.EvaluateExpressionAsync(
                "2 + var", _varInfoFactory.Create(mockVariable), natvisScope, "result");

            await mockVariable.Received(1).EvaluateExpressionLldbEvalAsync(
                Arg.Is("2 + $var_0"), Arg.Is(natvisScope.ContextVariables));

            Assert.That(natvisScope.ContextVariables.Count, Is.EqualTo(1));
            Assert.That(natvisScope.ContextVariables.ContainsKey("$var_0"));
            Assert.That(natvisScope.ContextVariables["$var_0"], Is.EqualTo(contextVar));

            await mockVariable.DidNotReceive().EvaluateExpressionAsync(Arg.Any <string>());
        }
Пример #5
0
        static IEnumerable <RemoteValue> GetRemoteValueChildren(RemoteValue remoteValue, int offset,
                                                                int count)
        {
            var  result      = new List <RemoteValue>();
            uint childOffset = (uint)offset;
            uint endIndex    = (uint)(offset + count);
            uint numChildren = remoteValue.GetNumChildren();

            while (childOffset < endIndex)
            {
                // Fetch children in batches for performance reasons.
                uint batchSize = System.Math.Min(endIndex - childOffset, _maxChildBatchSize);
                List <RemoteValue> currentBatch = remoteValue.GetChildren(childOffset, batchSize);

                for (int n = 0; n < batchSize; ++n)
                {
                    RemoteValue childValue = currentBatch[n];
                    if (childValue != null)
                    {
                        result.Add(childValue);
                    }
                    else if (n + childOffset < numChildren)
                    {
                        // There were times when LLDB was returning an error and thus a null child
                        // value. ex: Children[1] for a CustomType&* type.
                        Trace.WriteLine(
                            $"WARNING: No child found at index {n + childOffset} of " +
                            $"({remoteValue.GetTypeName()}){remoteValue.GetFullName()} even " +
                            $"though there are {numChildren} children.");
                    }
                }
                childOffset += batchSize;
            }
            return(result);
        }
        /// <summary>
        /// Get the variable assignment expression as a string. Returns null if the value is
        /// constant or invalid.
        /// </summary>
        public static string GetVariableAssignExpression(this RemoteValue remoteValue)
        {
            var valueType = remoteValue.GetValueType();

            if (valueType == ValueType.Invalid)
            {
                return(null);
            }

            if (valueType == ValueType.Register)
            {
                return($"${remoteValue.GetName()}");
            }

            TypeFlags?typeFlags = remoteValue.GetTypeInfo()?.GetTypeFlags();

            if (typeFlags.HasValue && typeFlags.Value.HasFlag(TypeFlags.IS_ARRAY))
            {
                return(null);
            }

            string variableExpression = remoteValue.GetFullName();

            if (variableExpression == null)
            {
                variableExpression = remoteValue.GetMemoryAddressAssignExpression();
            }
            return(variableExpression);
        }
        /// <summary>
        /// Returns the address to be used as memory context. This is used to get an address
        /// from an expression entered into Visual Studio's memory view's address text box.
        /// </summary>
        public static ulong?GetMemoryContextAddress(this RemoteValue remoteValue)
        {
            if (!IsValidValue(remoteValue))
            {
                return(null);
            }

            TypeFlags GetTypeFlags(RemoteValue value) =>
            remoteValue.GetTypeInfo().GetCanonicalType().GetTypeFlags();

            // If the value is an array, try to obtain its address.
            TypeFlags flags = GetTypeFlags(remoteValue);

            if (flags.HasFlag(TypeFlags.IS_ARRAY))
            {
                remoteValue = remoteValue.AddressOf();
                if (!IsValidValue(remoteValue))
                {
                    return(null);
                }
                flags = GetTypeFlags(remoteValue);
            }

            // Only interpret pointers, references and integers as addresses.
            if (!flags.HasFlag(TypeFlags.IS_REFERENCE) && !flags.HasFlag(TypeFlags.IS_POINTER) &&
                !flags.HasFlag(TypeFlags.IS_INTEGER))
            {
                return(null);
            }

            return(remoteValue.GetValueAsUnsigned());
        }
Пример #8
0
        public bool Assign(string expression, out string error)
        {
            if (IsReadOnly)
            {
                error = string.Format(
                    "Attempted to assign a value to a read only variable with name '{0}'.",
                    DisplayName);

                return(false);
            }

            string cast = "";

            if (_remoteValue.TypeIsPointerType() ||
                _remoteValue.GetTypeInfo().GetTypeFlags().HasFlag(TypeFlags.IS_ENUMERATION))
            {
                cast = $"({_remoteValue.GetTypeInfo().GetCanonicalType().GetName()})";
            }

            expression = _remoteValueFormat.FormatExpressionForAssignment(_remoteValue, expression);
            // Avoid using parentheses to enclose registers because they can prevent assignments
            // involving initialization lists from succeeding.
            if (_remoteValue.GetValueType() != DebuggerApi.ValueType.Register)
            {
                expression = $"({expression})";
            }

            RemoteValue tempValue = _remoteValue.CreateValueFromExpression(
                DisplayName, $"{_remoteValue.GetVariableAssignExpression()} = {cast}{expression}");

            SbError sbError = tempValue.GetError();

            error = sbError.Fail() ? sbError.GetCString() : null;
            return(sbError.Success());
        }
Пример #9
0
 internal static GrpcSbValue CreateValue(RemoteValue remoteValue, long id) =>
 new GrpcSbValue
 {
     Id    = id,
     Name  = remoteValue.GetName() ?? "",
     Error = CreateError(remoteValue.GetError())
 };
Пример #10
0
        // TODO: handle the situation when raw and expand formatter are both present
        public virtual IVariableInformation Create(
            RemoteValue remoteValue, string displayName = null,
            FormatSpecifier formatSpecifier             = null,
            CustomVisualizer customVisualizer           = CustomVisualizer.None)
        {
            IVariableInformation varInfo =
                _varInfoFactory.Create(remoteValue, displayName, formatSpecifier, customVisualizer);

            // Don't use Natvis for raw format specifier (!), e.g. "myvar,!".
            if (FormatSpecifierUtil.HasRawFormatSpecifier(varInfo.FormatSpecifier))
            {
                return(new CachingVariableInformation(varInfo));
            }

            var natvisVarInfo = new NatvisVariableInformation(_natvisExpander, varInfo);

            if (ExpandFormatSpecifierUtil.TryParseExpandFormatSpecifier(
                    natvisVarInfo.FormatSpecifier, out int expandedIndex))
            {
                return(new CachingVariableInformation(
                           _expandVariableFactory.Create(natvisVarInfo, expandedIndex)));
            }

            return(new CachingVariableInformation(natvisVarInfo));
        }
Пример #11
0
        static IEnumerable <RemoteValue> GetPointerChildren(RemoteValue value, int offset, int count)
        {
            var    result      = new List <RemoteValue>();
            SbType pointeeType = value.GetTypeInfo()?.GetPointeeType();

            if (pointeeType == null)
            {
                // If we cannot get the pointee type, just return the empty list.
                return(result);
            }
            ulong byteSize    = pointeeType.GetByteSize();
            ulong baseAddress = value.GetValueAsUnsigned() + (ulong)offset * byteSize;

            for (int n = 0; n < count; ++n)
            {
                ulong       address    = baseAddress + (ulong)n * byteSize;
                RemoteValue childValue =
                    value.CreateValueFromAddress($"[{offset + n}]", address, pointeeType);
                if (childValue != null)
                {
                    result.Add(childValue);
                }
            }
            return(result);
        }
Пример #12
0
 public RemoteValueVariableInformation CreateVarInfo(
     RemoteValue remoteValue, string displayName)
 {
     return(new RemoteValueVariableInformation(varInfoBuilder, "", RemoteValueFormat.Default,
                                               ValueFormat.Default, remoteValue, displayName,
                                               CustomVisualizer.None, childAdapterFactory));
 }
Пример #13
0
        private GrpcValueInfo CreateValueInfoAndUpdateStores(RemoteValue remoteValue)
        {
            if (remoteValue == null)
            {
                return(null);
            }

            string expressionPath;
            var    hasExpressionPath = remoteValue.GetExpressionPath(out expressionPath);
            var    valueInfo         = new GrpcValueInfo
            {
                ExpressionPath    = expressionPath ?? "",
                HasExpressionPath = hasExpressionPath,
                NumChildren       = remoteValue.GetNumChildren(),
                Summary           = remoteValue.GetSummary() ?? "",
                TypeName          = remoteValue.GetTypeName() ?? "",
                Value             = remoteValue.GetValue() ?? "",
                ValueType         = EnumUtil.ConvertTo <Debugger.Common.ValueType>(
                    remoteValue.GetValueType()),
                IsPointerType = remoteValue.TypeIsPointerType(),
                ByteSize      = remoteValue.GetByteSize(),
            };
            var typeInfo = remoteValue.GetTypeInfo();

            if (typeInfo != null)
            {
                valueInfo.Type = GrpcFactoryUtils.CreateType(
                    typeInfo, typeStore.AddObject(typeInfo));
            }
            return(valueInfo);
        }
Пример #14
0
        public RemoteValue GetCachedView(DebuggerApi.ValueFormat format)
        {
            GetCachedViewResponse response = null;

            if (connection.InvokeRpc(() =>
            {
                response = client.GetCachedView(
                    new GetCachedViewRequest
                {
                    Value = grpcSbValue,
                    Format = format.ConvertTo <Debugger.Common.ValueFormat>()
                });
            }))
            {
                if (response.ValueInfo != null)
                {
                    RemoteValue addressOf = null;
                    if (response.AddressValue != null && response.AddressValue.Id != 0)
                    {
                        addressOf = valueFactory.Create(connection, response.AddressValue);
                        if (response.AddressInfo != null)
                        {
                            // gRpc server does not set |format| on |addressOf|, so use default.
                            addressOf = CreateCachedValue(addressOf, response.AddressInfo, null,
                                                          DebuggerApi.ValueFormat.Default);
                        }
                    }
                    return(CreateCachedValue(this, response.ValueInfo, addressOf, format));
                }
            }
            return(null);
        }
Пример #15
0
        public override Task <GetChildrenResponse> GetChildren(
            GetChildrenRequest request, ServerCallContext context)
        {
            var value    = valueStore.GetObject(request.Value.Id);
            var children = value.GetChildren(request.Offset, request.Count);
            var response = new GetChildrenResponse();

            for (uint n = 0; n < children.Count; ++n)
            {
                RemoteValue child = children[(int)n];
                if (child != null)
                {
                    response.Children[n + request.Offset] =
                        GrpcFactoryUtils.CreateValue(child, valueStore.AddObject(child));
                }
            }

            // (internal): Special case for pointers. LLDB names them $"*{value.GetName()}", but
            // Visual Studio just shows an empty name.
            if (value.TypeIsPointerType() && response.Children.ContainsKey(0) &&
                response.Children[0].Name == $"*{value.GetName()}")
            {
                response.Children[0].Name = string.Empty;
            }

            return(Task.FromResult(response));
        }
Пример #16
0
 public virtual RemoteValue Create(RemoteValue remoteProxy, RemoteValue addressOf,
                                   SbType typeInfo, string expressionPath, bool hasExpressionPath, uint numChildren,
                                   string summary, string typeName, string value, ValueType valueType, bool isPointerType,
                                   ValueFormat valueFormat, ulong byteSize)
 => new CachedValue(remoteProxy, addressOf, typeInfo, expressionPath, hasExpressionPath,
                    numChildren, summary, typeName, value, valueType, isPointerType, valueFormat,
                    byteSize);
Пример #17
0
        public async Task <EvaluationResult> EvaluateExpressionAsync()
        {
            VsExpression vsExpression =
                await _vsExpressionCreator.CreateAsync(_text, EvaluateSizeSpecifierExpressionAsync);

            IDebugProperty2 result;

            if (vsExpression.Value.StartsWith("."))
            {
                EvaluateCommand(vsExpression.Value, out result);
                return(EvaluationResult.FromResult(result));
            }

            RemoteValue remoteValue = await CreateValueFromExpressionAsync(vsExpression.Value);

            if (remoteValue == null)
            {
                return(EvaluationResult.Fail());
            }

            string displayName           = vsExpression.ToString();
            IVariableInformation varInfo =
                _varInfoBuilder.Create(remoteValue, displayName, vsExpression.FormatSpecifier);

            result = _createPropertyDelegate.Invoke(varInfo);

            return(EvaluationResult.FromResult(result));
        }
        /// <summary>
        /// Returns an unquoted, unescaped version of the result from FormatValue() if that value
        /// looks like a quoted and escaped string literal. For instance, L"\"foo\\nbar\"" becomes
        /// "foo\nbar". Returns "" otherwise.
        /// </summary>
        public virtual string FormatStringView(
            RemoteValue remoteValue, ValueFormat fallbackValueFormat)
        {
            string value = FormatValue(remoteValue, fallbackValueFormat);

            return(CStringEscapeHelper.Unescape(value));
        }
        RemoteValue CreateMockVariable()
        {
            RemoteValue mockVariable = Substitute.For <RemoteValue>();

            mockVariable.TypeIsPointerType().Returns(false);
            mockVariable.GetValueForExpressionPath(Arg.Any <string>()).Returns((RemoteValue)null);
            return(mockVariable);
        }
Пример #20
0
 public virtual uint GetNumChildren(RemoteValue remoteValue)
 {
     if (_sizeSpecifier is uint childCount)
     {
         return(GetNumPointerOrArrayChildren(childCount, remoteValue));
     }
     return(remoteValue.GetNumChildren());
 }
        public void Pointer()
        {
            RemoteValue remoteValue =
                RemoteValueFakeUtil.CreatePointer("dummyType*", "dummyName", "0xDEADC0DE");

            Assert.That(RemoteValueExtensions.GetMemoryContextAddress(remoteValue),
                        Is.EqualTo(0xDEADC0DE));
        }
Пример #22
0
 RemoteValueChildAdapter(RemoteValue remoteValue, IRemoteValueFormat remoteValueFormat,
                         VarInfoBuilder varInfoBuilder, string formatSpecifier)
 {
     _remoteValue       = remoteValue;
     _remoteValueFormat = remoteValueFormat;
     _varInfoBuilder    = varInfoBuilder;
     _formatSpecifier   = formatSpecifier;
 }
Пример #23
0
        public string FormatValueWithSize(RemoteValue remoteValue, uint size)
        {
            string result = GetValueAsString(remoteValue, size, out string error);

            if (result == null)
            {
                return(error);
            }
            return(CStringEscapeHelper.Escape(result, _prefix, _postfix));
        }
 public virtual string FormatExpressionForAssignment(
     RemoteValue remoteValue, string expression)
 {
     if (remoteValue.GetTypeInfo().GetTypeFlags().HasFlag(TypeFlags.IS_FLOAT))
     {
         return(FloatRadixConversionHelper.TryConvertToFloatFromNumberString(
                    expression, new System.Lazy <int>(() => (int)remoteValue.GetByteSize())));
     }
     return(expression);
 }
        public virtual string FormatValueAsAddress(RemoteValue remoteValue)
        {
            TypeFlags flags = remoteValue?.GetTypeInfo()?.GetTypeFlags() ?? 0;

            if (flags.HasFlag(TypeFlags.IS_REFERENCE) || flags.HasFlag(TypeFlags.IS_POINTER))
            {
                return($"0x{remoteValue.GetValueAsUnsigned():x16}");
            }
            return(string.Empty);
        }
Пример #26
0
        /// <summary>
        /// Returns |remoteValue|'s summary if present and its value otherwise, formatted using
        /// |valueFormat|.
        /// </summary>
        public static string GetDisplayValue(this RemoteValue remoteValue, ValueFormat valueFormat)
        {
            var strValue = remoteValue.GetSummary(valueFormat);

            if (!string.IsNullOrEmpty(strValue))
            {
                return(TryConvertToUtf8(strValue));
            }
            return(remoteValue.GetValue(valueFormat));
        }
Пример #27
0
        public async Task <IVariableInformation> EvaluateExpressionAsync(string displayName,
                                                                         VsExpression vsExpression)
        {
            RemoteValue resultValue =
                await _remoteValue.EvaluateExpressionAsync(vsExpression.Value);

            return(resultValue == null
                       ? null
                       : _varInfoBuilder.Create(resultValue, displayName,
                                                formatSpecifier: vsExpression.FormatSpecifier));
        }
Пример #28
0
        public IVariableInformation FindChildByName(string name)
        {
            RemoteValue child = _remoteValue.GetChildMemberWithName(name);

            if (child == null)
            {
                return(null);
            }

            return(_varInfoBuilder.Create(child, name));
        }
Пример #29
0
        public void AddValueFromExpression(string expression, RemoteValue value)
        {
            Queue <RemoteValue> values;

            if (!expressionValues.TryGetValue(expression, out values))
            {
                values = new Queue <RemoteValue>();
                expressionValues[expression] = values;
            }
            values.Enqueue(value);
        }
Пример #30
0
        /// <summary>
        /// Return the expression path of the remoteValue. Don't return LLDB scratch variables like
        /// "$23" because they sometimes don't behave as expected when assigning values to them
        /// and they don't persist across debug sessions correctly.
        /// </summary>
        public static string GetFullName(this RemoteValue remoteValue)
        {
            string expressionPath;

            if (remoteValue.GetExpressionPath(out expressionPath) &&
                !string.IsNullOrEmpty(expressionPath) &&
                !expressionPath.Contains("$"))
            {
                return(expressionPath);
            }
            return(null);
        }