示例#1
0
    private async Task ProcessCommand2(ILogger <Program> logger)
    {
        string filePath       = @"C:\Users\Ne4to\projects\GitHub\Ne4to\Heartbeat\tests\dumps\AsyncStask.dmp";
        string?dacPath        = null;
        bool   ignoreMismatch = false;

        var     dataTarget = DataTarget.LoadDump(filePath);
        ClrInfo clrInfo    = dataTarget.ClrVersions[0];
        var     clrRuntime = dacPath == null
            ? clrInfo.CreateRuntime()
            : clrInfo.CreateRuntime(dacPath, ignoreMismatch);

        var runtimeContext = new RuntimeContext(clrRuntime, filePath);
        var traversingMode = _commandLineOptions.TraversingHeapMode;

        ExecuteWhenTrue(PrintHttpClients, _commandLineOptions.HttpClient);
        ExecuteWhenTrue(PrintStringDuplicates, _commandLineOptions.StringDuplicate);
        ExecuteWhenTrue(PrintObjectTypeStatistics, _commandLineOptions.ObjectTypeStatistics);
        ExecuteWhenTrue(PrintTimerQueueTimers, _commandLineOptions.TimerQueueTimer);
        ExecuteWhenTrue(PrintLongStrings, _commandLineOptions.LongString);

        void PrintHttpClients()
        {
            var analyzer = new HttpClientAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var httpClients = analyzer.GetClientsInfo();

            foreach (var httpclient in httpClients)
            {
                logger.LogInformation($"{httpclient.Address} timeout = {httpclient.Timeout.TotalSeconds:F2} seconds");
            }
        }

        void PrintStringDuplicates()
        {
            var analyzer = new StringDuplicateAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var duplicates = analyzer.GetStringDuplicates(10, 100);

            foreach (var duplicate in duplicates)
            {
                logger.LogInformation($"{duplicate.Count} instances of: {duplicate.String}");
            }
        }

        void PrintObjectTypeStatistics()
        {
            var analyzer = new ObjectTypeStatisticsAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var statistics = analyzer.GetObjectTypeStatistics();

            foreach (var stat in statistics)
            {
                logger.LogInformation($"{stat.TypeName}: {stat.TotalSize} ({stat.InstanceCount} instances)");
            }
        }

        void PrintTimerQueueTimers()
        {
            var analyzer = new TimerQueueTimerAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var timers = analyzer.GetTimers(traversingMode);

            foreach (var timer in timers)
            {
                logger.LogInformation($"{timer.Address} m_dueTime = {timer.DueTime}, m_period = {timer.Period}, m_canceled = {timer.Cancelled}");

                if (timer.CancellationState != null)
                {
                    logger.LogInformation($"CanBeCanceled: {timer.CancellationState.CanBeCanceled}");
                    logger.LogInformation($"IsCancellationRequested: {timer.CancellationState.IsCancellationRequested}");
                    logger.LogInformation($"IsCancellationCompleted: {timer.CancellationState.IsCancellationCompleted}");
                }
            }
        }

        void PrintLongStrings()
        {
            var analyzer = new LongStringAnalyzer(runtimeContext);

            analyzer.TraversingHeapMode = traversingMode;

            var strings = analyzer.GetStrings(20, null);

            foreach (var s in strings)
            {
                logger.LogInformation($"{s.Address} Length = {s.Length} chars, Value = {s.Value}");
            }
        }
    }
示例#2
0
    private void ProcessCommand(DataTarget dataTarget, ILogger logger)
    {
        logger.LogInformation($"Host PID: {Process.GetCurrentProcess().Id}");

        var clrInfo = dataTarget.ClrVersions[0];

        logger.LogInformation($"Flavor: {clrInfo.Flavor}");
        logger.LogInformation($"Dac: {clrInfo.DacInfo.PlatformAgnosticFileName}");
        logger.LogInformation($"Module: {clrInfo.ModuleInfo}");
        logger.LogInformation($"TargetArchitecture: {clrInfo.DacInfo.TargetArchitecture}");

        using var runtime = CreateRuntime(clrInfo);
        var runtimeContext = new RuntimeContext(runtime, string.Empty);

        var heap = runtime.Heap;

        logger.LogInformation($"Can Walk Heap: {heap.CanWalkHeap}");

        // heap.LogTopMemObjects(logger, 10, 1, 1);

        if (_commandLineOptions.TaskCompletionSource)
        {
            LogExtensions.LogTaskCompletionSources(logger, runtimeContext);
        }

        if (_commandLineOptions.ServicePointManager)
        {
            var servicePointManagerAnalyzer = new ServicePointManagerAnalyzer(runtimeContext);
            servicePointManagerAnalyzer.Dump(logger);
        }

        if (_commandLineOptions.LongString)
        {
            LongStringAnalyzer longStringAnalyzer = new LongStringAnalyzer(runtimeContext);
            longStringAnalyzer.TraversingHeapMode = _commandLineOptions.TraversingHeapMode;
            longStringAnalyzer.Dump(logger);
        }

        if (_commandLineOptions.AsyncStateMachine)
        {
            var asyncStateMachineAnalyzer = new AsyncStateMachineAnalyzer(runtimeContext);
            asyncStateMachineAnalyzer.TraversingHeapMode = _commandLineOptions.TraversingHeapMode;
            asyncStateMachineAnalyzer.Dump(logger);
        }

        if (_commandLineOptions.Heap)
        {
            // LogExtensions.LogHeapSegments(runtimeContext.Heap, logger);
            // var modulesAnalyzer = new ModulesAnalyzer(runtimeContext);
            // modulesAnalyzer.Dump(logger);
        }

        if (_commandLineOptions.Task)
        {
            LogExtensions.LogTaskObjects(
                runtimeContext,
                logger,
                true,
                false);
        }

        // var dictionaryProxy = new DictionaryProxy(runtimeContext, 0x1dccd3aec28);
        // var dictionaryProxy = new DictionaryProxy(runtimeContext, 0x000001dccd176650);
        // var dictionaryProxy = new DictionaryProxy(runtimeContext, 0x000001dccd1aba48);
        // dictionaryProxy.Dump(logger);

        // var dictionaryProxy2 = new DictionaryProxy(runtimeContext, 0x000001dccd2dd198);
        // var dictionaryProxy2 = new DictionaryProxy(runtimeContext, 0x000001dccef138b8);
        // dictionaryProxy2.Dump<char, int>(logger);

        // foreach (var segment in runtime.Heap.Segments)
        // {
        //     segment.EnumerateObjects()
        // }
        //
        // var q = from obj in runtime.Heap.EnumerateObjects()
        //     where obj.Type != null
        //           && obj.Type.Name == "System.Byte[]"
        //     select obj;
        //
        // foreach (var o in q.Take(10))
        // {
        //     System.Console.WriteLine($"{o.Address:X} {o.Type}");
        // }
        //
        // return;

        // ProcessByteArrays(runtime);

        ulong totalLohSegmentSize = 0;
        ulong totalLohObjSize     = 0;
        ulong totalLohArraySize   = 0;

        foreach (var segment in runtime.Heap.Segments)
        {
            if (!segment.IsLargeObjectSegment)
            {
                continue;
            }

            totalLohSegmentSize += segment.Length;

            var query = from obj in segment.EnumerateObjects()
                        select obj;

            foreach (var obj in query)
            {
                if (!obj.IsFree)
                {
                    totalLohObjSize += obj.Size;
                }

                var isArray = obj.Type?.Name == "System.Byte[]";
                if (isArray)
                {
                    totalLohArraySize += obj.Size;
                }
            }
        }

        System.Console.WriteLine($"LOH: segments {Size.ToString(totalLohSegmentSize)} all objects {Size.ToString(totalLohObjSize)} byte arrays {Size.ToString(totalLohArraySize)}");

        var q = from obj in runtime.Heap.EnumerateObjects()
                where obj.Type?.Name == "System.Net.Http.HttpResponseMessage"
                select obj;

        var countByDiscoveryKey = new Dictionary <string, int>();

        long totalRequestLoh             = 0;
        var  requestTotalByDiscoveryKey  = new Dictionary <string, long>();
        long totalResponseLoh            = 0;
        var  responseTotalByDiscoveryKey = new Dictionary <string, long>();

        foreach (var responseObj in q)
        {
            var requestMessageObj = responseObj.ReadObjectField("requestMessage");
            var uriProxy          = new UriProxy(runtimeContext, requestMessageObj.ReadObjectField("requestUri"));

            var(requestLength, requestLOH)   = GetRequestLength(responseObj, runtimeContext);
            var(responseLength, responseLOH) = GetResponseLength(responseObj, runtimeContext);
            // if (uriProxy.Value.Contains("c558fd4d8151489bbaf58896725d7540"))
            // {
            //     System.Console.WriteLine(
            //         $"{uriProxy.Value} {requestLength} {requestLOH} {responseLength} {responseLOH}");
            // }

            var discoveryKey = GetDiscoveryKey(uriProxy);
            if (discoveryKey != null)
            {
                countByDiscoveryKey.IncrementValue(discoveryKey);
            }

            if (requestLOH ?? false)
            {
                totalRequestLoh += requestLength ?? 0;
                if (discoveryKey != null)
                {
                    requestTotalByDiscoveryKey.IncrementValue(discoveryKey, requestLength ?? 0);
                }
            }

            if (responseLOH ?? false)
            {
                totalResponseLoh += responseLength ?? 0;
                if (discoveryKey != null)
                {
                    responseTotalByDiscoveryKey.IncrementValue(discoveryKey, responseLength ?? 0);
                }
            }
            // var bufferObj = streamObject.ReadObjectField("_buffer");
        }

        System.Console.WriteLine($"Total Request LOH: {Size.ToString(totalRequestLoh)} Total Response LOH: {Size.ToString(totalResponseLoh)}");

        System.Console.WriteLine("Requests by service");
        WriteTotals(requestTotalByDiscoveryKey, countByDiscoveryKey);
        System.Console.WriteLine("Responses by service");
        WriteTotals(responseTotalByDiscoveryKey, countByDiscoveryKey);

        return;

        foreach (var segment in runtime.Heap.Segments)
        {
            if (!segment.IsLargeObjectSegment)
            {
                continue;
            }

            var query = from obj in segment.EnumerateObjects()
                        where obj.Type?.Name == "System.Byte[]"
                        select obj;

            foreach (var arrayObject in query.Take(10))
            {
                System.Console.WriteLine(arrayObject.AsArray().Length);
            }

            // var query = from obj in segment.EnumerateObjects()
            //     where obj.Type?.Name == "System.Net.HttpWebRequest"
            //         && obj.Address == 0x1fd003e0a08
            //     select obj;

            // foreach (var requestObject in query)
            // {
            //     var uriProxy = new UriProxy(runtimeContext, requestObject.ReadObjectField("_Uri"));
            //     System.Console.WriteLine($"{requestObject} {uriProxy.Value}");
            //
            //     var responseObject = requestObject.ReadObjectField("_HttpResponse");
            //     var m_CoreResponseDataObject = responseObject.ReadObjectField("m_CoreResponseData");
            //     var m_ConnectStreamObject = m_CoreResponseDataObject.ReadObjectField("m_ConnectStream");
            //
            //     if (requestObject.IsNull)
            //     {
            //         System.Console.WriteLine("NO RESPONSE");
            //     }
            //     else
            //     {
            //         var responseLength = responseObject.ReadField<long>("m_ContentLength");
            //         System.Console.WriteLine($"Response content length: {responseLength.ToMemorySizeString()}");
            //
            //         // Retention path of System.Net.ConnectStream
            //         //
            //         // 0x000001fc90e69720 System.Net.HttpWebRequest._HttpResponse ->
            //         // 0x000001fc903248e0 System.Net.HttpWebResponse.m_CoreResponseData ->
            //         // 0x000001fc903248a8 System.Net.CoreResponseData.m_ConnectStream ->
            //         // 0x000001fc90324718 System.Net.ConnectStream
            //
            //
            //     }
            //
            //
            //     // if (clrObject.Address == 0x202eed90288)
            //     // {
            //     //     System.Console.WriteLine($"{clrObject} {clrObject.Size}");
            //     //
            //     //     var bytes = new byte[clrObject.Size];
            //     //     Span<byte> span = new Span<byte>(bytes);
            //     //     dataTarget.DataReader.Read(clrObject.Address, span);
            //     //
            //     //     var str = Encoding.UTF8.GetString(span);
            //     //     System.Console.WriteLine(str);
            //     //     System.Console.WriteLine("-------------------");
            //     // }
            // }
        }
    }