继上一篇简单给出wmi CPU占用高的教程后,本文通过windows系统的一个BUG深入进行分析Wmi,适用上一篇方案无法解决的小伙伴。借助工具进一步分析wmiprvse.exe的CPU占用高的原因,以防范其他Api调用也存在类似的风险。本次主要借助ProcExp、ProcMonitor、ApiMonitor和WPT。

bug描述:设备管理器禁用CD-ROM后CPU占用资源高。

一、ProcExp分析调用栈

左侧是禁用CD-rom后的CPU占用高的函数调用栈。右侧是正常启用CD-rom后的情况。llUnregisterServer 是一个在Windows操作系统中用于从系统注册表中移除DLL文件相关信息的函数。当使用 regsvr32 命令注销DLL文件时,命令会调用 DLL 文件中的 DllUnregisterServer 函数,这个函数负责从系统注册表中移除 DLL 文件的相关信息。通过对比能发现二者有差异的内容,但是无法分析出哪个API耗时最多。
[CPU占用高时的调用栈]
CPU占用低时的调用栈

二、ProcMonitor分析函数调用频率

1. 函数调用频率分析

从ProcMonitor导出csv文件分析一定周期各个函数的调用占比,发现禁用CD-ROM的异常情况下有ReadFile的较多调用。

在这里插入图片描述
图:启用CD-ROM驱动函数调用频率

在这里插入图片描述
图:禁用CD-ROM后的函数调用频率

2 结合ResMon工具分析Wmiprvse.exe对文件的访问禁用CD-ROM驱动后,很快观察到wmiprvse.exe访问ntbtlog.txt。分析ntbtlog文件的内容,貌似是在遍历系统安装的驱动列表。

在这里插入图片描述
图1 CPU占用高时的磁盘访问

启用CD-ROM后上图的文件访问,逐渐消去,最后为空。也就是正常情况下是不访问这个文件的。

在这里插入图片描述
图2 CPU占用低时的磁盘访问

添加图片注释,不超过 140 字(可选)
图 3 ntbtlog.txt 记录的是系统的引导日志。

三、使用WPT(Windows Performance Toolkit)工具进一步分析调用栈

1. 禁用CDROM设备后的分析:

GetTickCount调用很多次,是cpu占用的大头。

在这里插入图片描述

收缩范围后,仔细分析约1s内的情况,GetTickCount每次调用占0.01%,共2226次,2226×0.01%=22.26%。也就是导致CPU占用高的占比大头确实是GetTickCount。

2. 启动CDROM后的分析:

对比异常情况下的函数调用栈,cimwin32!CWin32CDROM::Enumerate函数下的cimwin32!CWin32CDROM::LoadPropertyValue是导致CPU占用差异的起始点。即禁用驱动后LoadPropertyValue走了不同的分支。

添加图片注释,不超过 140 字(可选)

关于CWin32CDROM的技术文档:Win32_CDROMDrive 类 - Win32 apps | Microsoft Learn

四、Api monitor观察函数调用参数值

此工具可以观察到函数调用参数值,但是仅限比较常见的系统API,类似cimwin32!CWin32CDROM::LoadPropertyValue这种比较偏的就无法抓到了。但也可以佐证,GetTickCount的次数和耗时。

在这里插入图片描述
图 4 Api Monitor截图

五、结论

目前可定位到具体是调用底层哪个Api耗时高,考虑到有专门的类名叫KeepBusy,无代码的情况也只能得出windows对此处的设计如此。如下是WPT抓取数据。

Logo

一站式 AI 云服务平台

更多推荐