Freigeben über


Verwenden von Symbolen in .NET TraceProcessing

TraceProcessor unterstützt das Laden von Symbolen sowie das Abrufen von Stapeln aus mehreren Datenquellen. Die folgende Konsolenanwendung untersucht CPU-Beispiele und gibt die geschätzte Dauer aus, die eine bestimmte Funktion ausgeführt wurde (basierend auf dem statistischen Sampling der CPU-Auslastung der Ablaufverfolgung).

using Microsoft.Windows.EventTracing;
using Microsoft.Windows.EventTracing.Cpu;
using Microsoft.Windows.EventTracing.Symbols;
using System;
using System.Collections.Generic;

class Program
{
    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.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]}");
            }
        }
    }
}

Die Ausführung dieses Programms erzeugt eine Ausgabe ähnlich der folgenden:

C:\GetCpuSampleDuration\bin\Debug\> GetCpuSampleDuration.exe C:\boot.etl user32.dll LoadImageInternal
0.0% (0 of 1165; 0 loaded)
<snip>
100.0% (1165 of 1165; 791 loaded)
wininit.exe: 15.99 ms
C:\Windows\Explorer.EXE: 5 ms
winlogon.exe: 20.15 ms
"C:\Users\AdminUAC\AppData\Local\Microsoft\OneDrive\OneDrive.exe" /background: 2.09 ms

(Die Ausgabedetails variieren je nach Ablaufverfolgung.)

Format von Symbolen

Intern verwendet TraceProcessor das SymCache-Format, bei dem es sich um einen Cache einiger der in einer PDB gespeicherten Daten handelt. Beim Laden von Symbolen erfordert TraceProcessor die Angabe eines Speicherorts für diese SymCache-Dateien (einen SymCache-Pfad) und unterstützt dabei optional das Angeben eines „SymbolPath>“ für den Zugriff auf PDBs. Wenn ein „SymbolPath“ bereitgestellt wird, erstellt TraceProcessor nach Bedarf SymCache-Dateien aus PDB-Dateien, und die nachfolgende Verarbeitung derselben Daten kann die SymCache-Dateien direkt verwenden, um die Leistung zu verbessern.

Nächste Schritte

In diesem Tutorial haben Sie gelernt, wie Sie bei der Verarbeitung von Ablaufverfolgungen Symbole laden.

Im nächsten Schritt erfahren Sie, wie Sie Streaming verwenden, um auf Ablaufverfolgungsdaten zuzugreifen, ohne alles im Arbeitsspeicher zu puffern.