使用Process Explorer、System Informer(Process Hacker)和Windbg工具排查软件高CPU占用问题

发布于:2025-06-04 ⋅ 阅读:(19) ⋅ 点赞:(0)

目录

1、问题现象

2、使用Process Explorer和System Informer(该工具原先叫Process Hacker)查看占用CPU高的线程

3、使用System Informer工具时发现了一个关键细节

4、将Windbg附加到软件进程上,根据System Informer中显示的线程id到Windbg中查看更准确的线程函数调用堆栈

5、通过比对,发现是视频加水印功能导致CPU占用飙升

6、解决办法

7、最后


C++软件异常排查从入门到精通系列教程(核心精品专栏,订阅量已达8000多个,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战专栏(重点专栏,专栏文章已更新500多篇,订阅量已达6000多个,欢迎订阅,持续更新中...)https://blog.csdn.net/chenlycly/article/details/140824370C++ 软件开发从入门到实战(重点专栏,专栏文章已更新300多篇,欢迎订阅,持续更新中...)https://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_2276111.html       在排查C++软件问题的过程中,可能会使用到一些软件工具去辅助分析,比如SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等。今天通过一个项目中遇到的问题实例,讲解如何使用Process Explorer、System Informer(Process Hacker)和Windbg工具排查软件高CPU占用问题。

关于如何使用SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等这些常用工具,以及相关实战分析案例,可以查看我的文章:

【C++软件实战问题排查经验分享系列 ③】 Process Explorer | Process Monitor | API Monitor | Windbg | IDA 等常用工具的使用总结https://blog.csdn.net/chenlycly/article/details/147574902

1、问题现象

       测试人员发现,在SIP协议下加入会议后,会议中开启水印,将视频窗口最小化后,整个Windows系统会出现明显的卡顿。于是打开系统的任务管理器,发现此时系统总的CPU基本达到100%,所以系统出现了明显的卡顿,已经明显影响电脑的使用!而我们的软件进程占用的CPU居然高达60%-70%左右,异常的高!测试人员进一步发现,当将视频窗口非最小化正常显示时,软件的CPU只会占到30%,如果将视频窗口最小化,则软件占用的CPU会一下飙升到70%左右,这明显是不正常的。

2、使用Process Explorer和System Informer(该工具原先叫Process Hacker)查看占用CPU高的线程

       于是使用Process Explorer工具查看软件进程中到底哪些进程占用的CPU比较高。问题复现后,我们看到多达20多个线程的CPU占用都达到3%或3%以上,这是明显不正常的。于是想双击这些占用CPU高的线程,查看线程的函数调用堆栈,看看线程中都调用了哪些模块中的哪些函数(主要看占用CPU高的线程是否调用了我们业务模块的接口以及调用了哪些接口),尝试去分析占用CPU高的原因。

       打开Process Explorer,在进程列表中找到我们的软件进程,双击之,弹出进程的属性窗口,在该属性窗口中点击Threads标签页,即可看到当前进程的所有线程信息。然后在线程列表中找到占用CPU较高的线程,但双击这些线程后查看到的函数调用堆栈不准。于是决定换工具,使用Process Hacker工具(该工具现在叫System Informer),这个工具查看线程的函数调用堆栈比较准确,这点比Process Explorer好用。

3、使用System Informer工具时发现了一个关键细节

       在使用System Informer过程中,观察到一个很好用的细节。目前的问题现象是,入会后,不将视频窗口最小化,即正常显示,观察Windows任务管理器,软件的CPU只占到30%左右,但将视频窗口最小化后,软件占用的CPU会飙到70%左右。在任务管理器中可以看到,整个系统中的CPU使用总和到达100%,导致整个Windows系统出现明显的卡顿。

       在System Informer工具中查看软件进程中的线程,和使用Process Explorer工具查看方法是一样的。打开System Informer,在进程列表中找到我们的软件进程,双击之,弹出进程的属性窗口,在该属性窗口中点击Threads标签页,即可看到当前进程的所有线程信息。然后在线程列表中找到占用CPU较高的线程:

        首先要查看占用CPU最高的线程,双击之查看该线程的函数调用堆栈,通过堆栈中的函数调用确定当前线程属于哪个模块。在本例中,占用CPU最高的线程占用大概10%左右,双击之查看该线程中的函数调用堆栈,看到了ksproxy.ax模块,找到该文件的路径,查看文件的属性属性得知,该文件是金山毒霸杀毒软件的模块,在当前机器上安装了金山毒霸软件。

有人可能会问,金山毒霸杀毒软件的ksproxy.ax模块怎么会加载到我们软件的进程空间中?这个模块应该是金山毒霸的注入模块,注入到我们的软件进程中的。安全杀毒软件正是通过远程注入的方式,实时监控系统中软件(进程)的行为,以起到实时安全监测的作用。

       在视频窗口显示时以及将视频窗口最小化后,该ksproxy.ax注入模块的线程都存在,且占用比没有明显的变化,所以该线程不是导致将视频窗口最小化后CPU飙升的原因。当前软件进程占用CPU高,应该是其他线程导致的。


        在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)

专栏1:该精品技术专栏的订阅量已达到10000多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,已经更新到200篇以上!欢迎订阅!)

C++软件调试与异常排查从入门到精通系列文章汇总https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!

专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2:(本专栏涵盖了C++多方面的内容,是当前重点打造的专栏,订阅量已达8000多个,专栏文章已经更新到500多篇,持续更新中...)

C/C++实战进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点(模版泛型编程、STL容器及算法函数的使用等)、数据结构与算法、C++11及以上新特性(不仅看开源代码会用到,日常编码中也会用到部分新特性,面试时也会涉及到)、常用C++开源库的介绍与使用、代码分享(调用系统API、使用开源库)、常用编程技术(动态库、多线程、多进程、数据库及网络编程等)、软件UI编程(Win32/duilib/QT/MFC)、C++软件调试技术(排查软件异常的手段与方法、分析C++软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等)、设计模式、网络基础知识与网络问题分析进阶内容等。

专栏3:  

C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/131405795

常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!

专栏4:   

VC++常用功能开发汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/124272585

将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。

专栏5: 

C++ 软件开发从入门到精通(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12695902.html

根据多年C++软件开发实践,详细地总结了C/C++软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。


       于是用System Informer工具实时观察视频窗口从正常显示(CPU占用正常)到最小化(最小化占用CPU高)这个过程中线程占用CPU比例的变化,发现将视频窗口最小化后明显多了几个CPU占比比较高的线程(不确定这几个线程在没最小化视频窗口时就有,还是最小化视频窗口后新增的线程,当时没关注这一点),大概10个左右,每个线程平均占用3%的CPU

这个细节是个很关键的线索!双击这几个线程,发现这几个线程的函数调用堆栈中的函数都是系统函数,所以可以确实这几个线程是系统线程。如果占用CPU高线程的函数调用堆栈中有调用业务模块的接口,我们还可以进行针对性排查,而当前这几个线程都是系统线程,可能是我们业务模块调用系统库的接口后,系统库中创建的线程,但我们从这些线程的函数调用堆栈中看不出与哪些业务模块有关,所以排查就陷入了僵局。

       至于为什么会出现系统线程呢?程序运行会依赖很多系统模块,这些系统模块中有线程。再就是我们调用到某些API接口或者使用到某些系统相关库的接口,这些库内部开启了线程。

4、将Windbg附加到软件进程上,根据System Informer中显示的线程id到Windbg中查看更准确的线程函数调用堆栈

       上面讲到System Informer中查看那几个CPU占用高的线程函数调用堆栈,结果堆栈中调用的都是系统接口,所以线程都是系统创建的线程。是不是System Informer中显示的线程函数调用堆栈不准确呢?将Windbg附加到软件进程中去查看线程的调用堆栈肯定是准确的。

       将Windbg附加到进程上,输入~*kn命令将当前进程的所有线程的函数调用堆栈都打印出来,然后根据System Informer中显示的线程id,到Windbg中显示的线程列表中去找对应的线程,就可以查看线程的函数调用堆栈了。System Informer中显示的线程id是10进制的,要转成16进制后,到Windbg中显示的线程列表中查找就可以找到对应的线程了。

5、通过比对,发现是视频加水印功能导致CPU占用飙升

       最近音视频编解码模块那边新增了在视频画面中添加水印的功能,是不是和这个水印功能有关?于是让测试人员,对比一下关闭水印时最小化视频窗口后的CPU占用比例。通过对比测试发现,关闭水印后最小化视频窗口,软件的CPU会达到40%左右;打开水印后,最小化视频窗口,软件的CPU占用会达到70%。CPU占用差额正好是30%左右,这和System Informer工具中显示的增加的几个高CPU占用线程的CPU占用总和是一致的。所以,基本可以确定是视频中加水印功能导致的。

我让测试人员看一下上一个没加水印的老版本,入会后将视频窗口最小化,没有出现CPU飙升的问题,所以进一步确认CPU占用飙升与水印功能有关。

6、解决办法

       音视频编解码模块的开发同事,怀疑是当前sip协议下同时使用D3D9和D3D11库导致的。sip协议入会和rtc协议入会,用的音视频编解码库是不同的。SIP协议下用的是xxxxxsdk.dll库,rtc协议下用的是xxxxxplayer.dll库。当前出问题的场景就是sip协议入会的场景,用的就是xxxxxsdk.dll库,在该库中使用了D3D的两个版本,绘制视频画面使用的是D3D9(当时为了兼容XP系统,使用了D3D9),绘制水印使用的是D3D11,可能是两个版本同时使用导致的,后面需要将视频画面绘制与水印绘制都统一使用同一个版本的D3D。

7、最后

       有些问题很难找到排查的线索或入口,但通过观察一些细节以及版本的对比,可能会从中发现一些端倪,从而找到一些线索。
 


网站公告

今日签到

点亮在社区的每一天
去签到