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)); } }
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); } }