Utiliser des symboles dans .NET TraceProcessing
TraceProcessor prend en charge le chargement de symboles et l’obtention de piles à partir de plusieurs sources de données. L’application console suivante examine les exemples d’UC et génère la durée estimée de l’exécution d’une fonction spécifique (en fonction de l’échantillonnage statistique de l’utilisation du processeur de la trace).
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]}");
}
}
}
}
L’exécution de ce programme produit une sortie similaire à ceci :
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
(Les détails de la sortie vont varier en fonction de la trace).
Format des symboles
En interne, TraceProcessor utilise le format SymCache, qui est un cache de certaines des données stockées dans un fichier PDB. Lors du chargement de symboles, TraceProcessor nécessite la spécification d’un emplacement à utiliser pour ces fichiers SymCache (un chemin SymCache) et peut prendre en charge la spécification d’un SymbolPath pour accéder aux fichiers PDB. Quand un SymbolPath est fourni, TraceProcessor va créer les fichiers SymCache en nécessaires à partir des fichiers PDB, et le traitement ultérieur des mêmes données peut alors utiliser les fichiers SymCache directement pour de meilleures performances.
Étapes suivantes
Dans ce tutoriel, vous avez découvert comment charger des symboles lors du traitement des traces.
L’étape suivante consiste à découvrir comment utiliser le streaming pour accéder aux données de trace sans tout mettre en mémoire tampon dans la mémoire.
Windows developer