Активировать стеки только для некоторых конкретных задач ETW в провайдере?

С Windows 7 можно активировать callstacks для событий usermode. Это прекрасно работает, но иногда активирование стеков для всех задач/событий в провайдере не требуется, и было бы неплохо активировать стеки для некоторых конкретных задач. Возможно ли это?

Ответ 1

Да, это возможно, так как Windows 8.1 с типом в _ EVENT_FILTER_DESCRIPTOR, когда он установлен на EVENT_FILTER_TYPE_STACKWALK, когда вы вызываете EnableTraceEx2.

В Windows 8.1, Windows Server 2012 R2 и более поздних версиях, объем и фильтры стека могут использоваться EnableTraceEx2 функции и ENABLE_TRACE_PARAMETERS и EVENT_FILTER_DESCRIPTOR структуры для фильтрации по конкретным условиям в сеансе регистрации.

Если для провайдера включена ходьба по стеклу, тогда стек захвачен для всех событий, генерируемых провайдером. Большинство из времени пользователь интересуется только стеком только от определенного количества события.

Эта функция позволяет включать или отключать стекирование в списке Мероприятия. Предоставленный фильтр включает в себя структуру EVENT_FILTER_EVENT_ID, который содержит массив идентификаторов событий и логическое значение, которое указывает включить или отключить захват стека для указанных событий. Каждый вызов записи события будет проходить через этот массив быстро, чтобы узнать следует ли захватить стек или нет.

С Windows Performance Recorder этого можно достичь в Профиль WPR со второй записью EventCollectorId, которая имеет EventProviders, в котором включено включение стека.

В этом демо-профиле я создал один EventProvider (EventProvider_DotNETRuntime) для провайдера Microsoft-Windows-DotNETRuntime без стеков для сбора данных JIT и GC и другого EventProvider (EventProvider_DotNETRuntime_Stack) для провайдера Microsoft-Windows-DotNETRuntime со стеками для захвата стеков для Исключения и события загрузчика.

<?xml version="1.0" encoding="utf-8"?>
<WindowsPerformanceRecorder Version="1.0" Author="MagicAndre1981" Copyright="MagicAndre1981">
  <Profiles>
    <SystemCollector Id="SystemCollector" Name="NT Kernel Logger">
      <BufferSize Value="1024" />
      <Buffers Value="384" />
    </SystemCollector>
    <EventCollector Id="EventCollector_DotNETRuntime_Session" Name="DotNETRuntime_Session">
      <BufferSize Value="1024" />
      <Buffers Value="128" />
    </EventCollector>
    <EventCollector Id="EventCollector_DotNETRuntime_with_Stack" Name="DotNETRuntime_Session_with_Stack">
      <BufferSize Value="1024" />
      <Buffers Value="128" />
    </EventCollector>
    <SystemProvider Id="SystemProvider">
      <Keywords>
        <Keyword Value="ProcessThread" />       <!--PROC_THREAD-->
        <Keyword Value="Loader" />              <!--LOADER-->
        <Keyword Value="SampledProfile" />      <!--PROFILE-->
        <Keyword Value="Interrupt"/>            <!--INTERRUPT-->
        <Keyword Value="DPC"/>                  <!--DPC-->
        <Keyword Value="ReadyThread" />         <!--Dispatcher-->
        <Keyword Value="CSwitch" />             <!--CSwitch-->
      </Keywords>
      <Stacks>
        <Stack Value="SampledProfile" />        <!--Profile-->
        <Stack Value="CSwitch" />               <!--CSwitch-->
        <Stack Value="ReadyThread" />           <!--ReadyThread-->
        <Stack Value="ImageLoad" />             <!--ImageLoad-->
        <Stack Value="ImageUnload" />           <!--ImageUnload-->
      </Stacks>
    </SystemProvider>
    <EventProvider Id="EventProvider_DotNETRuntime" Name="Microsoft-Windows-DotNETRuntime" Level="5" Stack="false">
      <Keywords>
        <Keyword Value="0x111" />                       <!--GCKeyword, JitKeyword, JitRundownKeyword, EndRundownKeyword -->
      </Keywords>
    </EventProvider>
    <EventProvider Id="EventProvider_DotNETRuntime_Stack" Name="Microsoft-Windows-DotNETRuntime" Level="5" Stack="true">
      <Keywords>
        <Keyword Value="0x8008" />                      <!--LoaderKeyword, LoaderRundownKeyword, ExceptionKeyword -->
      </Keywords>
    </EventProvider>
    <EventProvider Id="EventProvider_DotNETRuntimePrivate" Name="763fd754-7086-4dfe-95eb-c01a46faf4ca" Level="5" Stack="false">
      <Keywords>
        <Keyword Value="0xE" />
      </Keywords>
    </EventProvider>
    <EventProvider Id="EventProvider_DotNETRuntimeRundown_CaptureState" Name="Microsoft-Windows-DotNETRuntimeRundown" Level="5" CaptureStateOnly="true" Stack="false">
      <CaptureStateOnSave>
        <Keyword Value="0x118" />
      </CaptureStateOnSave>
    </EventProvider>
    <Profile Id="DotNetRuntimeProfile.Verbose.File" Name="DotNetRuntimeProfile" Description="DotNetRuntime Profile" LoggingMode="File" DetailLevel="Verbose">
      <Collectors>
        <SystemCollectorId Value="SystemCollector">
          <SystemProviderId Value="SystemProvider" />
        </SystemCollectorId>
        <EventCollectorId Value="EventCollector_DotNETRuntime_Session">
          <EventProviders>
            <EventProviderId Value="EventProvider_DotNETRuntime" />
            <EventProviderId Value="EventProvider_DotNETRuntimePrivate" />
            <EventProviderId Value="EventProvider_DotNETRuntimeRundown_CaptureState" />
          </EventProviders>
        </EventCollectorId>
        <EventCollectorId Value="EventCollector_DotNETRuntime_with_Stack">
          <EventProviders>
            <EventProviderId Value="EventProvider_DotNETRuntime_Stack" />
          </EventProviders>
        </EventCollectorId>
      </Collectors>
    </Profile>
    <Profile Id="DotNetRuntimeProfile.Verbose.Memory" Name="DotNetRuntimeProfile" Description="DotNetRuntime Profile" Base="DotNetRuntimeProfile.Verbose.File" LoggingMode="Memory" DetailLevel="Verbose"/>
  </Profiles>
  <TraceMergeProperties>
    <TraceMergeProperty Id="BaseVerboseTraceMergeProperties" Name="BaseTraceMergeProperties" Base="">
      <CustomEvents>
          <CustomEvent Value="ImageId"/>
          <CustomEvent Value="BuildInfo"/>
          <CustomEvent Value="VolumeMapping"/>
          <CustomEvent Value="EventMetadata"/>
          <CustomEvent Value="PerfTrackMetadata"/>
          <CustomEvent Value="NetworkInterface"/>
        </CustomEvents>
      <FileCompression Value="true" />
     </TraceMergeProperty>
  </TraceMergeProperties>
</WindowsPerformanceRecorder>

При запуске Windows Performance Recorder для записи данных:

"C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\wpr.exe" -start  DotNetRuntime.wprp

остановите запись

"C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\wpr.exe" -stop Result.etl

откройте трассировку с помощью Анализатор производительности Windows, загрузить отладочную символов вы можете видеть стеки для данных исключения, но не для событий Jit или GC:

WPA_dotNetRuntime_Events_some_withStacks

Внимание.. Когда вы запускаете это под Windows 7 или Windows 8 (сборка 9200), последний EventLogger для провайдера используется с указанными ключевыми словами и опциями стека. Здесь вы должны создать 2 профиля WPRP и определить версию Windows и запустить правильный профиль.