如何低成本的获取到应用卡顿情况
引入 在做 WPA 分析的时候,会通过 UI Delay 来判断应用卡顿的时间点。那我们是否可以单独把这一部分数据拎出来,来评估应用卡顿情况? UI Delays 视图是依据什么来做的 WPA 大部分数据都是来源于众多 ETW Provider,也就是说,我们想获取到卡顿数据,就是找到特定的 provider 的特定事
引入#
在做 WPA 分析的时候,会通过 UI Delay 来判断应用卡顿的时间点。那我们是否可以单独把这一部分数据拎出来,来评估应用卡顿情况?
UI Delays 视图是依据什么来做的#
WPA 大部分数据都是来源于众多 ETW Provider,也就是说,我们想获取到卡顿数据,就是找到特定的 provider 的特定事件。
通过对比 UI Delys 视图和 Generic Events 的视图。在 Generic Events 的视图中按 Process 排序,找到有出现卡顿的进程,分析其所有的事件。

于是可以看到,TaskName 为 MessageCheckDelay 和 InputProcessDelay两个 keyword。
结论:
UI Delays 视图根据 Microsoft-Windows-Win32k 的 MessageCheckDelay 和 InputProcessDelay 两个事件来实现 UI 卡顿的可视化。
看看 Provider 里还有什么#
由于我们已经找到了 Provider,并且也找到了两个事件。那是否还有其他事件呢?接下来到 Microsoft-Windows-Win32k 中去看看
我们可以在下面这个链接中看到 Microsoft-Windows-Win32k 的具体定义。
找到 MessageCheckDelay
<Event>
<Id>38</Id>
<Version>0</Version>
<Channel>Microsoft-Windows-Win32k/Tracing</Channel>
<Level>Information</Level>
<Task>MessageCheckDelay</Task>
<Keyword>UIUnresponsiveness</Keyword>
<Template><![CDATA[
<template xmlns="http://schemas.microsoft.com/win/2004/08/events">
<data name="Flags" inType="win:UInt32" outType="win:HexInt32"/>
<data name="DelayTimeMs" inType="win:UInt32" outType="xs:unsignedInt"/>
<data name="TimeSinceInputRemoveMs" inType="win:UInt32" outType="xs:unsignedInt"/>
<data name="TimeSinceOldestInputMs" inType="win:UInt32" outType="xs:unsignedInt"/>
<data name="ClassName" inType="win:UnicodeString" outType="xs:string"/>
<data name="TopLevelClassName" inType="win:UnicodeString" outType="xs:string"/>
<data name="ImagePath" inType="win:UnicodeString" outType="xs:string"/>
<data name="MessageId" inType="win:UInt32" outType="xs:unsignedInt"/>
<data name="WParam" inType="win:UInt64" outType="xs:unsignedLong"/>
</template>
]]></Template>
</Event>还有 InputProcessDelay
<Event>
<Id>37</Id>
<Version>0</Version>
<Channel>Microsoft-Windows-Win32k/Tracing</Channel>
<Level>Information</Level>
<Task>InputProcessDelay</Task>
<Keyword>UIUnresponsiveness</Keyword>
<Template><![CDATA[
<template xmlns="http://schemas.microsoft.com/win/2004/08/events">
<data name="Flags" inType="win:UInt32" outType="win:HexInt32"/>
<data name="TimeSinceInputRemoveMs" inType="win:UInt32" outType="xs:unsignedInt"/>
<data name="TimeSinceOldestInputMs" inType="win:UInt32" outType="xs:unsignedInt"/>
<data name="ClassName" inType="win:UnicodeString" outType="xs:string"/>
<data name="TopLevelClassName" inType="win:UnicodeString" outType="xs:string"/>
<data name="ImagePath" inType="win:UnicodeString" outType="xs:string"/>
<data name="MessageId" inType="win:UInt32" outType="xs:unsignedInt"/>
<data name="WParam" inType="win:UInt64" outType="xs:unsignedLong"/>
</template>
]]></Template>
</Event>可以看到,他们的关键词(keyword)都是 UIUnresponsiveness,于是我们可以看看这个关键词下的所有事件。汇总如下:
怎么做#
根据可以获取到的事件。我们可以订阅 ETW 事件,当事件发生时,则证明应用发生卡顿。
怎么实时订阅可以看:如何通过 C++ 实时监听 ETW 事件
还没有评论。下面留下第一条吧。