Пример #1
0
        public List <ClrRoot> GetClrRoots()
        {
            List <ClrRoot>          clrRoots = new List <ClrRoot>();
            CancellationTokenSource source   = new CancellationTokenSource();
            var token = source.Token;

            MessageBus.BeginTask("Looking for ClrRoots...", source);

            int n = 0;

            foreach (var obj in Runtime.Heap.EnumerateRoots())
            {
                if (token.IsCancellationRequested)
                {
                    break;
                }
                n++;
                if (n % 512 == 0)
                {
                    MessageBus.Status($"Looking for ClrRoots: {clrRoots.Count:###,###,###,##0}");
                }
                clrRoots.Add(obj);
            }
            if (token.IsCancellationRequested)
            {
                MessageBus.EndTask($"ClrRoots (cancelled): {clrRoots.Count:###,###,###,##0} found.");
            }
            else
            {
                MessageBus.EndTask($"ClrRoots : {clrRoots.Count:###,###,###,##0} found.");
            }
            return(clrRoots);
        }
Пример #2
0
        public List <BlockingObject> GetBlockingObjects()
        {
            List <BlockingObject>   blockingObjects = new List <BlockingObject>();
            CancellationTokenSource source          = new CancellationTokenSource();
            var token = source.Token;

            MessageBus.BeginTask("Looking for blocking objects...", source);

            int n = 0;

            foreach (var obj in Runtime.GetHeap().EnumerateBlockingObjects())
            {
                if (token.IsCancellationRequested)
                {
                    break;
                }
                n++;
                if (n % 512 == 0)
                {
                    MessageBus.Status($"Looking for blocking objects: {blockingObjects.Count:###,###,###,##0}");
                }
                blockingObjects.Add(obj);
            }
            if (token.IsCancellationRequested)
            {
                MessageBus.EndTask($"Blocking objects (cancelled): {blockingObjects.Count:###,###,###,##0} found.");
            }
            else
            {
                MessageBus.EndTask($"Blocking objects: {blockingObjects.Count:###,###,###,##0} found.");
            }
            return(blockingObjects);
        }
Пример #3
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);
        }
Пример #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
 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;
 }
Пример #7
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>();
            currentPath.Add(address);
            bool result = FindShortestPath(currentPath, ref bestPath, clrDump);

            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;
        }
Пример #8
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;
        }
Пример #9
0
        public static List<ArrayInstanceInformation> Analyze(ArraysAddressList arrayAddressList, MessageBus msgBus)
        {
            var clrDump = arrayAddressList.ClrDump;
            var clrType = arrayAddressList.ClrType;
            var typeName = clrType.Name;
            CancellationTokenSource token = new CancellationTokenSource();
            msgBus.BeginTask($"Analyzing arrays: {typeName}...", token);

            List<ArrayInstanceInformation> result = clrDump.Eval(() =>
            {
                var tmp = new List<ArrayInstanceInformation>();
                var count = arrayAddressList.Addresses.Count;
                HashSet<object> addresses = new HashSet<object>();

                for (int i=0; i < count; i++) {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }
                    var address = arrayAddressList.Addresses[i];
                    int length = clrType.GetArrayLength(address);
                    if (i % 128 == 0)
                    {
                        msgBus.Status($"Analyzing instance: {i:###,###,###,##0} / {count:###,###,###,##0}");
                    }
                    float? nullRatio = null;
                    float? uniqueRatio = null;

                    if ( clrType.ContainsPointers )
                    {
                        int nbNull = 0;
                        addresses.Clear();
                        for (int j=0; j < length; j++)
                        {
                            object elemAddress = clrType.GetArrayElementValue(address, j);
                            if( elemAddress is ulong && (ulong)elemAddress == 0)
                            {
                                nbNull++;
                            }
                            else if (elemAddress == null)
                            {
                                nbNull++;
                            }
                            else
                            {
                                addresses.Add(elemAddress);
                            }
                            if (j % 1024 == 0 && j !=0)
                            {
                                msgBus.Status($"Analyzing instance: {i:###,###,###,##0} / {count:###,###,###,##0}, element {j:###,###,###,##0} / {length:###,###,###,##0}");
                            }
                        }
                        nullRatio = ((float)nbNull) / length;
                        uniqueRatio = ((float)addresses.Count+nbNull) / length;
                    }

                    ArrayInstanceInformation info = new ArrayInstanceInformation(clrDump, clrType, address, length, nullRatio, uniqueRatio);
                    tmp.Add(info);
                }
                return tmp;
            });
            msgBus.EndTask("Arrays analyzed.");
            return result;
        }
        public static List <ArrayInstanceInformation> Analyze(ArraysAddressList arrayAddressList, MessageBus msgBus)
        {
            var clrDump  = arrayAddressList.ClrDump;
            var clrType  = arrayAddressList.ClrType;
            var typeName = clrType.Name;
            CancellationTokenSource token = new CancellationTokenSource();

            msgBus.BeginTask($"Analyzing arrays: {typeName}...", token);

            List <ArrayInstanceInformation> result = clrDump.Eval(() =>
            {
                var tmp   = new List <ArrayInstanceInformation>();
                var count = arrayAddressList.Addresses.Count;
                HashSet <object> addresses = new HashSet <object>();

                for (int i = 0; i < count; i++)
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }
                    var address = arrayAddressList.Addresses[i];
                    int length  = clrType.GetArrayLength(address);
                    if (i % 128 == 0)
                    {
                        msgBus.Status($"Analyzing instance: {i:###,###,###,##0} / {count:###,###,###,##0}");
                    }
                    float?nullRatio   = null;
                    float?uniqueRatio = null;

                    if (clrType.ContainsPointers)
                    {
                        int nbNull = 0;
                        addresses.Clear();
                        for (int j = 0; j < length; j++)
                        {
                            object elemAddress = clrType.GetArrayElementValue(address, j);
                            if (elemAddress is ulong x && x == 0)
                            {
                                nbNull++;
                            }
                            else if (elemAddress == null)
                            {
                                nbNull++;
                            }
                            else
                            {
                                addresses.Add(elemAddress);
                            }
                            if (j % 1024 == 0 && j != 0)
                            {
                                msgBus.Status($"Analyzing instance: {i:###,###,###,##0} / {count:###,###,###,##0}, element {j:###,###,###,##0} / {length:###,###,###,##0}");
                            }
                        }
                        nullRatio   = ((float)nbNull) / length;
                        uniqueRatio = ((float)addresses.Count + nbNull) / length;
                    }

                    ArrayInstanceInformation info = new ArrayInstanceInformation(clrDump, clrType, address, length, nullRatio, uniqueRatio);
                    tmp.Add(info);
                }
Пример #11
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);
        }
Пример #12
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;
        }