コード例 #1
0
        public static long CountTargets(ClrDump clrDump, ClrType clrType)
        {
            long count           = 0;
            var  targetField     = clrType.GetFieldByName(TargetFieldName);
            var  invocCountField = clrType.GetFieldByName(InvocationCountFieldName);

            foreach (ulong address in clrDump.EnumerateInstances(clrType))
            {
                count += CountTargets(address, clrType, targetField, invocCountField);
            }
            return(count);
        }
コード例 #2
0
        internal static List <ArraysInformation> Analyse(ClrDump clrDump, MessageBus msgBus)
        {
            CancellationTokenSource token = new CancellationTokenSource();
            var arrays = new List <ArraysInformation>();

            msgBus.BeginTask("Analyzing arrays...", token);
            int n = 0;

            clrDump.Run(() =>
            {
                var arrayTypes  = clrDump.AllTypes.Where(t => t.IsArray);
                int nbArrayType = arrayTypes.Count();
                foreach (var type in arrayTypes)
                {
                    string typeName = type.Name;
                    msgBus.Status($"Analyzing array type: {typeName} ({n:###,###,###,##0}/{nbArrayType:###,###,###,##0})");
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    n++;
                    ulong nbInstances = 0;
                    ulong totalSize   = 0;
                    ulong totalLength = 0;
                    ulong maxLength   = 0;
                    foreach (var address in clrDump.EnumerateInstances(type))
                    {
                        nbInstances++;
                        var length   = (ulong)(type.GetArrayLength(address));
                        maxLength    = Math.Max(maxLength, length);
                        totalSize   += type.GetSize(address);
                        totalLength += length;
                        if (nbInstances % 512 == 0)
                        {
                            msgBus.Status($"Analyzing array: #{nbInstances:###,###,###,##0} for type: {typeName}");
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }
                        }
                    }
                    arrays.Add(new ArraysInformation(new ClrDumpType(clrDump, type), nbInstances, totalLength, maxLength, totalSize));
                }
            });
            msgBus.EndTask($"Arrays analyzed. Types: {n:###,###,###,##0}");
            return(arrays);
        }
コード例 #3
0
        internal static List <StringInformation> Analyse(ClrDump clrDump, MessageBus msgBus)
        {
            var stringType      = clrDump.GetClrType(typeof(string).FullName);
            var stringInstances = clrDump.EnumerateInstances(stringType);
            int nbStrings       = clrDump.CountInstances(stringType);
            Dictionary <string, List <ulong> > result = new Dictionary <string, List <ulong> >();
            CancellationTokenSource            token  = new CancellationTokenSource();

            msgBus.BeginTask("Analyzing strings...", token);
            int n = 0;

            clrDump.Run(() =>
            {
                foreach (var address in stringInstances)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    n++;
                    var value = SimpleValueHelper.GetSimpleValue(address, stringType, false) as string;
                    if (value == null)
                    {
                        continue;
                    }
                    List <ulong> addresses;
                    if (!result.TryGetValue(value, out addresses))
                    {
                        addresses     = new List <ulong>();
                        result[value] = addresses;
                    }
                    addresses.Add(address);
                    if (n % 1024 == 0)
                    {
                        float pct = (float)n / nbStrings;
                        msgBus.Status($"Analyzing strings: {pct:p2}, n= {n:###,###,###,##0} / {nbStrings:###,###,###,##0}");
                    }
                }
            });
            msgBus.EndTask($"Strings analyzed. Instances: {n:###,###,###,##0}, unique values: {result.Count:###,###,###,##0}");

            var strings = result.Select(kvp => new StringInformation(kvp.Key, kvp.Value)).ToList();

            return(strings);
        }
コード例 #4
0
 internal static List<ArraysInformation> Analyse(ClrDump clrDump, MessageBus msgBus)
 {
     CancellationTokenSource token = new CancellationTokenSource();
     var arrays = new List<ArraysInformation>();
     msgBus.BeginTask("Analyzing arrays...", token);
     int n = 0;
     clrDump.Run(() =>
     {
         var arrayTypes = clrDump.AllTypes.Where(t => t.IsArray);
         int nbArrayType = arrayTypes.Count();
         foreach (var type in arrayTypes)
         {
             string typeName = type.Name;
             msgBus.Status($"Analyzing array type: {typeName} ({n:###,###,###,##0}/{nbArrayType:###,###,###,##0})");
             if ( token.IsCancellationRequested )
             {
                 return;
             }
             n++;
             ulong nbInstances = 0;
             ulong totalSize = 0;
             ulong totalLength = 0;
             ulong maxLength = 0;
             foreach (var address in clrDump.EnumerateInstances(type))
             {
                 nbInstances++;
                 var length = (ulong)(type.GetArrayLength(address));
                 maxLength = Math.Max(maxLength, length);
                 totalSize += type.GetSize(address);
                 totalLength += length;
                 if (nbInstances % 512 == 0)
                 {
                     msgBus.Status($"Analyzing array: #{nbInstances:###,###,###,##0} for type: {typeName}");
                     if (token.IsCancellationRequested)
                     {
                         return;
                     }
                 }
             }
             arrays.Add(new ArraysInformation(new ClrDumpType(clrDump, type), nbInstances, totalLength, maxLength, totalSize));
         }
     });
     msgBus.EndTask($"Arrays analyzed. Types: {n:###,###,###,##0}");
     return arrays;
 }
コード例 #5
0
        internal static List<StringInformation> Analyse(ClrDump clrDump, MessageBus msgBus)
        {
            var stringType = clrDump.GetClrType(typeof(string).FullName);
            var stringInstances = clrDump.EnumerateInstances(stringType);
            int nbStrings = clrDump.CountInstances(stringType);
            Dictionary <string, List<ulong>> result = new Dictionary<string, List<ulong>>();
            CancellationTokenSource token = new CancellationTokenSource();
            msgBus.BeginTask("Analyzing strings...", token);
            int n = 0;
            clrDump.Run(() =>
            {
                foreach (var address in stringInstances)
                {
                    if( token.IsCancellationRequested)
                    {
                        return;
                    }
                    n++;
                    var value = SimpleValueHelper.GetSimpleValue(address, stringType, false) as string;
                    if (value == null)
                    {
                        continue;
                    }
                    List<ulong> addresses;
                    if( ! result.TryGetValue(value, out addresses))
                    {
                        addresses = new List<ulong>();
                        result[value] = addresses;
                    }
                    addresses.Add(address);
                    if( n  % 1024 == 0)
                    {
                        float pct = (float)n / nbStrings;
                        msgBus.Status($"Analyzing strings: {pct:p2}, n= {n:###,###,###,##0} / {nbStrings:###,###,###,##0}");
                    }
                }
            });
            msgBus.EndTask($"Strings analyzed. Instances: {n:###,###,###,##0}, unique values: {result.Count:###,###,###,##0}");

            var strings = result.Select(kvp => new StringInformation(kvp.Key, kvp.Value)).ToList();
            return strings;
        }
コード例 #6
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;
        }
コード例 #7
0
        public static long CountTargets(ClrDump clrDump, ClrType clrType)
        {
            long count = 0;
            var targetField = clrType.GetFieldByName(TargetFieldName);
            var invocCountField = clrType.GetFieldByName(InvocationCountFieldName);

            foreach (ulong address in clrDump.EnumerateInstances(clrType))
            {
                count += CountTargets(address, clrType, targetField, invocCountField);
            }
            return count;
        }
コード例 #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
ファイル: ClrDumpType.cs プロジェクト: xlfj5211/MemoScope.Net
 internal IEnumerable <ulong> EnumerateInstances()
 {
     return(ClrDump.EnumerateInstances(ClrType));
 }
コード例 #10
0
 internal IEnumerable <ulong> EnumerateInstances() => ClrDump.EnumerateInstances(ClrType);