다음을 통해 공유


.NET TraceProcessing에서 기호 사용

TraceProcessor는 여러 데이터 원본에서 기호 로드 및 스택 가져오기를 지원합니다. 다음 콘솔 애플리케이션은 CPU 샘플을 살펴보고 특정 함수가 실행 중인 예상 기간을 출력합니다(추적의 CPU 사용량 통계 샘플링에 따라).

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]}");
            }
        }
    }
}

이 프로그램을 실행하면 다음과 비슷한 출력이 생성됩니다.

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

(출력 세부 정보는 추적에 따라 달라집니다.)

기호 형식

내부적으로 TraceProcessor는 PDB에 저장된 일부 데이터의 캐시인 SymCache 형식을 사용합니다. 기호를 로드할 때 TraceProcessor는 이러한 SymCache 파일에 사용할 위치(SymCache 경로)를 지정해야 하며, 선택적으로 PDB에 액세스하기 위한 SymbolPath 지정을 지원합니다. SymbolPath가 제공되면 TraceProcessor는 필요에 따라 PDB 파일에서 SymCache 파일을 생성하며 이후에 동일한 데이터를 처리하면 SymCache 파일을 직접 사용하여 성능을 향상시킬 수 있습니다.

다음 단계

이 자습서에서는 추적을 처리할 때 기호를 로드하는 방법을 알아보았습니다.

다음 단계에서는 메모리의 모든 항목을 버퍼링하지 않고 스트리밍을 사용하여 추적 데이터에 액세스하는 방법을 알아보겠습니다.