Exemple #1
0
        public static ClrtRootInfo Load(int rtm, DumpFileMoniker fileMoniker, out string error)
        {
            error = null;
            BinaryReader bw = null;

            try
            {
                var path = fileMoniker.GetFilePath(rtm, Constants.MapRootsInfoFilePostfix);
                bw = new BinaryReader(File.Open(path, FileMode.Open));

                // root details
                //
                int          count = bw.ReadInt32();
                ClrtRoot[][] roots = new ClrtRoot[count][];
                for (int i = 0; i < count; ++i)
                {
                    int kindCount = bw.ReadInt32();
                    roots[i] = new ClrtRoot[kindCount];
                    for (int j = 0; j < kindCount; ++j)
                    {
                        roots[i][j] = ClrtRoot.Load(bw);
                    }
                }
                return(new ClrtRootInfo(roots));
            }
            catch (Exception ex)
            {
                error = Utils.GetExceptionErrorString(ex);
                return(null);
            }
            finally
            {
                bw?.Close();
            }
        }
Exemple #2
0
 public ClrtRoot(ClrtRoot root)
 {
     Address         = root.Address;
     Object          = root.Object;
     TypeId          = root.TypeId;
     NameId          = root.DomainId;
     RootKind        = root.RootKind;
     DomainId        = root.DomainId;
     OsThreadId      = root.OsThreadId;
     ManagedThreadId = root.ManagedThreadId;
 }
Exemple #3
0
        public bool GetRootInfo(ulong addr, out ClrtRoot info, out bool inFinalizerQueue)
        {
            inFinalizerQueue = Array.BinarySearch(_finalizerQue, addr) >= 0;
            var ndx = Array.BinarySearch(_objectAddresses, addr);

            if (ndx >= 0)
            {
                info = _clrtRoots[_objectAddressMap[ndx]];
                return(true);
            }
            return(GetRootInfoByAddress(addr, out info));
        }
Exemple #4
0
        public bool GetRootInfoByAddress(ulong addr, out ClrtRoot info)
        {
            var ndx = Array.BinarySearch(_rootAddresses, addr);

            if (ndx < 0)
            {
                info = ClrtRoot.EmptyClrtRoot;
                return(false);
            }

            info = _clrtRoots[_rootAddressMap[ndx]];
            return(true);
        }
Exemple #5
0
        public static void SortRoots(ClrtRoot[] roots, out int[] kindOffsets, out ulong[] addresses, out int[] addressMap, out ulong[] objects, out int[] objectMap)
        {
            objects     = Utils.EmptyArray <ulong> .Value;
            objectMap   = Utils.EmptyArray <int> .Value;
            kindOffsets = Utils.EmptyArray <int> .Value;
            addresses   = objects;
            addressMap  = objectMap;
            if (roots == null || roots.Length < 1)
            {
                return;
            }
            Array.Sort(roots, new ClrtRootKindCmp());

            List <int> offs = new List <int>(16)
            {
                0
            };

            ClrtRoot.Kinds pkind = ClrtRoot.GetGCRootKindPart(roots[0].RootKind);
            objects       = new ulong[roots.Length];
            objectMap     = new int[roots.Length];
            objects[0]    = roots[0].Object;
            objectMap[0]  = 0;
            addresses     = new ulong[roots.Length];
            addressMap    = new int[roots.Length];
            addresses[0]  = roots[0].Address;
            addressMap[0] = 0;
            for (int i = 1, icnt = roots.Length; i < icnt; ++i)
            {
                objects[i]    = roots[i].Object;
                objectMap[i]  = i;
                addresses[i]  = roots[i].Address;
                addressMap[i] = i;
                var kind = ClrtRoot.GetGCRootKindPart(roots[0].RootKind);
                if (pkind != kind)
                {
                    offs.Add(i);
                    pkind = kind;
                }
            }
            offs.Add(roots.Length);
            kindOffsets = offs.ToArray();
            Array.Sort(objects, objectMap);
            Array.Sort(addresses, addressMap);
        }
Exemple #6
0
        // TODO JRD -- delete later
        public static ClrtRoots GetRoots(ClrHeap heap, ulong[] instances, int[] types, StringIdAsyncDct 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())
            {
                var rootObj = root.Object;
                if (root.Kind == GCRootKind.Finalizer)
                {
                    finalizeQue.Add(rootObj);
                    var obj = Array.BinarySearch(instances, rootObj);
                    if (obj < 0)
                    {
                        obj = Constants.InvalidIndex;
                    }
                    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     = Array.BinarySearch(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     = Array.BinarySearch(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));
        }
Exemple #7
0
 public RootInfo(ClrtRoot root, bool inFinalizerQueue)
 {
     _root             = root;
     _inFinalizerQueue = inFinalizerQueue;
 }
Exemple #8
0
 public static bool IsDummyRoot(ClrtRoot root)
 {
     return(root.Address == Constants.InvalidAddress && root.Object == Constants.InvalidAddress);
 }
Exemple #9
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));
            }
        }
Exemple #10
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);
            }
        }