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

article/2025/6/7 21:53:18

目录

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、最后

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


http://www.hkcw.cn/article/VHldqbZUDF.shtml

相关文章

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…

传统业务对接AI-AI编程框架-Rasa的业务应用实战(1)--项目背景即学习初衷

我的初衷:我想学习AI。具体的方向是这样的:原本传统的平台业务去对接智能体。比如发票业务,发票的开具、审核、计税、回款等。根据用户在业务系统前台界面输入若干提示词 或者 语音输入简短语音信息,可以通过智能体给出需要处理的…

【八股消消乐】索引失效与优化方法总结

😊你好,我是小航,一个正在变秃、变强的文艺倾年。 🔔本专栏《八股消消乐》旨在记录个人所背的八股文,包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法等相关知识点&#xff…

Java面试八股--06-Linux篇

目录 一、Git 1、工作中git开发使用流程(命令版本描述) 2.Reset与Rebase,Pull与Fetch的区别 3、git merge和git rebase的区别 4、git如何解决代码冲突 5、项目开发时git分支情况 二、Linux 1、Linux常用的命令 2、如何查看测试项目的…

动态规划-647.回文子串-力扣(LeetCode)

一、题目解析 这里的子字符串是连续的,与之前的子序列不同,这里需要我们统计回文子串的数目。 二、算法原理 这里也有其他算法可以解决该问题,如中心扩展算法 时间复杂度O(N^2)/空间复杂度O(1),马拉车算法(具有局限性) 时间复杂…

条形进度条

组件 <template><view class"pk-detail-con"><i class"lightning" :style"{ left: line % }"></i><i class"acimgs" :style"{ left: line % }"></i><view class"progress&quo…

大模型赋能:金融智能革命中的特征工程新纪元

一、AI进化论&#xff1a;从“判别”到“生成”的金融新战场 1.1 判别式AI的“痛点”与大模型的“破局” 想象这样一幅画面&#xff1a;银行风控模型像老式收音机&#xff0c;需要人工反复调试参数才能捕捉风险信号&#xff1b;而大模型则是智能调音台&#xff0c;能自动“听…

HA: Wordy靶场

HA: Wordy 来自 <HA: Wordy ~ VulnHub> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.128&#xff0c;靶场IP192.168.23.130 3&#xff0c;对靶机进行端口服务探…

技巧小结:外部总线访问FPGA寄存器

概述 需求&#xff1a;stm32的fsmc总线挂载fpga&#xff0c;stm32需要访问fpga内部寄存器 1、分散加载文件将变量存放到指定地址即FPGA寄存器地址 sct文件指定变量存储地址&#xff0c;从而可以直接访问外设&#xff0c;&#xff08;28335也可以&#xff0c;不过用的是cmd文件…

深入理解 x86 汇编中的重复前缀:REP、REPZ/REPE、REPNZ/REPNE(进阶详解版)

一、重复前缀&#xff1a;串操作的 “循环加速器” 如果你写过汇编代码&#xff0c;一定遇到过需要重复处理大量数据的场景&#xff1a; 复制 1000 字节的内存块比较两个长达 200 字符的字符串在缓冲区中搜索特定的特征值 手动用loop指令编写循环&#xff1f;代码冗长不说&a…

【PCB设计】STM32开发板——原理图设计(电源部分)

一、PCB设计流程 二、准备工作 1.点击文件新建工程并命名 2.新建图页 在绘制较为复杂的原理图时&#xff0c;可以建立多个图页&#xff0c;使得原理图更加清晰。 右击原理图→新建图页 右击→重命名 3.设计规则相关配置 取消勾选第22个 4.调整页面大小 5.放置“电源树”图片…

C++仿RabbitMQ实现消息队列

前言 本项目将使用 C 在 Linux&#xff08;CentOS 7.6&#xff09; 环境下开发一个仿 RabbitMQ 的简易消息队列。 开发和调试环境如下&#xff1a; 操作系统&#xff1a;Linux (CentOS 7.6) 编辑器&#xff1a;Visual Studio Code / Vim 编译器&#xff1a;g&#xff08;GNU…

离散数学_数理逻辑(二):命题逻辑的推理

前言 每一件事都存在现象和本质.现象是表面,本质是内在.数学可以说是自然科学之母,是一切自然现象的本质.对于编程,表面上是在写代码,实际上是在用离散数学理解问题和解决问题. 引入 命题逻辑的推理部分. "推理"在思考中占了很大比重.笔者曾经把学习方法分了两种:一…

KITTI数据集(计算机视觉和自动驾驶领域)

KITTI&#xff08;Karlsruhe Institute of Technology and Toyota Technological Institute at Chicago&#xff09;数据集是计算机视觉和自动驾驶领域中最广泛使用的基准数据集之一。它由德国卡尔斯鲁厄理工学院和美国芝加哥丰田技术研究所联合发布&#xff0c;旨在推动自动驾…

力扣4.寻找两个正序数组的中位数

文章目录 题目介绍题解 题目介绍 题解 题解链接&#xff1a;题解 核心思路&#xff1a;通过二分查找的确定分割点使左右两部分元素数量相等。 class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {int n1 nums1.length;int n2 nums2.length…

Windows下将Nginx设置注册安装为服务方法!

一、需求背景 每次启动 Nginx 都要去到 Nginx 安装目录下寻找 nginx.exe 文件点击&#xff0c;很是麻烦。 并且远程登录桌面&#xff0c;有时注销用户&#xff0c;会把在当前用户打开的nginx关闭了。 于是考虑可不可以跟其它服务一样能够开机自启&#xff1f;显然是可以的。…

web第九次课后作业--SpringBoot基于mybatis实现对数据库的操作

前言 在前面我们学习MySQL数据库时&#xff0c;都是利用图形化客户端工具(如&#xff1a;idea、datagrip)&#xff0c;来操作数据库的。 在客户端工具中&#xff0c;编写增删改查的SQL语句&#xff0c;发给MySQL数据库管理系统&#xff0c;由数据库管理系统执行SQL语句并返回执…

SpringBoot+XXL-JOB:高效定时任务管理

一、前言 在现代应用程序中&#xff0c;定时任务是不可或缺的一部分。Spring Boot 和 XXL-Job 为你提供了一个强大的工具组合&#xff0c;以简化任务调度和管理。本文将带领你探索如何将这两者集成在一起&#xff0c;实现高效的定时任务管理。无论你是初学者还是有经验的开发者…

java-spring

入门案例 通过bean创建对象 先通过spring的ClassPathXmlApplicationContext读取xml文件 ,然后通过getbean()函数获取对象&#xff0c;进行操作通过反射机制&#xff0c;吸纳Class的函数forName(class属性)创建对象&#xff0c;然后clazz.getDeclaredConstructor().newinstanc…

springboot @value

#springboot value value 可以读取 yaml 中 的数据