private void SetTypePriorities(string priorityPats)
        {
            if (m_typePriorities == null)
            {
                m_typePriorities = new float[(int)m_graph.NodeTypeIndexLimit];
            }

            string[] priorityPatArray   = priorityPats.Split(';');
            Regex[]  priorityRegExArray = new Regex[priorityPatArray.Length];
            float[]  priorityArray      = new float[priorityPatArray.Length];
            for (int i = 0; i < priorityPatArray.Length; i++)
            {
                var m = Regex.Match(priorityPatArray[i], @"(.*)->(-?\d+.?\d*)");
                if (!m.Success)
                {
                    if (string.IsNullOrWhiteSpace(priorityPatArray[i]))
                    {
                        continue;
                    }

                    throw new ApplicationException("Priority pattern " + priorityPatArray[i] + " is not of the form Pat->Num.");
                }

                var dotNetRegEx = FilterStackSource.ToDotNetRegEx(m.Groups[1].Value.Trim());
                priorityRegExArray[i] = new Regex(dotNetRegEx, RegexOptions.IgnoreCase);
                priorityArray[i]      = float.Parse(m.Groups[2].Value);
            }

            // Assign every type index a priority in m_typePriorities based on if they match a pattern.
            NodeType typeStorage = m_graph.AllocTypeNodeStorage();

            for (NodeTypeIndex typeIdx = 0; typeIdx < m_graph.NodeTypeIndexLimit; typeIdx++)
            {
                var type = m_graph.GetType(typeIdx, typeStorage);

                var fullName = type.Name;
                for (int regExIdx = 0; regExIdx < priorityRegExArray.Length; regExIdx++)
                {
                    var priorityRegEx = priorityRegExArray[regExIdx];
                    if (priorityRegEx == null)
                    {
                        continue;
                    }

                    var m = priorityRegEx.Match(fullName);
                    if (m.Success)
                    {
                        m_typePriorities[(int)typeIdx] = priorityArray[regExIdx];
                        // m_log.WriteLine("Type {0} assigned priority {1:f3}", fullName, priorityArray[regExIdx]);
                        break;
                    }
                }
            }
        }
        public CallTreeDataProvider(TraceLog log, FilterParams filterParams, SymbolReader reader, ITraceDataPlugin plugin)
        {
            if (log == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(log));
            }

            if (filterParams == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(filterParams));
            }

            if (reader == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(reader));
            }

            if (plugin == null)
            {
                ThrowHelper.ThrowArgumentNullException(nameof(plugin));
            }

            this.reader = reader;
            TraceEvents events = log.Events;
            var         unfilteredStacksource = plugin.GetStackSource(events);

            this.summaryPredicate       = plugin.SummaryPredicate;
            CallTree.DisableParallelism = true; // important
            this.stacksource            = new FilterStackSource(filterParams, unfilteredStacksource, ScalingPolicyKind.TimeMetric);
            this.callTree = new CallTree(ScalingPolicyKind.TimeMetric)
            {
                StackSource = this.stacksource
            };

            // Indicate I want the Time histograms to be computed.
            double startTimeRelativeMsec = 0;

            double.TryParse(filterParams.StartTimeRelativeMSec, out startTimeRelativeMsec);
            //System.Diagnostics.Debug.WriteLine("\n\nTIME: 1" + filterParams.StartTimeRelativeMSec + "\n2 " + startTimeRelativeMsec + "\n3 " + this.stacksource.SampleTimeRelativeMSecLimit + "\n\n");
            callTree.TimeHistogramController = new TimeHistogramController(callTree, startTimeRelativeMsec, this.stacksource.SampleTimeRelativeMSecLimit);
            float minIncusiveTimePercent;

            if (float.TryParse(filterParams.MinInclusiveTimePercent, out minIncusiveTimePercent) && minIncusiveTimePercent > 0)
            {
                this.callTree.FoldNodesUnder(minIncusiveTimePercent * this.callTree.Root.InclusiveMetric / 100, true);
            }
        }
Example #3
0
        private async Task Initialize()
        {
            await this.semaphoreSlim.WaitAsync();

            try
            {
                if (this.initialized == 1)
                {
                    return;
                }

                var filterParams = new FilterParams
                {
                    StartTimeRelativeMSec   = this.model.Start,
                    EndTimeRelativeMSec     = this.model.End,
                    ExcludeRegExs           = this.model.ExcPats,
                    IncludeRegExs           = this.model.IncPats,
                    FoldRegExs              = this.model.FoldPats,
                    GroupRegExs             = this.model.GroupPats,
                    MinInclusiveTimePercent = this.model.FoldPct,
                    Name = "NoName",
                };

                var ss = new FilterStackSource(filterParams, this.stackSource, ScalingPolicyKind.TimeMetric);

                double startTimeRelativeMsec = double.TryParse(filterParams.StartTimeRelativeMSec, out startTimeRelativeMsec) ? Math.Max(startTimeRelativeMsec, 0.0) : 0.0;
                double endTimeRelativeMsec   = double.TryParse(filterParams.EndTimeRelativeMSec, out endTimeRelativeMsec) ? Math.Min(endTimeRelativeMsec, this.stackSource.SampleTimeRelativeMSecLimit) : this.stackSource.SampleTimeRelativeMSecLimit;

                var c = new CallTree(ScalingPolicyKind.TimeMetric);
                c.TimeHistogramController = new TimeHistogramController(c, startTimeRelativeMsec, endTimeRelativeMsec);
                c.StackSource             = ss;

                if (float.TryParse(filterParams.MinInclusiveTimePercent, out float minIncusiveTimePercent) && minIncusiveTimePercent > 0)
                {
                    c.FoldNodesUnder(minIncusiveTimePercent * c.Root.InclusiveMetric / 100, true);
                }

                var t = new Tuple(c);
                this.tuple = t;

                this.initialized = 1;
            }
            finally
            {
                this.semaphoreSlim.Release();
            }
        }
Example #4
0
        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));
        }
Example #5
0
        private async Task Initialize()
        {
            await this.semaphoreSlim.WaitAsync();

            try
            {
                if (this.initialized == 1)
                {
                    return;
                }

                var pid            = uint.Parse(this.model.Pid);
                var symbolProvider = new TracePdbSymbolReaderProvider(this.symbolServerArtifactRetriever);

                if (this.deserializer.ImageLoadMap.TryGetValue(pid, out var images))
                {
                    int total = 0;
                    int count = 0;
                    foreach (var image in images)
                    {
                        count++;
                        total += image.InstructionPointers.Count;
                    }

                    var pdbLookupImageList = new List <ImageInfo>(count);
                    var ftotal             = (float)total;
                    foreach (var image in images)
                    {
                        if ((image.InstructionPointers.Count / ftotal) * 100 >= 1.0)
                        {
                            pdbLookupImageList.Add(image);
                        }
                    }

                    foreach (var image in pdbLookupImageList)
                    {
                        if (this.deserializer.ImageToDebugInfoMap.TryGetValue(new ProcessImageId(pid, image.Begin), out var dbgId))
                        {
                            await symbolProvider.GetSymbolReader(image.FilePath, dbgId.Signature, dbgId.Age, dbgId.Filename);
                        }
                    }
                }

                var filterParams = new FilterParams
                {
                    StartTimeRelativeMSec   = this.model.Start,
                    EndTimeRelativeMSec     = this.model.End,
                    ExcludeRegExs           = this.model.ExcPats,
                    IncludeRegExs           = this.model.IncPats,
                    FoldRegExs              = this.model.FoldPats,
                    GroupRegExs             = this.model.GroupPats,
                    MinInclusiveTimePercent = this.model.FoldPct,
                    Name = "NoName"
                };

                var stackType = int.Parse(this.model.StackType);
                if (!this.deserializer.EventStacks.TryGetValue(stackType, out var stackEventType))
                {
                    throw new ArgumentException();
                }

                var instructionPointerDecoder = new InstructionPointerToSymbolicNameProvider(this.deserializer, symbolProvider);
                var stackSource = new GenericStackSource(
                    this.deserializer,
                    instructionPointerDecoder,
                    callback =>
                {
                    var sampleSource = this.deserializer;
                    var samples      = stackEventType.SampleIndices;
                    foreach (var s in samples)
                    {
                        var sample = sampleSource.Samples[s];
                        if (sample.Scenario == pid)
                        {
                            callback(sampleSource.Samples[s]);
                        }
                    }
                });

                var ss = new FilterStackSource(filterParams, stackSource, ScalingPolicyKind.TimeMetric);

                double startTimeRelativeMsec = double.TryParse(filterParams.StartTimeRelativeMSec, out startTimeRelativeMsec) ? Math.Max(startTimeRelativeMsec, 0.0) : 0.0;
                double endTimeRelativeMsec   = double.TryParse(filterParams.EndTimeRelativeMSec, out endTimeRelativeMsec) ? Math.Min(endTimeRelativeMsec, ss.SampleTimeRelativeMSecLimit) : ss.SampleTimeRelativeMSecLimit;

                this.callTree = new CallTree(ScalingPolicyKind.TimeMetric);
                this.callTree.TimeHistogramController = new TimeHistogramController(this.callTree, startTimeRelativeMsec, endTimeRelativeMsec);
                this.callTree.StackSource             = ss;

                if (float.TryParse(filterParams.MinInclusiveTimePercent, out float minIncusiveTimePercent) && minIncusiveTimePercent > 0)
                {
                    this.callTree.FoldNodesUnder(minIncusiveTimePercent * this.callTree.Root.InclusiveMetric / 100, true);
                }

                this.initialized = 1;
            }
            finally
            {
                this.semaphoreSlim.Release();
            }
        }