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

mag*_*981 4 etw stack-trace windows-8.1 wpr

从Windows 7开始,可以为用户模式事件激活调用栈。这可以正常工作,但有时不需要为提供程序中的所有任务/事件激活堆栈,最好仅为某些特定任务激活堆栈。这可能吗?

mag*_*981 6

是的,这是可能的,因为Windows 8.1在调用EnableTraceEx2 时将类型条目设置为EVENT_FILTER_TYPE_STACKWALK时具有_EVENT_FILTER_DESCRIPTOR中的类型条目。

在Windows 8.1,Windows Server 2012 R2和更高版本上,EnableTraceEx2函数以及ENABLE_TRACE_PARAMETERS和EVENT_FILTER_DESCRIPTOR结构可以使用事件有效负载,范围和堆栈遍历筛选器,以在记录器会话中的特定条件下进行筛选。

为提供程序启用堆栈漫游时,将为该提供程序生成的所有事件捕获堆栈。在大多数情况下,用户仅对来自特定数量事件的堆栈感兴趣。

此功能允许在事件列表上启用或禁用堆栈遍历。提供的过滤器包括EVENT_FILTER_EVENT_ID结构,该结构包含事件ID数组和布尔值,该布尔值指示是为指定事件启用还是禁用堆栈捕获。每个事件写调用都将快速通过此数组,以查找是否应捕获堆栈。

使用Windows Performance Recorder,可以在WPR配置文件中使用第二个EventCollectorId条目来实现此目的,该条目具有启用了堆栈漫游的EventProviders条目。

在这个演示配置文件中,我EventProvider_DotNETRuntime为Microsoft-Windows-DotNETRuntime不带堆栈的提供程序创建了一个EventProvider(),以捕获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>
Run Code Online (Sandbox Code Playgroud)

现在运行Windows Performance Recorder捕获数据时:

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

,停止录音

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

使用Windows Performance Analyzer打开跟踪,加载调试符号,您可以看到Exception数据的堆栈,而不是Jit或GC事件的堆栈:

WPA_dotNetRuntime_Events_some_withStacks

注意。在Windows 7或Windows 8(内部版本9200)下运行此命令时,提供程序的最后一个EventLogger与指定的关键字和堆栈选项一起使用。在这里,您应该创建2个WPRP配置文件并检测Windows版本并运行正确的配置文件。