Пример #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));
            }
        }
Пример #2
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);
            }
        }