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(); } }
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; }
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)); }
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); }
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); }
// 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)); }
public RootInfo(ClrtRoot root, bool inFinalizerQueue) { _root = root; _inFinalizerQueue = inFinalizerQueue; }
public static bool IsDummyRoot(ClrtRoot root) { return(root.Address == Constants.InvalidAddress && root.Object == Constants.InvalidAddress); }
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); } }