public TreeNode(CallTreeNodeBase template) { if (template == null) { ThrowHelper.ThrowArgumentNullException(nameof(template)); } this.Id = template.Name; this.ContextId = this.Id; this.ParentContextId = string.Empty; this.ParentId = string.Empty; this.ParentNode = null; this.Name = template.Name; this.FindFlag = string.Empty; this.Visited = false; this.InclusiveMetric = template.InclusiveMetric; this.InclusiveCount = template.InclusiveCount; this.ExclusiveMetric = template.ExclusiveMetric; this.ExclusiveCount = template.ExclusiveCount; this.ExclusiveFoldedMetric = template.ExclusiveFoldedMetric; this.ExclusiveFoldedCount = template.ExclusiveFoldedCount; this.FirstTimeRelativeMSec = template.FirstTimeRelativeMSec; this.LastTimeRelativeMSec = template.LastTimeRelativeMSec; this.InclusiveMetricPercent = template.InclusiveMetric * 100 / template.CallTree.PercentageBasis; this.ExclusiveMetricPercent = template.ExclusiveMetric * 100 / template.CallTree.PercentageBasis; this.ExclusiveFoldedMetricPercent = template.ExclusiveFoldedMetric * 100 / template.CallTree.PercentageBasis; this.HasChildren = false; this.BackingNode = template; //System.Diagnostics.Debug.WriteLine("\n1\n" + template.InclusiveMetricByTimeString + "\n\n"); }
public TreeNode(CallTreeNodeBase template) { if (template == null) { ThrowHelper.ThrowArgumentNullException(nameof(template)); } this.Base64EncodedId = Base64UrlTextEncoder.Encode(Encoding.UTF8.GetBytes(template.Name)); this.Path = string.Empty; this.Name = template.Name; this.InclusiveMetric = template.InclusiveMetric.ToString("N3"); this.InclusiveCount = template.InclusiveCount.ToString("N0"); this.ExclusiveMetric = template.ExclusiveMetric.ToString("N3"); this.ExclusiveCount = template.ExclusiveCount.ToString("N0"); this.ExclusiveFoldedMetric = template.ExclusiveFoldedMetric.ToString("N0"); this.ExclusiveFoldedCount = template.ExclusiveFoldedCount.ToString("N0"); this.InclusiveMetricByTimeString = template.InclusiveMetricByTimeString; this.FirstTimeRelativeMSec = template.FirstTimeRelativeMSec.ToString("N3"); this.LastTimeRelativeMSec = template.LastTimeRelativeMSec.ToString("N3"); this.InclusiveMetricPercent = (template.InclusiveMetric * 100 / template.CallTree.PercentageBasis).ToString("N2"); this.ExclusiveMetricPercent = (template.ExclusiveMetric * 100 / template.CallTree.PercentageBasis).ToString("N2"); this.ExclusiveFoldedMetricPercent = (template.ExclusiveFoldedMetric * 100 / template.CallTree.PercentageBasis).ToString("N2"); this.HasChildren = false; this.BackingNode = template; }
public TreeNode(CallTreeNodeBase template) { if (template == null) { ThrowHelper.ThrowArgumentNullException(nameof(template)); } this.Id = template.Name; this.ContextId = this.Id; this.ParentContextId = string.Empty; this.ParentId = string.Empty; this.Name = template.Name; this.InclusiveMetric = template.InclusiveMetric; this.InclusiveCount = template.InclusiveCount; this.ExclusiveMetric = template.ExclusiveMetric; this.ExclusiveCount = template.ExclusiveCount; this.ExclusiveFoldedMetric = template.ExclusiveFoldedMetric; this.ExclusiveFoldedCount = template.ExclusiveFoldedCount; this.InclusiveMetricByTimeString = template.InclusiveMetricByTimeString; this.FirstTimeRelativeMSec = template.FirstTimeRelativeMSec; this.LastTimeRelativeMSec = template.LastTimeRelativeMSec; this.InclusiveMetricPercent = template.InclusiveMetric * 100 / template.CallTree.PercentageBasis; this.ExclusiveMetricPercent = template.ExclusiveMetric * 100 / template.CallTree.PercentageBasis; this.ExclusiveFoldedMetricPercent = template.ExclusiveFoldedMetric * 100 / template.CallTree.PercentageBasis; this.HasChildren = false; this.BackingNode = template; }
public TreeNode GetCalleeTreeNode(string name, string path = "") { lock (this.lockobj) { CallTreeNodeBase node = this.GetNode(name).BackingNode; TreeNode calleeTreeNode; if (this.calleeTreeCache.ContainsKey(node)) { calleeTreeNode = this.calleeTreeCache[node]; } else { calleeTreeNode = new TreeNode(AggregateCallTreeNode.CalleeTree(node)); this.calleeTreeCache.Add(node, calleeTreeNode); } if (string.IsNullOrEmpty(path)) { return(calleeTreeNode); } var pathArr = path.Split('/'); var pathNodeRoot = calleeTreeNode.Children[int.Parse(pathArr[0])]; for (int i = 1; i < pathArr.Length; ++i) { pathNodeRoot = pathNodeRoot.Children[int.Parse(pathArr[i])]; } return(pathNodeRoot); } }
private StackSourceFrameIndex GetSourceLocation(CallTreeNodeBase node, string cellText, out Dictionary <StackSourceFrameIndex, float> retVal) { var m = Regex.Match(cellText, "<<(.*!.*)>>"); if (m.Success) { cellText = m.Groups[1].Value; } var frameIndexCounts = new Dictionary <StackSourceFrameIndex, float>(); node.GetSamples(false, sampleIdx => { var matchingFrameIndex = StackSourceFrameIndex.Invalid; var sample = this.callTree.StackSource.GetSampleByIndex(sampleIdx); var callStackIdx = sample.StackIndex; while (callStackIdx != StackSourceCallStackIndex.Invalid) { var frameIndex = this.callTree.StackSource.GetFrameIndex(callStackIdx); var frameName = this.callTree.StackSource.GetFrameName(frameIndex, false); if (frameName == cellText) { matchingFrameIndex = frameIndex; } callStackIdx = this.callTree.StackSource.GetCallerIndex(callStackIdx); } if (matchingFrameIndex != StackSourceFrameIndex.Invalid) { frameIndexCounts.TryGetValue(matchingFrameIndex, out float count); frameIndexCounts[matchingFrameIndex] = count + sample.Metric; } return(true); }); var maxFrameIdx = StackSourceFrameIndex.Invalid; float maxFrameIdxCount = -1; foreach (var keyValue in frameIndexCounts) { if (keyValue.Value >= maxFrameIdxCount) { maxFrameIdxCount = keyValue.Value; maxFrameIdx = keyValue.Key; } } retVal = frameIndexCounts; return(maxFrameIdx); }
public static string GetCellStringValue(DataGridCellInfo cell) { CallTreeNodeBase model = cell.Item as CallTreeNodeBase; if (model != null) { switch (((TextBlock)cell.Column.Header).Name) { case "NameColumn": return(model.DisplayName); case "IncPercentColumn": return(model.InclusiveMetricPercent.ToString("n1")); case "IncColumn": return(model.InclusiveMetric.ToString("n1")); case "IncAvgColumn": return(model.AverageInclusiveMetric.ToString("n1")); case "IncCountColumn": return(model.InclusiveCount.ToString("n0")); case "ExcPercentColumn": return(model.ExclusiveMetricPercent.ToString("n1")); case "ExcColumn": return(model.ExclusiveMetric.ToString("n0")); case "ExcCountColumn": return(model.ExclusiveCount.ToString("n0")); case "FoldColumn": return(model.ExclusiveFoldedMetric.ToString("n0")); case "FoldCountColumn": return(model.ExclusiveFoldedCount.ToString("n0")); case "TimeHistogramColumn": return(model.InclusiveMetricByTimeString); case "ScenarioHistogramColumn": return(model.InclusiveMetricByScenarioString); case "FirstColumn": return(model.FirstTimeRelativeMSec.ToString("n3")); case "LastColumn": return(model.LastTimeRelativeMSec.ToString("n3")); } } var frameworkElement = cell.Column.GetCellContent(cell.Item); if (frameworkElement == null) { return(""); } return(GetCellStringValue(frameworkElement)); }
public async ValueTask <TreeNode> GetCalleeTreeNode(string name, string path = "") { if (name == null) { ThrowHelper.ThrowArgumentNullException(nameof(name)); } await this.EnsureInitialized(); var t = this.tuple; var node = this.GetNodeInner(name, t); lock (this.lockObj) { CallTreeNodeBase backingNode = node.BackingNode; TreeNode calleeTreeNode; var c = t.CalleeTreeCache; if (c.ContainsKey(backingNode)) { calleeTreeNode = c[backingNode]; } else { calleeTreeNode = new TreeNode(AggregateCallTreeNode.CalleeTree(backingNode)); c.Add(backingNode, calleeTreeNode); } if (string.IsNullOrEmpty(path)) { return(calleeTreeNode); } var pathArr = path.Split('/'); var pathNodeRoot = calleeTreeNode.Children[int.Parse(pathArr[0])]; for (int i = 1; i < pathArr.Length; ++i) { pathNodeRoot = pathNodeRoot.Children[int.Parse(pathArr[i])]; } return(pathNodeRoot); } }
private Task TestSetTimeRangeWithSpaceImplAsync(CultureInfo culture) { Func <Task <StackWindow> > setupAsync = async() => { await JoinableTaskFactory.SwitchToMainThreadAsync(); var file = new TimeRangeFile(); await OpenAsync(JoinableTaskFactory, file, GuiApp.MainWindow, GuiApp.MainWindow.StatusBar).ConfigureAwait(true); var stackSource = file.GetStackSource(); return(stackSource.Viewer); }; Func <StackWindow, Task> cleanupAsync = async stackWindow => { await JoinableTaskFactory.SwitchToMainThreadAsync(); stackWindow.Close(); }; Func <StackWindow, Task> testDriverAsync = async stackWindow => { await JoinableTaskFactory.SwitchToMainThreadAsync(); var byNameView = stackWindow.m_byNameView; var row = byNameView.FindIndex(node => node.FirstTimeRelativeMSec > 0 && node.FirstTimeRelativeMSec < node.LastTimeRelativeMSec); CallTreeNodeBase selected = byNameView[row]; var selectedCells = stackWindow.ByNameDataGrid.Grid.SelectedCells; selectedCells.Clear(); selectedCells.Add(new DataGridCellInfo(byNameView[row], stackWindow.ByNameDataGrid.FirstTimeColumn)); selectedCells.Add(new DataGridCellInfo(byNameView[row], stackWindow.ByNameDataGrid.LastTimeColumn)); StackWindow.SetTimeRangeCommand.Execute(null, stackWindow.ByNameDataGrid); // Wait for any background processing to complete await stackWindow.StatusBar.WaitForWorkCompleteAsync().ConfigureAwait(true); Assert.Equal(selected.FirstTimeRelativeMSec.ToString("n3", culture), stackWindow.StartTextBox.Text); Assert.Equal(selected.LastTimeRelativeMSec.ToString("n3", culture), stackWindow.EndTextBox.Text); }; return(RunUITestAsync(setupAsync, testDriverAsync, cleanupAsync)); }
private static bool SummaryPredicateFunc(CallTreeNodeBase node) { return(node.Name.StartsWith("Type ")); }
/// <summary> /// Get the call tree node for the specified symbol. /// </summary> /// <param name="symbolName">The symbol.</param> /// <returns>The call tree node representing the symbol, or null if the symbol is not found.</returns> public CallTreeNodeBase GetCallTreeNode(string symbolName) { string[] symbolParts = symbolName.Split(SymbolSeparator); if (symbolParts.Length != 2) { return(null); } // Try to get the call tree node. CallTreeNodeBase node = FindNodeByName(Regex.Escape(symbolName)); // Check to see if the node matches. if (node.Name.StartsWith(symbolName, StringComparison.OrdinalIgnoreCase)) { return(node); } // Check to see if we should attempt to load symbols. if (_traceLog != null && _symbolReader != null && !_resolvedSymbolModules.Contains(symbolParts[0])) { // Look for an unresolved symbols node for the module. string unresolvedSymbolsNodeName = symbolParts[0] + "!?"; node = FindNodeByName(unresolvedSymbolsNodeName); if (node.Name.Equals(unresolvedSymbolsNodeName, StringComparison.OrdinalIgnoreCase)) { // Symbols haven't been resolved yet. Try to resolve them now. TraceModuleFile moduleFile = _traceLog.ModuleFiles.Where(m => m.Name.Equals(symbolParts[0], StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); if (moduleFile != null) { // Special handling for NGEN images. if (symbolParts[0].EndsWith(".ni", StringComparison.OrdinalIgnoreCase)) { SymbolReaderOptions options = _symbolReader.Options; try { _symbolReader.Options = SymbolReaderOptions.CacheOnly; _traceLog.CallStacks.CodeAddresses.LookupSymbolsForModule(_symbolReader, moduleFile); } finally { _symbolReader.Options = options; } } else { _traceLog.CallStacks.CodeAddresses.LookupSymbolsForModule(_symbolReader, moduleFile); } InvalidateCachedStructures(); } } // Mark the module as resolved so that we don't try again. _resolvedSymbolModules.Add(symbolParts[0]); // Try to get the call tree node one more time. node = FindNodeByName(Regex.Escape(symbolName)); // Check to see if the node matches. if (node.Name.StartsWith(symbolName, StringComparison.OrdinalIgnoreCase)) { return(node); } } return(null); }
private static bool SummaryPredicateFunc(CallTreeNodeBase node) { return(node.Name.StartsWith("Managed Contention") || node.Name.StartsWith("Native Contention")); }
private SourceLocation GetSourceLocation(CallTreeNodeBase asCallTreeNodeBase, string cellText, out SortedDictionary <int, float> metricOnLine) { metricOnLine = null; var m = Regex.Match(cellText, "<<(.*!.*)>>"); if (m.Success) { cellText = m.Groups[1].Value; } var frameIndexCounts = new Dictionary <StackSourceFrameIndex, float>(); asCallTreeNodeBase.GetSamples(false, delegate(StackSourceSampleIndex sampleIdx) { var matchingFrameIndex = StackSourceFrameIndex.Invalid; var sample = this.stacksource.GetSampleByIndex(sampleIdx); var callStackIdx = sample.StackIndex; while (callStackIdx != StackSourceCallStackIndex.Invalid) { var frameIndex = this.stacksource.GetFrameIndex(callStackIdx); var frameName = this.stacksource.GetFrameName(frameIndex, false); if (frameName == cellText) { matchingFrameIndex = frameIndex; // We keep overwriting it, so we get the entry closest to the root. } callStackIdx = this.stacksource.GetCallerIndex(callStackIdx); } if (matchingFrameIndex != StackSourceFrameIndex.Invalid) { float count = 0; frameIndexCounts.TryGetValue(matchingFrameIndex, out count); frameIndexCounts[matchingFrameIndex] = count + sample.Metric; } return(true); }); var maxFrameIdx = StackSourceFrameIndex.Invalid; float maxFrameIdxCount = -1; foreach (var keyValue in frameIndexCounts) { if (keyValue.Value >= maxFrameIdxCount) { maxFrameIdxCount = keyValue.Value; maxFrameIdx = keyValue.Key; } } if (maxFrameIdx == StackSourceFrameIndex.Invalid) { return(null); } // Find the most primitive TraceEventStackSource TraceEventStackSource asTraceEventStackSource = GetTraceEventStackSource(this.stacksource); if (asTraceEventStackSource == null) { return(null); } var frameToLine = new Dictionary <StackSourceFrameIndex, int>(); var sourceLocation = asTraceEventStackSource.GetSourceLine(maxFrameIdx, this.reader); if (sourceLocation != null) { var filePathForMax = sourceLocation.SourceFile.BuildTimeFilePath; metricOnLine = new SortedDictionary <int, float>(); // Accumulate the counts on a line basis foreach (StackSourceFrameIndex frameIdx in frameIndexCounts.Keys) { var loc = asTraceEventStackSource.GetSourceLine(frameIdx, this.reader); if (loc != null && loc.SourceFile.BuildTimeFilePath == filePathForMax) { frameToLine[frameIdx] = loc.LineNumber; float metric; metricOnLine.TryGetValue(loc.LineNumber, out metric); metric += frameIndexCounts[frameIdx]; metricOnLine[loc.LineNumber] = metric; } } } bool commonMethodIdxSet = false; MethodIndex commonMethodIdx = MethodIndex.Invalid; var nativeAddressFreq = new SortedDictionary <ulong, Tuple <int, float> >(); foreach (var keyValue in frameIndexCounts) { var codeAddr = asTraceEventStackSource.GetFrameCodeAddress(keyValue.Key); if (codeAddr != CodeAddressIndex.Invalid) { var methodIdx = asTraceEventStackSource.TraceLog.CodeAddresses.MethodIndex(codeAddr); if (methodIdx != MethodIndex.Invalid) { if (!commonMethodIdxSet) { commonMethodIdx = methodIdx; // First time, set it as the common method. } else if (methodIdx != commonMethodIdx) { methodIdx = MethodIndex.Invalid; // More than one method, give up. } commonMethodIdxSet = true; } var nativeAddr = asTraceEventStackSource.TraceLog.CodeAddresses.Address(codeAddr); var lineNum = 0; frameToLine.TryGetValue(keyValue.Key, out lineNum); nativeAddressFreq[nativeAddr] = new Tuple <int, float>(lineNum, keyValue.Value); } } foreach (var keyValue in nativeAddressFreq) { Console.WriteLine(" {0,12:x} : {1,6} {2,10:f1}", keyValue.Key, keyValue.Value.Item1, keyValue.Value.Item2); } if (sourceLocation == null) { return(null); } foreach (var keyVal in metricOnLine) { Console.WriteLine(" Line {0,5}: Metric {1,5:n1}", keyVal.Key, keyVal.Value); } return(sourceLocation); }
private static async Task <int> TopNReport(CancellationToken ct, IConsole console, string traceFile, int number, bool inclusive, bool verbose) { try { string tempEtlxFilename = TraceLog.CreateFromEventPipeDataFile(traceFile); int count = 0; int index = 0; List <CallTreeNodeBase> nodesToReport = new List <CallTreeNodeBase>(); using (var symbolReader = new SymbolReader(System.IO.TextWriter.Null) { SymbolPath = SymbolPath.MicrosoftSymbolServerPath }) using (var eventLog = new TraceLog(tempEtlxFilename)) { var stackSource = new MutableTraceEventStackSource(eventLog) { OnlyManagedCodeStacks = true }; var computer = new SampleProfilerThreadTimeComputer(eventLog, symbolReader); computer.GenerateThreadTimeStacks(stackSource); FilterParams filterParams = new FilterParams() { FoldRegExs = "CPU_TIME;UNMANAGED_CODE_TIME;{Thread (}", }; FilterStackSource filterStack = new FilterStackSource(filterParams, stackSource, ScalingPolicyKind.ScaleToData); CallTree callTree = new(ScalingPolicyKind.ScaleToData); callTree.StackSource = filterStack; List <CallTreeNodeBase> callTreeNodes = null; if (!inclusive) { callTreeNodes = callTree.ByIDSortedExclusiveMetric(); } else { callTreeNodes = callTree.ByIDSortedInclusiveMetric(); } int totalElements = callTreeNodes.Count; while (count < number && index < totalElements) { CallTreeNodeBase node = callTreeNodes[index]; index++; if (!unwantedMethodNames.Any(node.Name.Contains)) { nodesToReport.Add(node); count++; } } PrintReportHelper.TopNWriteToStdOut(nodesToReport, inclusive, verbose); } return(await Task.FromResult(0)); } catch (Exception ex) { Console.Error.WriteLine($"[ERROR] {ex.ToString()}"); } return(await Task.FromResult(0)); }
internal static void TopNWriteToStdOut(List <CallTreeNodeBase> nodesToReport, bool isInclusive, bool isVerbose) { const int functionColumnWidth = 70; const int measureColumnWidth = 20; string measureType = null; if (isInclusive) { measureType = "Inclusive"; } else { measureType = "Exclusive"; } int n = nodesToReport.Count; int maxDigit = n.ToString().Count(); string extra = new string(' ', maxDigit - 1); string header = "Top " + n.ToString() + " Functions (" + measureType + ")"; string uniformHeader = MakeFixedWidth(header, functionColumnWidth + 7); string inclusive = "Inclusive"; string uniformInclusive = MakeFixedWidth(inclusive, measureColumnWidth); string exclusive = "Exclusive"; string uniformExclusive = MakeFixedWidth(exclusive, measureColumnWidth); Console.WriteLine(uniformHeader + extra + uniformInclusive + uniformExclusive); int numLines; for (int i = 0; i < n; i++) { int iLength = (i + 1).ToString().Count(); int numSpace = maxDigit - iLength + 1; CallTreeNodeBase node = nodesToReport[i]; string name = node.Name; string formatName = FormatFunction(name); List <string> nameList = SplitInto(formatName, functionColumnWidth); if (isVerbose) { numLines = nameList.Count; } else { numLines = 1; } for (int j = 0; j < numLines; j++) { string inclusiveMeasure = ""; string exclusiveMeasure = ""; string number = new string(' ', maxDigit + 2); //+2 lines 130 and 137 account for '. ' if (j == 0) { inclusiveMeasure = Math.Round(node.InclusiveMetricPercent, 2).ToString() + "%"; exclusiveMeasure = Math.Round(node.ExclusiveMetricPercent, 2).ToString() + "%"; number = (i + 1).ToString() + "." + number.Substring(maxDigit - numSpace + 2); } string uniformIMeasure = MakeFixedWidth(inclusiveMeasure, measureColumnWidth).PadLeft(measureColumnWidth + 4); string uniformEMeasure = MakeFixedWidth(exclusiveMeasure, measureColumnWidth); Console.WriteLine(number + nameList[j] + uniformIMeasure + uniformEMeasure); } } }
private static bool SummaryPredicateFunc(CallTreeNodeBase node) { return(true); }