コード例 #1
0
        public static ulong FindOwner(ulong address, ClrDump clrDump, ClrType delegateType, ClrType arrayObjType, HashSet <ulong> visited)
        {
            if (visited.Contains(address))
            {
                return(0);
            }

            var type = clrDump.GetObjectType(address);

            if (type == null)
            {
                return(0);
            }
            if (type != arrayObjType && (type.BaseType == null || type.BaseType != delegateType))
            {
                return(address);
            }

            visited.Add(address);
            foreach (var newAddress in clrDump.GetReferers(address))
            {
                var owner = FindOwner(newAddress, clrDump, delegateType, arrayObjType, visited);
                if (owner != 0)
                {
                    return(owner);
                }
            }

            return(0);
        }
コード例 #2
0
 public InstanceInformation(ClrDump clrDump, ulong address)
 {
     ClrDump = clrDump;
     Address = address;
     ClrType = ClrDump.GetObjectType(Address);
     if (ClrType != null)
     {
         TypeName = ClrType.Name;
     }
 }
コード例 #3
0
 public InstanceInformation(ClrDump clrDump, ulong address)
 {
     ClrDump = clrDump;
     Address = address;
     ClrType = ClrDump.GetObjectType(Address);
     if (ClrType != null)
     {
         TypeName = ClrType.Name;
     }
 }
コード例 #4
0
        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);
        }
コード例 #5
0
 private void OnCellClick(object sender, CellClickEventArgs e)
 {
     if (e.ClickCount == 2 && e.Model != null)
     {
         var arrayInstance = dlvArrays.SelectedObject <ArrayInstanceInformation>();
         if (arrayInstance != null)
         {
             var address = arrayInstance.Address;
             var type    = ClrDump.GetObjectType(address);
             if (type == null)
             {
                 Log($"Can't find type for instance: {address:X}", LogLevelType.Error);
                 return;
             }
             var clrDumpObject = new ClrDumpObject(ClrDump, type, address);
             InstanceDetailsCommand.Display(this, clrDumpObject);
         }
     }
 }
コード例 #6
0
        public static ulong FindOwner(ulong address, ClrDump clrDump, ClrType delegateType, ClrType arrayObjType, HashSet<ulong> visited)
        {
            if( visited.Contains(address))
            {
                return 0;
            }

            var type = clrDump.GetObjectType(address);
            if (type == null) {
                return 0;
            }
            if( type != arrayObjType && (type.BaseType == null || type.BaseType != delegateType ) )
            {
                return address;
            }

            visited.Add(address);
            var refs = clrDump.GetReferers(address);

            foreach(var newAddress in refs)
            {
                var owner = FindOwner(newAddress, clrDump, delegateType, arrayObjType, visited);
                if( owner != 0)
                {
                    return owner;
                }
            }

            return 0;
        }
コード例 #7
0
        public static List<LoneTargetInformation> GetLoneTargetInformations(ClrDump clrDump)
        {
            CancellationTokenSource token = new CancellationTokenSource();
            clrDump.MessageBus.BeginTask("Analyzing lone targets...", token);

            Dictionary<ClrObject, ClrObject> loneTargetAddresses = new Dictionary<ClrObject, ClrObject>();
            // For each instance of every delegate types 
            // let's find all the target objects
            // and select those with only referenced once
            var types = GetDelegateTypes(clrDump);
            foreach(var type in types)
            {
                clrDump.MessageBus.Status($"Analyzing delegate type: {type.Name}");
                if (token.IsCancellationRequested)
                {
                    break;
                }
                int n = 0;
                foreach (var address in clrDump.EnumerateInstances(type)) {
                    if (n++ % 128 == 0)
                    {
                        clrDump.MessageBus.Status($"Analyzing delegate type: {type.Name}, instance #{n:###,###,###,##0}");
                    }
                    var handlerObject = new ClrObject(address, type);
                    foreach(var subHandlerObject in EnumerateHandlers(handlerObject))
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }
                        var target = subHandlerObject[TargetFieldName];
                        int count = clrDump.CountReferers(target.Address);
                        if( count == 1)
                        {
                            loneTargetAddresses[target] = subHandlerObject;
                        }
                    }
                }
            }

            List<LoneTargetInformation> loneTargets = new List<LoneTargetInformation>();

            // foreach lone target, in its reference tree, we try to find the first 
            // object that is not a delegate type or an array of object (ie invocationList)
            var delegateType = clrDump.GetClrType(typeof(MulticastDelegate).FullName);
            var arrayObjType = clrDump.GetClrType(typeof(object[]).FullName);
            HashSet<ulong> visited = new HashSet<ulong>();
            foreach (var kvp in loneTargetAddresses)
            {
                var loneTarget = kvp.Key;
                var handler = kvp.Value;
                var methInfo = GetDelegateMethod(clrDump, handler, loneTarget);
                visited.Clear();
                ulong ownerAddress = FindOwner(handler.Address, clrDump, delegateType, arrayObjType, visited);
                ClrObject owner = new ClrObject(ownerAddress, clrDump.GetObjectType(ownerAddress));
                var loneTargetInformation = new LoneTargetInformation(clrDump, loneTarget, methInfo, owner);
                loneTargets.Add(loneTargetInformation);
            }
            string status = token.IsCancellationRequested ? "cancelled" : "done";
            clrDump.MessageBus.EndTask($"Analyzing lone targets: {status}. Found: {loneTargets.Count}");
            return loneTargets;
        }
コード例 #8
0
        public static List <LoneTargetInformation> GetLoneTargetInformations(ClrDump clrDump)
        {
            CancellationTokenSource token = new CancellationTokenSource();

            clrDump.MessageBus.BeginTask("Analyzing lone targets...", token);

            Dictionary <ClrObject, ClrObject> loneTargetAddresses = new Dictionary <ClrObject, ClrObject>();

            // For each instance of every delegate types
            // let's find all the target objects
            // and select those with only referenced once
            foreach (var type in GetDelegateTypes(clrDump))
            {
                clrDump.MessageBus.Status($"Analyzing delegate type: {type.Name}");
                if (token.IsCancellationRequested)
                {
                    break;
                }
                int n = 0;
                foreach (var address in clrDump.EnumerateInstances(type))
                {
                    if (n++ % 128 == 0)
                    {
                        clrDump.MessageBus.Status($"Analyzing delegate type: {type.Name}, instance #{n:###,###,###,##0}");
                    }
                    var handlerObject = new ClrObject(address, type);
                    foreach (var subHandlerObject in EnumerateHandlers(handlerObject))
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }
                        var target = subHandlerObject[TargetFieldName];
                        int count  = clrDump.CountReferers(target.Address);
                        if (count == 1)
                        {
                            loneTargetAddresses[target] = subHandlerObject;
                        }
                    }
                }
            }

            List <LoneTargetInformation> loneTargets = new List <LoneTargetInformation>();

            // foreach lone target, in its reference tree, we try to find the first
            // object that is not a delegate type or an array of object (ie invocationList)
            var             delegateType = clrDump.GetClrType(typeof(MulticastDelegate).FullName);
            var             arrayObjType = clrDump.GetClrType(typeof(object[]).FullName);
            HashSet <ulong> visited      = new HashSet <ulong>();

            foreach (var kvp in loneTargetAddresses)
            {
                var loneTarget = kvp.Key;
                var handler    = kvp.Value;
                var methInfo   = GetDelegateMethod(clrDump, handler, loneTarget);
                visited.Clear();
                ulong     ownerAddress          = FindOwner(handler.Address, clrDump, delegateType, arrayObjType, visited);
                ClrObject owner                 = new ClrObject(ownerAddress, clrDump.GetObjectType(ownerAddress));
                var       loneTargetInformation = new LoneTargetInformation(clrDump, loneTarget, methInfo, owner);
                loneTargets.Add(loneTargetInformation);
            }
            string status = token.IsCancellationRequested ? "cancelled" : "done";

            clrDump.MessageBus.EndTask($"Analyzing lone targets: {status}. Found: {loneTargets.Count}");
            return(loneTargets);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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;
        }