Beispiel #1
0
        internal async Task <VariableInformation> CreateMIDebuggerVariable(ThreadContext ctx, AD7Engine engine, AD7Thread thread)
        {
            VariableInformation vi = new VariableInformation(Name, ctx, engine, thread, IsParameter);
            await vi.Eval();

            return(vi);
        }
Beispiel #2
0
        //this constructor is private because it should only be used internally to create children
        private VariableInformation(TupleValue results, VariableInformation parent)
            : this(parent._ctx, parent._engine, parent.Client)
        {
            TypeName      = results.TryFindString("type");
            Value         = results.TryFindString("value");
            Name          = results.FindString("exp");
            CountChildren = results.FindUint("numchild");
            int index;

            if (!results.Contains("value") && (Name == TypeName || Name.Contains("::")))
            {
                // base classes show up with no value and exp==type
                // (sometimes underlying debugger does not follow this convention, when using typedefs in templated types so look for "::" in the field name too)
                Name             = "base";
                Value            = TypeName;
                VariableNodeType = NodeType.BaseClass;
            }
            else if (Int32.TryParse(this.Name, System.Globalization.NumberStyles.Integer, null, out index)) // array element
            {
                Name             = '[' + this.Name + ']';
                VariableNodeType = NodeType.ArrayElement;
            }
            else
            {
                _strippedName    = Name;
                VariableNodeType = NodeType.Field;
            }

            _internalName = results.FindString("name");
            IsChild       = true;
            _format       = parent._format; // inherit formatting
            _parent       = parent.VariableNodeType == NodeType.AccessQualifier ? parent._parent : parent;
        }
Beispiel #3
0
 //this constructor is used to create modified expressions from a parent
 internal VariableInformation(string expr, VariableInformation parent)
     : this(parent._ctx, parent._engine, parent.Client)
 {
     // strip off formatting string
     _strippedName    = StripFormatSpecifier(expr, out _format);
     Name             = expr;
     VariableNodeType = NodeType.Root;
 }
Beispiel #4
0
        //this constructor is private because it should only be used internally to create children
        private VariableInformation(TupleValue results, VariableInformation parent, string name = null)
            : this(parent._ctx, parent._engine, parent.Client)
        {
            TypeName = results.TryFindString("type");
            Value    = results.TryFindString("value");
            Name     = name ?? results.FindString("exp");
            if (results.Contains("dynamic"))
            {
                CountChildren = 1;
            }
            else
            {
                CountChildren = results.FindUint("numchild");
            }
            if (results.Contains("displayhint"))
            {
                DisplayHint = results.FindString("displayhint");
            }
            if (results.Contains("attributes"))
            {
                if (results.FindString("attributes") == "noneditable")
                {
                    _isReadonly = true;
                }
                _attribsFetched = true;
            }

            int index;

            if (!results.Contains("value") && (Name == TypeName || Name.Contains("::")))
            {
                // base classes show up with no value and exp==type
                // (sometimes underlying debugger does not follow this convention, when using typedefs in templated types so look for "::" in the field name too)
                Name             = TypeName + " (base)";
                Value            = TypeName;
                VariableNodeType = NodeType.BaseClass;
            }
            else if (Int32.TryParse(this.Name, System.Globalization.NumberStyles.Integer, null, out index)) // array element
            {
                Name             = '[' + this.Name + ']';
                VariableNodeType = NodeType.ArrayElement;
            }
            else if (this.Name.Length > 2 && this.Name[0] == '[' && this.Name[this.Name.Length - 1] == ']')
            {
                VariableNodeType = NodeType.ArrayElement;
            }
            else
            {
                _strippedName    = Name;
                VariableNodeType = NodeType.Field;
            }

            _internalName          = results.FindString("name");
            IsChild                = true;
            _format                = parent._format; // inherit formatting
            _parent                = parent.VariableNodeType == NodeType.AccessQualifier ? parent._parent : parent;
            this.PropertyInfoFlags = parent.PropertyInfoFlags;
        }
Beispiel #5
0
        //This method gets the locals and parameters and creates an MI debugger variable for each one so that we can manipulate them (and expand children, etc.)
        //NOTE: Eval is called
        internal async Task <List <VariableInformation> > GetLocalsAndParameters(AD7Thread thread, ThreadContext ctx)
        {
            List <VariableInformation> variables = new List <VariableInformation>();

            ValueListValue localsAndParameters = await MICommandFactory.StackListVariables(PrintValues.NoValues, thread.Id, ctx.Level);

            foreach (var localOrParamResult in localsAndParameters.Content)
            {
                string name    = localOrParamResult.FindString("name");
                bool   isParam = localOrParamResult.TryFindString("arg") == "1";
                SimpleVariableInformation simpleInfo = new SimpleVariableInformation(name, isParam);
                VariableInformation       vi         = await simpleInfo.CreateMIDebuggerVariable(ctx, Engine, thread);

                variables.Add(vi);
            }

            return(variables);
        }
Beispiel #6
0
        public VariableInformation FindChildByName(string name)
        {
            EnsureChildren();
            if (CountChildren == 0)
            {
                return(null);
            }
            Debug.Assert(Children != null, "Failed to find children");
            VariableInformation var = Array.Find(Children, (c) => c.Name == name);

            if (var != null)
            {
                return(var);
            }
            VariableInformation baseChild = null;

            var = Array.Find(Children, (c) => c.VariableNodeType == NodeType.BaseClass && (baseChild = c.FindChildByName(name)) != null);
            return(baseChild);
        }
Beispiel #7
0
        private async Task InternalFetchChildren()
        {
            Results results = await _engine.DebuggedProcess.CmdAsync(string.Format("-var-list-children --simple-values \"{0}\"", _internalName), ResultClass.None);

            if (results.ResultClass == ResultClass.done)
            {
                TupleValue[] children          = results.Find <ResultListValue>("children").FindAll <TupleValue>("child");
                int          i                 = 0;
                bool         isArray           = IsArrayType();
                bool         elementIsReadonly = false;
                if (isArray)
                {
                    CountChildren = results.FindUint("numchild");
                    Children      = new VariableInformation[CountChildren];
                    //if (k.Length > 0)    // perform attrib check on first array child, apply to all elements
                    //{
                    //    MICore.Debugger.Results childResults = MICore.Debugger.DecodeResults(k[0]);
                    //    string name = childResults.Find("name");
                    //    Debug.Assert(!string.IsNullOrEmpty(name));
                    //    string attribute = await m_engine.DebuggedProcess.MICommandFactory.VarShowAttributes(name);
                    //    elementIsReadonly = (attribute != "editable");
                    //}
                    foreach (var c in children)
                    {
                        Children[i] = new VariableInformation(c, this, elementIsReadonly);
                        i++;
                    }
                }
                else
                {
                    List <VariableInformation> listChildren = new List <VariableInformation>();
                    foreach (var c in children)
                    {
                        var variable = new VariableInformation(c, this);
                        enum_DBG_ATTRIB_FLAGS access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_NONE;
                        if (variable.Name == "public")
                        {
                            access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PUBLIC;
                            variable.VariableNodeType = NodeType.AccessQualifier;
                        }
                        else if (variable.Name == "private")
                        {
                            access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PRIVATE;
                            variable.VariableNodeType = NodeType.AccessQualifier;
                        }
                        else if (variable.Name == "protected")
                        {
                            access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PROTECTED;
                            variable.VariableNodeType = NodeType.AccessQualifier;
                        }
                        if (access != enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_NONE)
                        {
                            // Add this child's children
                            await variable.InternalFetchChildren();

                            foreach (var child in variable.Children)
                            {
                                ((VariableInformation)child).Access = access;
                                listChildren.Add(child);
                            }
                        }
                        else
                        {
                            listChildren.Add(variable);
                        }
                    }
                    Children      = listChildren.ToArray();
                    CountChildren = (uint)Children.Length;
                }
            }
            else
            {
                Children      = new VariableInformation[0];
                CountChildren = 0;
            }
            if (_format != null)
            {
                foreach (var child in Children)
                {
                    await child.Format();
                }
            }
        }
Beispiel #8
0
 private VariableInformation(TupleValue results, VariableInformation parent, bool ro)
     : this(results, parent)
 {
     _attribsFetched = true;  // read-only attribute is passed in at construction
     _isReadonly     = ro;
 }
Beispiel #9
0
        private void InitializeBytes()
        {
            if (_bytes != null)
            {
                return;
            }

            uint fetched = 0;

            _bytes = new byte[0];

            IDebugMemoryContext2 memAddr;

            if (GetMemoryContext(out memAddr) != Constants.S_OK)
            {
                // no address in the expression value, try casting to a char*
                VariableInformation v = new VariableInformation("(char*)(" + _variableInformation.FullName() + ")", (VariableInformation)_variableInformation);
                v.SyncEval();
                if (v.Error)
                {
                    return;
                }
                AD7Property p = new AD7Property(_engine, v);
                uint        pLen;
                if (p.GetStringCharLength(out pLen) == Constants.S_OK)
                {
                    _bytes = new byte[pLen];
                    p.GetStringRawBytes(pLen, _bytes, out fetched);
                }
                return;
            }

            IDebugMemoryBytes2 memContent;

            if (((AD7MemoryAddress)memAddr).Engine.GetMemoryBytes(out memContent) != Constants.S_OK)
            {
                return;
            }

            fetched = 0;
            bool eos = false;

            byte[] bytes = new byte[s_maxChars + 1];
            byte[] chunk = new byte[2048];
            while (!eos)
            {
                // fetched is count of bytes in string so far
                // eos == false => fetch < s_maxChars
                // eos == true => string is terminated, that is bytes[fetched-1] == 0

                uint bytesRead;
                uint bytesUnreadable = 0;
                // get next chunk
                if (memContent.ReadAt(memAddr, (uint)chunk.Length, chunk, out bytesRead, ref bytesUnreadable) != Constants.S_OK)
                {
                    break;
                }
                // copy chunk to bytes
                for (uint i = 0; i < bytesRead; ++i)
                {
                    bytes[fetched++] = chunk[i];
                    if (bytes[fetched - 1] == 0)
                    {
                        eos = true; // end of string
                        break;
                    }
                    if (fetched == s_maxChars)  // buffer is full
                    {
                        bytes[fetched++] = 0;   // end the string
                        eos = true;
                        break;
                    }
                }
                if (bytesRead != chunk.Length)
                {
                    // read to end of available memory
                    break;
                }
                // advance to next chunk
                memAddr.Add(bytesRead, out memAddr);
            }
            if (!eos)
            {
                Debug.Assert(fetched < bytes.Length);
                bytes[fetched++] = 0;
            }
            if (fetched < bytes.Length)
            {
                _bytes = new byte[fetched];
                Array.Copy(bytes, _bytes, (int)fetched);
            }
            else
            {
                _bytes = bytes;
            }
        }
Beispiel #10
0
        private async Task InternalFetchChildren()
        {
            this.VerifyNotDisposed();

            Results results = await _engine.DebuggedProcess.MICommandFactory.VarListChildren(_internalName, PropertyInfoFlags, ResultClass.None);

            if (results.ResultClass == ResultClass.done)
            {
                TupleValue[] children = results.Contains("children")
                    ? results.Find <ResultListValue>("children").FindAll <TupleValue>("child")
                    : new TupleValue[0];
                int  i       = 0;
                bool isArray = IsArrayType();
                if (isArray)
                {
                    CountChildren = results.FindUint("numchild");
                    Children      = new VariableInformation[CountChildren];
                    foreach (var c in children)
                    {
                        Children[i] = new VariableInformation(c, this);
                        i++;
                    }
                }
                else if (IsMapType())
                {
                    //
                    // support for gdb's pretty-printing built-in displayHint "map", from the gdb docs:
                    //      'Indicate that the object being printed is “map-like”, and that the
                    //      children of this value can be assumed to alternate between keys and values.'
                    //
                    List <VariableInformation> listChildren = new List <VariableInformation>();
                    for (int p = 0; p + 1 < children.Length; p += 2)
                    {
                        // One Variable is created for each pair returned with the first element (p) being the name of the child
                        // and the second element (p+1) becoming the value.
                        string name     = children[p].FindString("value");
                        var    variable = new VariableInformation(children[p + 1], this, '[' + name + ']');
                        listChildren.Add(variable);
                    }
                    Children      = listChildren.ToArray();
                    CountChildren = (uint)Children.Length;
                }
                else
                {
                    List <VariableInformation> listChildren = new List <VariableInformation>();
                    foreach (var c in children)
                    {
                        var variable = new VariableInformation(c, this);
                        enum_DBG_ATTRIB_FLAGS access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_NONE;
                        if (variable.Name == "public")
                        {
                            access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PUBLIC;
                            variable.VariableNodeType = NodeType.AccessQualifier;
                        }
                        else if (variable.Name == "private")
                        {
                            access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PRIVATE;
                            variable.VariableNodeType = NodeType.AccessQualifier;
                        }
                        else if (variable.Name == "protected")
                        {
                            access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PROTECTED;
                            variable.VariableNodeType = NodeType.AccessQualifier;
                        }
                        if (access != enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_NONE)
                        {
                            // Add this child's children
                            await variable.InternalFetchChildren();

                            foreach (var child in variable.Children)
                            {
                                ((VariableInformation)child).Access = access;
                                listChildren.Add(child);
                            }
                        }
                        else
                        {
                            listChildren.Add(variable);
                        }
                    }
                    Children      = listChildren.ToArray();
                    CountChildren = (uint)Children.Length;
                }
            }
            else
            {
                Children      = new VariableInformation[0];
                CountChildren = 0;
            }
            if (_format != null)
            {
                foreach (var child in Children)
                {
                    await child.Format();
                }
            }
        }