static void Main(string[] args) { if (args.Length != 3) { Console.Error.WriteLine("Usage: GetCpuSampleDuration.exe <trace.etl> <imageName> <functionName>"); return; } string tracePath = args[0]; string imageName = args[1]; string functionName = args[2]; Dictionary <string, Duration> matchDurationByCommandLine = new Dictionary <string, Duration>(); using (ITraceProcessor trace = TraceProcessor.Create(tracePath)) { IPendingResult <ISymbolDataSource> pendingSymbolData = trace.UseSymbols(); IPendingResult <ICpuSampleDataSource> pendingCpuSamplingData = trace.UseCpuSamplingData(); trace.Process(); ISymbolDataSource symbolData = pendingSymbolData.Result; ICpuSampleDataSource cpuSamplingData = pendingCpuSamplingData.Result; symbolData.LoadSymbolsForConsoleAsync(SymCachePath.Automatic, SymbolPath.Automatic).GetAwaiter().GetResult(); Console.WriteLine(); IThreadStackPattern pattern = AnalyzerThreadStackPattern.Parse($"{imageName}!{functionName}"); foreach (ICpuSample sample in cpuSamplingData.Samples) { if (sample.IsExecutingDeferredProcedureCall == true || sample.IsExecutingInterruptServicingRoutine == true) { continue; } if (sample.Stack != null && sample.Stack.Matches(pattern)) { string commandLine = sample.Process.CommandLine; if (!matchDurationByCommandLine.ContainsKey(commandLine)) { matchDurationByCommandLine.Add(commandLine, Duration.Zero); } matchDurationByCommandLine[commandLine] += sample.Weight; } } } foreach (string commandLine in matchDurationByCommandLine.Keys) { Console.WriteLine($"{commandLine}: {matchDurationByCommandLine[commandLine]}"); } }
private void GatherCpuSampleData(ICpuSampleDataSource cpuSampleDataSource) { foreach (ICpuSample sample in cpuSampleDataSource.Samples) { Process process = new Process(sample.Process.Id, sample.Process.ImageName); if (!SampledProfileCounts.ContainsKey(process)) { SampledProfileCounts.Add(process, 1); } else { ++SampledProfileCounts[process]; } } }
static void RunWithOptions(Options opts) { using (ITraceProcessor trace = TraceProcessor.Create(opts.etlFileName)) { IPendingResult <ICpuSampleDataSource> pendingCpuSampleData = trace.UseCpuSamplingData(); IPendingResult <ISymbolDataSource> pendingSymbolData = trace.UseSymbols(); trace.Process(); ISymbolDataSource symbolData = pendingSymbolData.Result; ICpuSampleDataSource cpuSampleData = pendingCpuSampleData.Result; var symbolProgress = new Progress <SymbolLoadingProgress>(progress => { Console.Write("\r{0:P} {1} of {2} symbols processed ({3} loaded)", (double)progress.ImagesProcessed / progress.ImagesTotal, progress.ImagesProcessed, progress.ImagesTotal, progress.ImagesLoaded); }); symbolData.LoadSymbolsAsync( SymCachePath.Automatic, SymbolPath.Automatic, symbolProgress) .GetAwaiter().GetResult(); Console.WriteLine(); var profileWriter = new ProfileWriter(opts.etlFileName, opts.includeInlinedFunctions, opts.includeProcessAndThreadIds, opts.stripSourceFileNamePrefix); var timeStart = opts.timeStart ?? 0; var timeEnd = opts.timeEnd ?? decimal.MaxValue; var exportAllProcesses = opts.processFilter == "*"; var processFilterSet = new HashSet <string>( opts.processFilter.Trim().Split(",", StringSplitOptions.RemoveEmptyEntries)); for (int i = 0; i < cpuSampleData.Samples.Count; i++) { if (i % 100 == 0) { Console.Write("\r{0:P} {1} of {2} samples processed", (double)i / cpuSampleData.Samples.Count, i, cpuSampleData.Samples.Count); } var cpuSample = cpuSampleData.Samples[i]; if ((cpuSample.IsExecutingDeferredProcedureCall ?? false) || (cpuSample.IsExecutingInterruptServicingRoutine ?? false)) { continue; } if (!exportAllProcesses) { var processImage = cpuSample.Process.Images .FirstOrDefault(image => image.FileName == cpuSample.Process.ImageName); string imagePath = processImage?.Path ?? cpuSample.Process.ImageName; if (!processFilterSet.Any(filter => imagePath.Contains(filter.Replace("/", "\\")))) { continue; } } var timestamp = cpuSample.Timestamp.RelativeTimestamp.TotalSeconds; if (timestamp < timeStart || timestamp > timeEnd) { continue; } profileWriter.AddSample(cpuSample); } Console.WriteLine(); long outputSize = profileWriter.Write(opts.outputFileName); Console.WriteLine("Wrote {0:N0} bytes to {1}", outputSize, opts.outputFileName); } }