Beispiel #1
0
        internal void AssignInterestLevelToObject(ulong id, GcObject gcObject, BuildTypeGraphOptions options, FilterForm filterForm, bool isRoot)
        {
            bool isInteresting = gcObject.Type(this).interestLevel == InterestLevel.Interesting &&
                                 filterForm.IsInterestingAddress(id);

            if (isInteresting && filterForm.signatureFilters.Length != 0)
            {
                string signature = SignatureOfObject(id, gcObject, BuildTypeGraphOptions.LumpBySignature);
                isInteresting = filterForm.IsInterestingTypeName(gcObject.Type(this).name, signature,
                                                                 readNewLog.finalizableTypes.ContainsKey(gcObject.Type(this).typeID));
            }

            if (isInteresting)
            {
                gcObject.InterestLevel = InterestLevel.Interesting;
                if (!isRoot)
                {
                    gcObject.InterestLevel |= filterForm.InterestLevelForParentsAndChildren();
                }
            }
            else
            {
                gcObject.InterestLevel = InterestLevel.Ignore;
            }

            // Check if this is an interesting object, and we are supposed to mark its ancestors
            if ((gcObject.InterestLevel & InterestLevel.InterestingParents) == InterestLevel.InterestingParents)
            {
                for (GcObject parentObject = gcObject.parent; parentObject != null; parentObject = parentObject.parent)
                {
                    // As long as we find uninteresting objects, mark them for display
                    // When we find an interesting object, we stop, because either it
                    // will itself mark its parents, or it isn't interested in them (and we
                    // respect that despite the interest of the current object, somewhat arbitrarily).
                    if ((parentObject.InterestLevel & InterestLevel.InterestingParents) == InterestLevel.Ignore)
                    {
                        parentObject.InterestLevel |= InterestLevel.Display;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            // It's tempting here to mark the descendants as well, but they may be reached via
            // long reference paths, when there are shorter ones that were deemed uninteresting
            // Instead, we look whether our parent objects are interesting and want to show their
            // descendants, but we have to do that in a separate pass.
        }
Beispiel #2
0
        internal Vertex FindVertex(ulong id, GcObject gcObject, Graph graph, BuildTypeGraphOptions options)
        {
            Vertex vertex = gcObject.vertex;

            if (vertex != null)
            {
                return(vertex);
            }

            string signature = SignatureOfObject(id, gcObject, options);

            vertex          = graph.FindOrCreateVertex(gcObject.Type(this).name, signature, null);
            gcObject.vertex = vertex;

            return(vertex);
        }
Beispiel #3
0
 internal void PrintGCRoot(ulong[] path)
 {
     Console.WriteLine("<GcRoot>");
     Console.WriteLine("<!-- ");
     for (int j = 0; j < path.Length; j++)
     {
         GcObject temp = idToObject[path[j]];
         if (temp != null)
         {
             System.Console.WriteLine("{0}, {1:X} ->", temp.Type(this).name, path[j]);
         }
         //else
         //  System.Console.WriteLine("{0}, n/a ->", path[j]);
     }
     Console.WriteLine("-->");
     Console.WriteLine("</GcRoot>");
 }
Beispiel #4
0
        internal string SignatureOfObject(ulong id, GcObject gcObject, BuildTypeGraphOptions options)
        {
            StringBuilder sb = new StringBuilder();

            if (gcObject.parent != null)
            {
                switch (options)
                {
                case    BuildTypeGraphOptions.IndividualObjects:
                    if (gcObject.Type(this).name == "Stack" || gcObject.Type(this).name.StartsWith("Stack, "))
                    {
                        if (id < (ulong)readNewLog.funcName.Length)
                        {
                            sb.AppendFormat(readNewLog.funcName[id] + "  " + readNewLog.funcSignature[id]);
                        }
                        else
                        {
                            sb.AppendFormat("Function id = {0}", id);
                        }
                    }
                    else
                    {
                        sb.AppendFormat("Address = {0}, size = {1:n0} bytes", FormatAddress(id), gcObject.Size(this));
                    }
                    break;

                case    BuildTypeGraphOptions.LumpBySignature:
                    sb.Append(gcObject.parent.Type(this).name);
                    sb.Append("->");
                    sb.Append(gcObject.Type(this).name);
                    List <GcObject> references = new List <GcObject>();
                    foreach (GcObject refObject in gcObject.References)
                    {
                        references.Add(refObject);
                    }

                    if (references.Count > 0)
                    {
                        sb.Append("->(");

                        const int     MAXREFTYPECOUNT = 3;
                        List <string> typeNameList    = new List <string>(MAXREFTYPECOUNT);
                        string        separator       = "";
                        int           refTypeCount    = 0;
                        for (int i = 0; i < references.Count; i++)
                        {
                            GcObject refObject = references[i];
                            GcType   refType   = refObject.Type(this);
                            if (typeHintTable[refType.index] < i && references[typeHintTable[refType.index]].Type(this) == refType)
                            {
                                ;       // we already found this type - ignore further occurrences
                            }
                            else
                            {
                                typeHintTable[refType.index] = i;
                                refTypeCount++;
                                if (refTypeCount <= MAXREFTYPECOUNT)
                                {
                                    typeNameList.Add(refType.name);
                                }
                                else
                                {
                                    break;
                                }
                            }
                            i++;
                        }
                        typeNameList.Sort();

                        foreach (string typeName in typeNameList)
                        {
                            sb.Append(separator);
                            separator = ",";
                            sb.Append(typeName);
                        }

                        if (refTypeCount > MAXREFTYPECOUNT)
                        {
                            sb.Append(",...");
                        }

                        sb.Append(")");
                    }
                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
            }
            return(sb.ToString());
        }
Beispiel #5
0
        private Dictionary <GcObject, ulong> objectToId;        // reverse mapping from gc objects to their addresses

        internal void WriteVertexPaths(int allocatedAfterTickIndex, int allocatedBeforeTickIndex, string typeName)
        {
            BuildTypeGraph(new FilterForm());

            if (objectToId == null)
            {
                objectToId = new Dictionary <GcObject, ulong>();
                // initialize the reverse mapping
                foreach (KeyValuePair <ulong, GcObject> keyValuePair in idToObject)
                {
                    objectToId[keyValuePair.Value] = keyValuePair.Key;
                }
            }

            ulong[][] idsFromRoot  = new ulong[1][];
            Vertex[]  pathFromRoot = new Vertex[32];
            int       counter      = 0;

            foreach (GcObject gcObject in idToObject.Values)
            {
                if (gcObject.Type(this).name.CompareTo(typeName) != 0)
                {
                    continue;
                }

                if (gcObject.AllocTickIndex <= allocatedAfterTickIndex ||
                    gcObject.AllocTickIndex >= allocatedBeforeTickIndex)
                {
                    continue;
                }
                ulong[][] _idsFromRoot = idsFromRoot;
                if (_idsFromRoot.Length <= counter)
                {
                    idsFromRoot = new ulong[counter + 1][];
                    for (int i = 0; i < _idsFromRoot.Length; i++)
                    {
                        idsFromRoot[i] = _idsFromRoot[i];
                    }
                }

                int levels = 0;
                for (GcObject pathObject = gcObject; pathObject != null; pathObject = pathObject.parent)
                {
                    if (pathObject.vertex != null)
                    {
                        levels++;
                    }
                }

                while (pathFromRoot.Length < levels + 1)
                {
                    pathFromRoot = new Vertex[pathFromRoot.Length * 2];
                }

                int level = levels;
                //System.Console.WriteLine("{0} -- {1}:", counter, gcObject.id);
                for (GcObject pathObject = gcObject; pathObject != null; pathObject = pathObject.parent)
                {
                    if (pathObject.vertex != null)
                    {
                        level--;
                        pathFromRoot[level]  = pathObject.vertex;
                        pathObject.vertex.id = 0;
                        objectToId.TryGetValue(pathObject, out pathObject.vertex.id);
                    }
                }

                levels = Vertex.SqueezeOutRepetitions(pathFromRoot, levels);
                idsFromRoot[counter] = new ulong[levels];
                for (int i = 0; i < levels; i++)
                {
                    //System.Console.Write("{0}, {1} ->", pathFromRoot[i].name, pathFromRoot[i].id);
                    idsFromRoot[counter][i] = pathFromRoot[i].id;
                }
                //System.Console.WriteLine("---------------------------------------");
                counter++;
            }
            Console.WriteLine("<TotalAllocations>{0}</TotalAllocations>", idsFromRoot.Length);
            Console.WriteLine("</Difference>");
            Console.WriteLine("</Summary>");
            Console.WriteLine("<PossibleCulPrits>");
            // Display the reference list and stack trace for 0th object

            // Find Culprit here.
            var mismatchedObjects = new List <int>();
            var differentCulprits = new List <string>();

            for (int j = 1; j < idsFromRoot.Length; j++)
            {
                for (int i = 0; i < idsFromRoot[0].Length; i++)
                {
                    if ((i > idsFromRoot[j].Length) || ((i < idsFromRoot[j].Length) && (idsFromRoot[0][i] != idsFromRoot[j][i])))
                    {
                        if (i < idsFromRoot[0].Length - 1)
                        {
                            mismatchedObjects.Add(j);
                        }
                        GcObject temp = idToObject[idsFromRoot[0][i - 1]];
                        if (temp != null)
                        {
                            if (!differentCulprits.Contains(temp.Type(this).name))
                            {
                                differentCulprits.Add(temp.Type(this).name);
                                if (differentCulprits.Count <= 5)
                                {
                                    System.Console.WriteLine("<CulPrit><!--{0}--></CulPrit>", temp.Type(this).name);
                                }
                            }
                        }
                        break;
                    }
                }
            }
            Console.WriteLine("</PossibleCulPrits>");
            Console.WriteLine("<FirstObject>");
            PrintGCRoot(idsFromRoot[0]);
            PrintStackTrace(idsFromRoot[0]);
            Console.WriteLine("</FirstObject>");
            Console.WriteLine("<MisMatchedObjects>");

            if (mismatchedObjects.Count > 0)
            {
                Console.WriteLine();
                int limit = (mismatchedObjects.Count > 5) ? 5 : mismatchedObjects.Count;
                for (int i = 0; i < limit; i++)
                {
                    Console.WriteLine("<Object>");
                    PrintGCRoot(idsFromRoot[mismatchedObjects[i]]);
                    PrintStackTrace(idsFromRoot[mismatchedObjects[i]]);
                    Console.WriteLine("</Object>");
                }
            }
            Console.WriteLine("</MisMatchedObjects>");
        }