Ejemplo n.º 1
0
        public static ValueTuple <ulong[], ulong[]> SetupRootAddresses(int rtm, ClrHeap heap, string[] typeNames, StringIdDct strIds, DumpFileMoniker fileMoniker, out string error)
        {
            error = null;
            try
            {
                var roots   = heap.EnumerateRoots(true);
                var objSet  = new HashSet <ulong>(new Utils.AddressEqualityComparer());
                var finlSet = new HashSet <ulong>(new Utils.AddressEqualityComparer());
                List <ClrtRoot>[] ourRoots = new List <ClrtRoot> [(int)GCRootKind.Max + 1];
                for (int i = 0, icnt = (int)GCRootKind.Max + 1; i < icnt; ++i)
                {
                    ourRoots[i] = new List <ClrtRoot>(256);
                }

                foreach (var root in roots)
                {
                    ulong  rootAddr = root.Address;
                    ulong  objAddr  = root.Object;
                    int    typeId;
                    string typeName;
                    if (root.Type == null)
                    {
                        var clrType = heap.GetObjectType(objAddr);
                        typeName = clrType == null ? Constants.UnknownName : clrType.Name;
                    }
                    else
                    {
                        typeName = root.Type.Name;
                    }

                    typeId = Array.BinarySearch(typeNames, typeName, StringComparer.Ordinal);
                    if (typeId < 0)
                    {
                        typeId = Constants.InvalidIndex;
                    }
                    string rootName = root.Name == null ? Constants.UnknownName : root.Name;

                    var nameId   = strIds.JustGetId(rootName);
                    var clrtRoot = new ClrtRoot(root, typeId, nameId);

                    ourRoots[(int)root.Kind].Add(clrtRoot);

                    if (objAddr != 0UL)
                    {
                        if (root.Kind == GCRootKind.Finalizer)
                        {
                            objAddr = Utils.SetAsFinalizer(objAddr);
                            finlSet.Add(objAddr);
                        }
                        else
                        {
                            objAddr = Utils.SetRooted(objAddr);
                            objSet.Add(objAddr);
                        }
                    }
                    if (rootAddr != 0UL)
                    {
                        if (root.Kind == GCRootKind.Finalizer)
                        {
                            rootAddr = Utils.SetAsFinalizer(rootAddr);
                            finlSet.Add(rootAddr);
                        }
                        else
                        {
                            rootAddr = Utils.SetRooted(rootAddr);
                            objSet.Add(rootAddr);
                        }
                    }
                }

                // root infos TODO JRD -- Fix this
                //
                var rootCmp = new ClrtRootObjCmp();
                for (int i = 0, icnt = (int)GCRootKind.Max + 1; i < icnt; ++i)
                {
                    ourRoots[i].Sort(rootCmp);
                }

                // unique addresses
                //
                var addrAry = objSet.ToArray();
                Array.Sort(addrAry, new Utils.AddressComparison());

                var finlAry = finlSet.ToArray();
                Array.Sort(finlAry, new Utils.AddressComparison());

                if (!ClrtRootInfo.Save(rtm, ourRoots, fileMoniker, out error))
                {
                    return(new ValueTuple <ulong[], ulong[]>(null, null));
                }
                return(new ValueTuple <ulong[], ulong[]>(addrAry, finlAry));
            }
            catch (Exception ex)
            {
                error = Utils.GetExceptionErrorString(ex);
                return(new ValueTuple <ulong[], ulong[]>(null, null));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Collect roots information.
        /// </summary>
        /// <param name="heap">Clr heap of current runtime.</param>
        /// <param name="instances">Instance addresses.</param>
        /// <param name="types">Instance types.</param>
        /// <param name="idDct">String id dictionary.</param>
        /// <returns>Roots info, <see cref="ClrtRoots"/></returns>
        public static ClrtRoots GetRootInfos(ClrHeap heap, ulong[] instances, int[] types, ulong[] rootAddresses, StringIdDct idDct)
        {
            var rootDct            = new SortedDictionary <ulong, List <ClrtRoot> >();
            var finalizeQue        = new List <ulong>(1024 * 1024);
            var finalizeQueInstIds = new List <int>(1024 * 1024);

            List <ClrRoot>  lstNotFoundObject = new List <ClrRoot>();
            List <ClrtRoot> lstRoots          = new List <ClrtRoot>(1024 * 64);

            foreach (var root in heap.EnumerateRoots(true))
            {
                var rootObj = root.Object;
                if (root.Kind == GCRootKind.Finalizer)
                {
                    finalizeQue.Add(rootObj);
                    var obj = Utils.AddressSearch(instances, rootObj);
                    finalizeQueInstIds.Add(obj);
                    continue;
                }
                var             rootAddr = root.Address;
                List <ClrtRoot> lst;
                if (rootDct.TryGetValue(rootAddr, out lst))
                {
                    int i     = 0;
                    int icnt  = lst.Count;
                    var rkind = root.Kind;
                    for (; i < icnt; ++i)
                    {
                        if (rootObj == lst[i].Object && rkind == ClrtRoot.GetGCRootKind(lst[i].RootKind))
                        {
                            break;
                        }
                    }
                    if (i == icnt)
                    {
                        var rname   = root.Name ?? Constants.NullName;
                        var rnameId = idDct.JustGetId(rname);
                        var obj     = Utils.AddressSearch(instances, rootObj);
                        if (obj < 0)
                        {
                            lstNotFoundObject.Add(root);
                        }
                        var typeId   = obj < 0 ? Constants.InvalidIndex : types[obj];
                        var clrtRoot = new ClrtRoot(root, typeId, rnameId, Constants.InvalidIndex, Constants.InvalidThreadId, Constants.InvalidIndex);
                        lst.Add(clrtRoot);
                        lstRoots.Add(clrtRoot);
                    }
                }
                else
                {
                    var rname   = root.Name ?? Constants.NullName;
                    var rnameId = idDct.JustGetId(rname);
                    var obj     = Utils.AddressSearch(instances, rootObj);
                    if (obj < 0)
                    {
                        lstNotFoundObject.Add(root);
                    }
                    var typeId   = obj < 0 ? Constants.InvalidIndex : types[obj];
                    var clrtRoot = new ClrtRoot(root, typeId, rnameId, Constants.InvalidIndex, Constants.InvalidThreadId, Constants.InvalidIndex);
                    rootDct.Add(rootAddr, new List <ClrtRoot>()
                    {
                        clrtRoot
                    });
                    lstRoots.Add(clrtRoot);
                }
            }

            var rootAry = lstRoots.ToArray();

            lstRoots.Clear();
            lstRoots = null;
            ulong[] sortedObjs;
            int[]   kindOffsets;
            int[]   objMap;
            ulong[] sortedAddrs;
            int[]   addrMap;
            SortRoots(rootAry, out kindOffsets, out sortedAddrs, out addrMap, out sortedObjs, out objMap);

            var finQueAry        = finalizeQue.ToArray();
            var finQueInstIdsAry = finalizeQueInstIds.ToArray();

            Array.Sort(finQueAry, finQueInstIdsAry);

            return(new ClrtRoots(rootAry, kindOffsets, sortedAddrs, addrMap, sortedObjs, objMap, finQueAry, finQueInstIdsAry));
        }
Ejemplo n.º 3
0
        public static ValueTuple <ulong[], int, int> GetFlaggedRoots(ClrHeap heap, string[] typeNames, StringIdDct strIds, string rootPath, out string error)
        {
            error = null;
            try
            {
                Dictionary <ulong, ulong> dct      = new Dictionary <ulong, ulong>(1024 * 512);
                List <ClrtRoot>[]         ourRoots = new List <ClrtRoot> [(int)GCRootKind.Max + 1];
                for (int i = 0, icnt = (int)GCRootKind.Max + 1; i < icnt; ++i)
                {
                    ourRoots[i] = new List <ClrtRoot>(256);
                }
                var roots = heap.EnumerateRoots(true);
                //ulong savedAddr;
                int finalizerCount = 0;
                int rootCount      = 0;
                foreach (var root in roots)
                {
                    ulong rootAddr        = root.Address;
                    ulong objAddr         = root.Object;
                    ulong flaggedRootAddr = rootAddr;
                    ulong flaggedObjAddr  = objAddr;

                    int    typeId;
                    string typeName;
                    if (root.Type == null)
                    {
                        var clrType = heap.GetObjectType(objAddr);
                        typeName = clrType == null ? Constants.UnknownName : clrType.Name;
                    }
                    else
                    {
                        typeName = root.Type.Name;
                    }

                    typeId = Array.BinarySearch(typeNames, typeName, StringComparer.Ordinal);
                    if (typeId < 0)
                    {
                        typeId = Constants.InvalidIndex;
                    }
                    string rootName = root.Name == null ? Constants.UnknownName : root.Name;

                    var nameId   = strIds.JustGetId(rootName);
                    var clrtRoot = new ClrtRoot(root, typeId, nameId);
                    ourRoots[(int)root.Kind].Add(clrtRoot);

                    switch (root.Kind)
                    {
                    case GCRootKind.Finalizer:
                        ++finalizerCount;
                        if (objAddr != 0UL)
                        {
                            flaggedObjAddr = Utils.SetAsFinalizer(flaggedObjAddr);
                        }
                        if (rootAddr != 0UL)
                        {
                            flaggedRootAddr = Utils.SetAsFinalizer(flaggedRootAddr);
                        }
                        break;

                    case GCRootKind.LocalVar:
                        if (objAddr != 0UL)
                        {
                            flaggedObjAddr = Utils.SetAsLocal(flaggedObjAddr);
                        }
                        if (rootAddr != 0UL)
                        {
                            flaggedRootAddr = Utils.SetAsLocal(flaggedRootAddr);
                        }
                        break;

                    default:
                        ++rootCount;
                        flaggedObjAddr = Utils.SetAsRoot(flaggedObjAddr);
                        if (objAddr != 0UL)
                        {
                            flaggedObjAddr = Utils.SetAsRoot(flaggedObjAddr);
                        }
                        if (rootAddr != 0UL)
                        {
                            flaggedRootAddr = Utils.SetAsRoot(flaggedRootAddr);
                        }
                        break;
                    }
                    SetFlaggedAddress(dct, objAddr, flaggedObjAddr);
                    SetFlaggedAddress(dct, rootAddr, flaggedRootAddr);
                }

                var rootCmp = new ClrtRootObjCmp();
                for (int i = 0, icnt = (int)GCRootKind.Max + 1; i < icnt; ++i)
                {
                    ourRoots[i].Sort(rootCmp);
                }

                Save(rootPath, ourRoots, out error);

                ulong[] rootAddrs = dct.Values.ToArray();
                Utils.SortAddresses(rootAddrs);
                return(rootAddrs, rootCount, finalizerCount);
            }
            catch (Exception ex)
            {
                error = Utils.GetExceptionErrorString(ex);
                return(null, 0, 0);
            }
        }