public static List <RootPathInformation> AnalyzeRootPath(MessageBus msgBus, ClrDumpObject clrDumpObject) { ClrDump clrDump = clrDumpObject.ClrDump; ulong address = clrDumpObject.Address; CancellationTokenSource token = new CancellationTokenSource(); msgBus.BeginTask("Analysing Root Path...", token); if (token.IsCancellationRequested) { msgBus.EndTask("Root Path analysis: cancelled."); return(null); } msgBus.Status("Analysing Root Path: collecting root instances..."); var roots = new HashSet <ulong>(clrDump.EnumerateClrRoots.Select(clrRoot => clrRoot.Object)); if (logger.IsDebugEnabled) { logger.Debug("Roots: " + Str(roots)); } List <ulong> bestPath = null; var currentPath = new List <ulong>(); bool result = FindShortestPath(address, currentPath, ref bestPath, clrDump.GetReferers, roots.Contains, new Dictionary <ulong, List <ulong> >()); if (!result) { currentPath = new List <ulong>(); FindShortestPath(address, currentPath, ref bestPath, clrDump.GetReferers, (addr) => !clrDump.HasReferers(addr), new Dictionary <ulong, List <ulong> >()); } List <RootPathInformation> path = new List <RootPathInformation>(); ulong prevAddress = address; if (bestPath != null) { foreach (var refAddress in bestPath) { var refClrDumpObject = new ClrDumpObject(clrDump, clrDump.GetObjectType(refAddress), refAddress); var fieldName = refAddress == address ? " - " : clrDump.GetFieldNameReference(prevAddress, refAddress); fieldName = TypeHelpers.RealName(fieldName); path.Add(new RootPathInformation(refClrDumpObject, fieldName)); prevAddress = refAddress; } msgBus.EndTask("Root Path found."); } else { msgBus.EndTask("Root Path NOT found."); } return(path); }
public ReferenceInformation(ClrDump clrDump, ulong address, ulong refAddress) : this(clrDump, address) { FieldName = ClrDump.GetFieldNameReference(refAddress, address); FieldName = TypeHelpers.RealName(FieldName); }
public static List <ReferersInformation> AnalyzeReferers(MessageBus msgBus, ClrDump clrDump, HashSet <ulong> addresses) { var referers = new List <ReferersInformation>(); var dicoByRefererType = new Dictionary <ClrType, Dictionary <string, ReferersInformation> >(); CancellationTokenSource token = new CancellationTokenSource(); msgBus.BeginTask("Analyzing referers...", token); Application.DoEvents(); // todo: avoid this call to Application.DoEvents() int count = addresses.Count; int i = 0; foreach (var address in addresses) { i++; if (token.IsCancellationRequested) { msgBus.EndTask("Referers analyze: cancelled."); return(referers); } if (i % 1024 == 0) { msgBus.Status($"Analyzing referers: {(double)i/count:p2}, {i:###,###,###,##0} / {count:###,###,###,##0}..."); Application.DoEvents();// todo: avoid this call to Application.DoEvents() } foreach (var refererAddress in clrDump.EnumerateReferers(address)) { var type = clrDump.GetObjectType(refererAddress); string field; if (type.IsArray) { field = "[ x ]"; } else { field = clrDump.GetFieldNameReference(address, refererAddress); field = TypeHelpers.RealName(field); } Dictionary <string, ReferersInformation> dicoRefInfoByFieldName; if (!dicoByRefererType.TryGetValue(type, out dicoRefInfoByFieldName)) { dicoRefInfoByFieldName = new Dictionary <string, ReferersInformation>(); dicoByRefererType[type] = dicoRefInfoByFieldName; } ReferersInformation referersInformation; if (!dicoRefInfoByFieldName.TryGetValue(field, out referersInformation)) { referersInformation = new ReferersInformation(clrDump, type, field, msgBus, count); dicoRefInfoByFieldName[field] = referersInformation; } referersInformation.References.Add(address); referersInformation.Instances.Add(refererAddress); } } foreach (var kvpType in dicoByRefererType) { var type = kvpType.Key; foreach (var kvpField in kvpType.Value) { var refInfo = kvpField.Value; referers.Add(refInfo); refInfo.Init(); } } msgBus.EndTask("Referers analyzed."); Application.DoEvents();// todo: avoid this call to Application.DoEvents() return(referers); }
public static List<ReferersInformation> AnalyzeReferers(MessageBus msgBus, ClrDump clrDump, HashSet<ulong> addresses) { var referers = new List<ReferersInformation>(); var dicoByRefererType = new Dictionary<ClrType, Dictionary<string, ReferersInformation>>(); CancellationTokenSource token = new CancellationTokenSource(); msgBus.BeginTask("Analyzing referers...", token); Application.DoEvents(); // todo: avoid this call to Application.DoEvents() int count = addresses.Count; int i = 0; foreach(var address in addresses) { i++; if( token.IsCancellationRequested) { msgBus.EndTask("Referers analyze: cancelled."); return referers; } if ( i % 1024 == 0) { msgBus.Status($"Analyzing referers: {(double)i/count:p2}, {i:###,###,###,##0} / {count:###,###,###,##0}..."); Application.DoEvents();// todo: avoid this call to Application.DoEvents() } foreach( var refererAddress in clrDump.EnumerateReferers(address)) { var type = clrDump.GetObjectType(refererAddress); string field; if (type.IsArray) { field = "[ x ]"; } else { field = clrDump.GetFieldNameReference(address, refererAddress); field = TypeHelpers.RealName(field); } Dictionary<string, ReferersInformation> dicoRefInfoByFieldName; if( ! dicoByRefererType.TryGetValue(type, out dicoRefInfoByFieldName)) { dicoRefInfoByFieldName = new Dictionary<string, ReferersInformation>(); dicoByRefererType[type] = dicoRefInfoByFieldName; } ReferersInformation referersInformation; if ( ! dicoRefInfoByFieldName.TryGetValue(field, out referersInformation)) { referersInformation = new ReferersInformation(clrDump, type, field, msgBus, count); dicoRefInfoByFieldName[field] = referersInformation; } referersInformation.References.Add(address); referersInformation.Instances.Add(refererAddress); } } foreach(var kvpType in dicoByRefererType) { var type = kvpType.Key; foreach(var kvpField in kvpType.Value) { var refInfo = kvpField.Value; referers.Add(refInfo); refInfo.Init(); } } msgBus.EndTask("Referers analyzed."); Application.DoEvents();// todo: avoid this call to Application.DoEvents() return referers; }