仅为提供程序中的某些特定 ETW 任务激活堆栈?

Activate Stacks only for some specific ETW Tasks in a provider?

Since Windows 7 it is possible to activate callstacks for usermode events。这工作正常,但有时不需要为提供者中的所有 tasks/Events 激活堆栈,并且只为某些特定任务激活堆栈会很好。这可能吗?

是的,这是可能的,因为 Windows 8.1 在您调用 EnableTraceEx2 时使用 _EVENT_FILTER_DESCRIPTOR when it is set to EVENT_FILTER_TYPE_STACKWALK 中的类型条目。

On Windows 8.1,Windows Server 2012 R2, and later, event payload, scope, and stack walk filters can be used by the EnableTraceEx2 function and the ENABLE_TRACE_PARAMETERS and EVENT_FILTER_DESCRIPTOR structures to filter on specific conditions in a logger session.

When stack walking is enabled for a provider, then the stack is captured for all the events generated by the provider. Most of the time, the user is only interested in stack from only certain number of events.

This feature allows enabling or disabling stack walking on a list of events. The provided filter includes a EVENT_FILTER_EVENT_ID structure that contains an array of event IDs and a Boolean value that indicates whether to enable or disable stack capturing for the specified events. Each event write call will go through this array quickly to find out whether the stack should be captured or not.

Windows Performance Recorder it is possible to achieve this in the WPR Profile with a second EventCollectorId entry which has an EventProviders 个启用了 stackwalking 的条目。

在此演示配置文件中,我为提供程序 Microsoft-Windows-DotNETRuntime 创建了一个 EventProvider (EventProvider_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.1\Windows Performance Toolkit\wpr.exe" -start  DotNetRuntime.wprp

,停止录制

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

使用 Windows Performance Analyzer, load the debug symbols 打开跟踪,您可以看到异常数据的堆栈,但看不到 Jit 或 GC 事件:

注意。当你运行 this under Windows 7 or Windows 8 (Build 9200),最后一个EventLogger for provider与指定的关键字和堆栈选项一起使用。在这里您应该创建 2 个 WPRP 配置文件并检测 Windows 版本和 运行 正确的配置文件。