Трассировка событий ETW в WPF 4+ - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь использовать демонстрационный проект Microsoft, в котором показано, как выполнять трассировку событий ETW в WPF , в качестве основы для определенного профилирования, которое я хочу выполнить в разрабатываемом приложении.

Скомпилировано как есть, демо работает отлично.Однако измените целевой фреймворк с .Net 3.5 на .Net 4, и он сломается.Очевидно, что между версиями фреймворка есть некоторые существенные изменения.

Вопрос в том, что изменилось, и (что более важно) возможно ли исправить демо?

Мое расследование до сих пор

Добавление Debug.WriteLine к FpsEventConsumer.EtwEventCallback Я вижу, что в рамках 4 либо никакие события не приходят, либо приходят два события, оба с Header.Guid из 68fdd900-4a3e-11d1-84f4-0000f80464e3;один с Header.Class.Type из UCE_GLASS_START, а другой с UCE_GLYPHRUN_START.Обратите внимание, что я также наблюдаю эти события, среди многих других, при тестировании в фреймворке 3.5.

В процессе поиска на сайте sourcesource.microsoft.com я обнаружил, что статическое поле MS.Utility.EventTrace EventProvider типа MS.Utility.TraceProvider контролирует то, что отправляется в ETW.Используя рефлексию для доступа к провайдеру событий (поскольку он не является общедоступным), я наблюдаю, что в 3.5 он начинается со всего, что включено (_enabled это true, _flags это 2147483647, _level это 5);и в 4 он начинается со всех отключенных (_enabled - ложь, _keywords - 0 и _level - 0).Но изменение этих ценностей с отражением, кажется, не очень помогает ситуации.В лучшем случае в очень редком случае я получаю несколько событий, переданных выше UCE_.

Помещая WriteLine в TraceConsumer.ProcessTrace следующим образом, я наблюдаю, что вызов p / вызвалпродолжает блокировать, поэтому проблема не в том, что трассировка прерывается.

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

1 Ответ

0 голосов
/ 21 сентября 2018

Оказывается, что ответ был там все время в одном из файлов источников ссылок, на которые я смотрел:

    /// ...
    /// 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");
...