【问题标题】:ETW event tracing in WPF 4+WPF 4+ 中的 ETW 事件跟踪
【发布时间】:2019-02-25 15:30:48
【问题描述】:

我正在尝试使用显示 how to do ETW event tracing in WPF 的 Microsoft 演示项目作为我想在我正在开发的应用程序中执行的某些特定分析的基础。

按原样编译,演示工作正常。但是,将目标框架从 .Net 3.5 更改为 .Net 4,它就会中断。显然,框架版本之间存在一些重大变化。

问题是发生了什么变化,(更重要的是)是否可以修复演示?

到目前为止我的调查

Debug.WriteLine 添加到FpsEventConsumer.EtwEventCallback 我看到在框架4 中要么没有事件到达,要么有两个事件到达,两者都具有Header.Guid68fdd900-4a3e-11d1-84f4-0000f80464e3;一个是Header.Class.TypeUCE_GLASS_START,另一个是UCE_GLYPHRUN_START。请注意,在框架 3.5 下进行测试时,我还观察到了这些事件以及许多其他事件。

通过在referencesource.microsoft.com 中进行挖掘,我发现MS.Utility.EventTrace's static field EventProvider 类型为MS.Utility.TraceProvider 控制发送到ETW 的内容。使用反射访问事件提供程序(因为它是非公开的)我观察到在 3.5 中它从启用所有功能开始(_enabledtrue_flags2147483647_level5);在 4 中,它从禁用所有内容开始(_enabled 为假,_keywords0_level0)。但是通过反思改变这些价值观似乎对这种情况没有多大帮助。充其量,在非常罕见的情况下,我会在上述UCE_ 之前发出一些事件。

通过如下方式在TraceConsumer.ProcessTrace 中放置WriteLine,我观察到 p/invoked 调用继续阻塞,因此问题不在于跟踪被中断。

             ErrorCode errorCode = UnsafeEventTrace.ProcessTrace(handleArray, handleArray.Length,
                                                                 (FILETIME)startTime, (FILETIME)endTime);
+            System.Diagnostics.Debug.WriteLine("ProcessTrace: " + errorCode);
             if (errorCode != ERROR.SUCCESS)
             {
                 errorCode.OutputErrorMessage("TraceConsumer.ProcessTrace");
             }

【问题讨论】:

  • 恐怕自从演示创建以来,一切都发生了很大变化。现在你应该使用这个包:nuget.org/packages/Microsoft.Diagnostics.Tracing.TraceEvent。另外,如果我没记错的话,目前您需要打开 WPF ETW 事件,然后才能收集它们。
  • @MaciekŚ.,谢谢。我会研究一下,虽然我最初的实验不是很有希望。

标签: wpf etw


【解决方案1】:

事实证明,答案一直存在于我查看的一个参考源文件中:

    /// ...
    /// TreatAsSafe:  it generates the GUID that is passed into the TraceProvider
    /// WPF versions prior to 4.0 used provider guid: {a42c77db-874f-422e-9b44-6d89fe2bd3e5}
    ///</SecurityNote>
    [SecurityCritical, SecurityTreatAsSafe]
    static EventTrace()
    {
        Guid providerGuid = new Guid("E13B77A8-14B6-11DE-8069-001B212B5009");
        ...

Sample.RunTrace 的以下简单补丁会导致事件开始流动(尽管它们不再包括演示用于 FPS 的特定事件)。

-            m_traceSession = TraceController.WpfController;
+            m_traceSession = typeof(System.Windows.Rect).Assembly.GetName().Version.Major == 3
+                ? TraceController.WpfController
+                : TraceController.GetController(new Guid("E13B77A8-14B6-11DE-8069-001B212B5009"), "WPF");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-29
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 2022-08-09
    • 2020-05-23
    • 2011-09-18
    • 2019-06-03
    相关资源
    最近更新 更多