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}"); } } }
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("-------------------"); // // } // } } }