C++ 软件常用分析工具及项目实战问题分析案例集锦

news2024/9/28 21:22:24

目录

1、库依赖关系查看工具Dependency Walker

2、GDI对象查看工具GDIview

3、PE信息查看工具PeViewer/MiTeC EXE Explorer

4、进程信息查看工具Process Explorer

5、进程监控工具Process Monitor

6、API函数调用监测工具API Monitor


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_2276111.html        在分析C++软件问题时,我们时常需要使用一些常用的软件分析工具,比如Dependency Walker、GDIview、PeViewer/MiTeC EXE Explorer、Process Explorer、Process Monitor和API Monitor等。今天就来详解介绍一下使用这些工具分析问题的案例集锦。

1、库依赖关系查看工具Dependency Walker

       Dependency Walker主要用来查看库与库的依赖关系,用来排查因为库版本或者库缺失引发的程序启动报错、动态加载的dll库加载失败的问题。

       程序启动时,会优先将exe主程序依赖的各个dll库加载到进程空间中,在加载某个dll库时会优先将其依赖的dll库加载到进程空间中,最后等所有依赖的dll库都加载起来后,最后将主程序加载起来,进入主程序的main函数,程序进而运行起来。如果在加载dll库时失败,则整个程序的启动过程会终止,程序启动失败。

       程序因为库问题问题导致程序启动失败,主要有两种原因

1)可能在运行的机器上缺少dll库。比如缺少业务库或者C/C++运行时库,即在加载库时报错;
2)也有可能时在加载某个dll模块时发现其调用的另一个dll库的接口在该dll中找不到。这个一般是因为库与库之间的版本不一致导致的。

这两类问题排查起来很简单,只要用Dependency Walker打开exe主程序或者出问题的dll库,即可查看到缺少哪些库以及哪些接口在被依赖的dll库中找不到。

       使用Dependency Walker排查程序启动报错问题的案例,可以查看我之前写的文章:(有时需要将几个工具结合起来去分析)
使用Dependency Walker和Process Explorer排查瑞芯微工具软件RKPQTool.exe启动报错问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/135229025使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错的问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/135165307使用Dependency Walker和Process Explorer排查程序启动时缺少ucrtbase.dll等运行时库以及报0xC000007B错误icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131505299       有时有些dll库是在程序启动时动态启动的,比如软件可以根据自己的业务需要,选择性其启动一些模块,就可以采用动态启动的方式。如果动态加载的dll库有问题加载不起来了,启动exe主程序时是不会报错的。我们需要根据相关业务是否正常去判断对应的dll模块有没有启动起来,我们可以使用Process Explorer去查看目标进程加载的dll库列表,如果列表中没看到目标dll库,则说明该dll库加载失败了。

       使用Process Explorer和Dependency Walker排查动态加载的库加载失败的案例,可以查看我之前写的文章:

使用Process Explorer和Dependency Walker排查C++程序中dll库动态加载失败问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/130198751

      但Dependency Walker目前有个较大的问题,在Win10等较新的操作系统上打开文件时非常慢,有时要等好几分钟,夸张的时候甚至要等十来分钟!因为Dependency Walker最后一个版本是2006的,至今没有出过新版本了,如下所示:

可能是对Win10等新系统兼容不好,导致打开文件特别慢。

       大家可以使用github上开源的一个叫做Dependencies的开源工具(Dependencies - An open-source modern Dependency Walker),这个工具打开文件特别快,如下所示:

这是一个网上的朋友推荐的!这个Dependencies工具是开源的,github地址为:https://github.com/lucasg/Dependencies ,需要的话,可以到该地址上去下载该工具。


        在这里,给大家重点推荐一下我的几个热门畅销专栏:

专栏1:(该专栏订阅量接近350个,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!)

C++软件调试与异常排查从入门到精通系列文章汇总icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931

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

专栏中的文章均是通过项目实战总结出来的(通过项目实战积累了大量的异常排查素材和案例),有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2: 

C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战为基础,总结并讲解一些的C/C++基础与进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域的多个方面的内容,同时给出C/C++及网络方面的常见笔试面试题,并详细讲述Visual Studio常用调试手段与技巧!

专栏3: 

开源组件及数据库技术icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html

以多年的开发实战为基础,分享一些开源组件及数据库技术! 


2、GDI对象查看工具GDIview

        在Windows程序中很多的绘图操作都是使用系统的GDI对象去完成的,比如输出文字、绘制线条、绘制图片等,常见的GDI对象包括Pen画笔、Brush画刷、Font字体、Bitmap位图、Region区域、DC设备上下文等。在绘制操作完成后需要将GDI对象释放掉,否则会造成GDI对象泄露

如果有GDI对象泄露的代码在持续不断的执行,会导致GDI对象持续的泄露,而一个进程的GDI对象总数是有上限的(默认上限值是10000个)如果程序占用的GDI对象接近或达到上限,会导致绘制操作出现失败或异常,紧接着就会发生闪退崩溃

       如何判断程序运行过程中是否有GDI对象泄露呢?其实很简单,只需要打开Windows任务管理器:

       持续的观察程序的GDI对象总数是否在持续不断地上升,如果在持续上升,则说明有GDI对象泄露。

Windows任务管理器的进程列表中默认是不显示GDI列的,可以右键点击进程列表的标题栏,在弹出的右键菜单中点击“选择列”,然后再弹出的窗口中勾选“GDI对象”就可以了,如下所示:

       Windows任务管理器中只能看到进程占用的GDI对象总数,但看不到具体对象的数目,这恰恰是GDiView能做到的!

       GDIView工具则是排查GDI对象泄露的利器,可以查看到每种GDI对象的数目,这样就能看到具体是哪种GDI对象明显偏高了,这样我们就能有针对性的排查问题了。有时我们可能要使用历史版本比对法,使用二分法选择多个时间的软件版本去安装,看看问题是从哪一天出现的,然后查看前一天的代码修改记录或者底层库发布记录,就大概能确定问题范围了。

历史版本比对法,要依赖历史版本的维护,比如我们有自动化编译系统,如果当天有代码修改或者底层库发布,每天凌晨会自动更新代码并发起编译,并将编译出来的版本拷贝到专用的文件服务器上维护起来,如下所示:

颗粒度精细到每天,这样对有效实施历史版本比对法很重要!

       关于使用GDIView排查GDI对象泄露的实例,可以查看我的文章:

使用GDIView工具排查GDI对象泄漏导致程序UI界面绘制异常的问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/128625868使用GDIView工具排查WebRTC开源库中的GDI对象泄漏问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125399896

3、PE信息查看工具PeViewer/MiTeC EXE Explorer

       目前主要用PE信息查看工具查看二进制文件的时间戳,即二进制文件生成的时间,通过时间戳可以确定二进制文件的版本。

我这边之前使用的PE信息查看工具叫PeViewer,有次在排查问题时发现,在用该工具打开一个64位二进制文件时发生了闪退崩溃。后来在网上搜到了MiTeC EXE Explorer工具,这个工具兼容性比较好,打开64位二进制文件没有问题。

       使用PE工具排查问题的案例,可以查看我的文章:
使用PE信息查看工具和Beyond Compare文件比较工具排查dll文件版本不对的问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/135138815使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错的问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/135165307

4、进程信息查看工具Process Explorer

       Process Explorer是微软提供的一个查看进程信息的工具,某些功能类似于Windows任务管理器,但功能要强大很多,是增强版的任务管理器。Process Explorer的主要功能有:

1)可以查看运行起来的程序在启动时传递的命令行参数。比如Chrome浏览器程序,启动时会启动多个进程,可以通过查看每个进程启动时传递的命令行参数去大概看出该进程是用来做什么的,比如用来做GPU加速、页面渲染等。
2)可以查看程序启动起来后都加载了哪些dll库。可以查看到dll库的路径等详细信息。可以用来确认动态加载的dll库有没有加载起来。
3)可以查看进程的各个线程的信息。比如查看线程的CPU占用比例,可以查看线程的实时函数调用堆栈,这对于分析死循环引起的高CPU占用问题非常有用。但Process Explorer查看线程的函数调用堆栈可能不太准确,可以尝试使用同类型工具Process Hacker
4)可以查看进程的GPU占用情况。以音视频处理为例,GPU占用分两类,一是播放视频时会用到GPU加速,二是视频硬编硬解会使用到GPU。如果要看GPU,建议使用Windows系统自带的任务管理器,显示的比较详细,如下:

       使用Process Explorer排查程序高CPU占用的实例,可以查看我的文章:(有时可能需要使用到多个软件工具)

使用Process Explorer/Process Hacker和Windbg高效排查软件高CPU占用问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/134180480       使用Process Explorer排查程序因为死循环导致线程堵塞的实例,可以查看我的文章:

使用Process Explorer和Windbg排查软件线程堵塞案例分享icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/135361532

5、进程监控工具Process Monitor

       我们可以使用该工具监控目标程序对文件和注册表的操作情况,在监控到的条目中可以双击查看相关的函数调用堆栈,通过函数调用堆栈可以看到是哪些模块操作的,调用了哪些接口操作的。

       比如,我们在运行软件时会在桌面上生成一个日志文件,但无法确定是我们程序的哪个模块生成的,可以使用该工具监控一下我们程序的文件操作活动。再比如,我们想知道当执行某个程序的某个操作时程序都读写了哪些注册表信息,可以使用该工具监测一下该程序的注册表活动。

       使用Process Monitor监控程序文件活动的实例,可以查看我的文章:
使用Process Monitor工具探测日志文件是程序哪个模块生成的icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/133339034使用Process Monitor排查因dll库被锁定导致C++程序启动报“0xc0000022”错误问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/130655847      使用Process Monitor监控程序注册表活动的实例,可以查看我的文章:

使用Process Monitor探测Windows系统高DPI缩放设置的注册表项icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/130586460

6、API函数调用监测工具API Monitor

        API Monitor工具可以用来监测目标程序对系统API函数或第三方库接口的调用情况。比如我们想研究某主流软件的某个功能的实现方法,看看程序在实现该功能时都调用了哪些系统API函数,就可以使用该工具去探测一下,我们在项目中用到过多次。

       使用API Monitor工具监测程序调用函数的实例,可以参见我的文章:
使用API Monitor工具巧妙探测C++程序中监听某端口的模块icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/133339829使用API Monitor监测目标程序实现阻止屏保的新功能icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125362394

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1363687.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux-v4l2框架

框架图 从上图不难看出,v4l2_device作为顶层管理者,一方面通过嵌入到一个video_device中,暴露video设备节点给用户空间进行控制;另一方面,video_device内部会创建一个media_entity作为在media controller中的抽象体&a…

基于springboot的停车场管理系统-计算机毕业设计源码82061

摘要 由于数据库和数据仓库技术的快速发展,停车场管理系统建设越来越向模块化、智能化、自我服务和管理科学化的方向发展。停车场管理系统对处理对象和服务对象,自身的系统结构,处理能力,都将适应技术发展的要求发生重大的变化。停…

【读书笔记】网空态势感知理论与模型(九)

对分析人员数据分类分流操作的研究 1.概述 本章节介绍一种以人员为中心的智能数据分类分流系统,该系统利用了入侵检测分析人员的认知轨迹。整合了3个维度的动态网络-人系统(cyber-humber system):网空防御分析人员、网络监测数据…

基于天牛须算法优化的Elman神经网络数据预测 - 附代码

基于天牛须算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于天牛须算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于天牛须优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&#x…

OpenCV图像处理|1.1 OpenCV介绍与环境搭建

1.1.1 介绍 OpenCV(Open Source Computer Vision Library)开放源代码计算机视觉库,主要算法涉及图像处理、计算机视觉和机器学习相关方法。OpenCV 其实就是一堆 C 和 C语言的源代码文件,这些源代码文件中实现了许多常用的计算机视…

JavaWeb——新闻管理系统(Jsp+Servlet)之jsp新闻新增

java-ee项目结构设计 1.dao:对数据库的访问,实现了增删改查 2.entity:定义了新闻、评论、用户三个实体,并设置对应实体的属性 3.filter:过滤器,设置字符编码都为utf8,防止乱码出现 4.service:业务逻辑处理 5.servlet:处…

Spring中事务控制的API介绍(PlatformTransactionManager和TransactionDefinition)

事务控制的API PlatformTransactionManager接口 作用:是一个事务管理器,负责开启、提交或回滚事务 实现类:DataSourceTransactionManager(sqlSession) 此接口是spring的事务管理器,它里面提供了我们常用的操作事务的方法…

生信 R语言

11.芯片表达矩阵下游分析 ​rm(list ls())#清除所有变量 options(stringsAsFactors F) #BiocManager::install("CLL") suppressPackageStartupMessages(library(CLL)) data("sCLLex") sCLLex ## ExpressionSet (storageMode: lockedEnvironment) ## as…

报错curl: (6) Could not resolve host: raw.githubusercontent...的解决办法

我起初想要在macOS系统安装pip包,首先在终端安装homebrew,敲了命令:/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent...)" 之后触发的报错,报错内容:curl: (6) Could not resolve host: raw.…

如何从 Android SD卡/存储卡中恢复删除的照片

虽然大多数摄影师和智能手机用户都非常喜欢在一张 存储卡上存储数千张照片的能力,但它也可能导致灾难性的数据丢失,而 存储卡照片恢复软件通常是唯一的解决方案。 但是,如果您不迅速采取行动并在图像被覆盖之前恢复图像,那么即使…

如何向嵌入式设备中添加tcpdump工具

说明:tcpdump是一个在网络设备调试中一个非常重要的工具,它并不像hexdump等工具集成在busybox里面,也不像其他的软件一样只需要依赖linux标准的库就可以实现,它需要pcap相关的库和加密的相关库。 本文主要是基于realtek 83系列的…

SpringBoot+Redis实现接口防刷功能

场景描述: 在实际开发中,当前端请求后台时,如果后端处理比较慢,但是用户是不知情的,此时后端仍在处理,但是前端用户以为没点到,那么再次点击又发起请求,就会导致在短时间内有很多请求…

《路由与交换技术》---简答题

1、什么是STP?解决什么问题? STP代表生成树协议(Spanning Tree Protocol)。它是用于在计算机网络中解决环路问题的一种协议。 STP的主要目标是消除环路,保持网络的稳定性和可靠性,同时提供冗余路径以实现网…

批量删除文件名的空格,一键清理让文件名中的空格去无踪

我们每天都会创建、下载、重命名很多文件,在文件的重命名过程中,我们会不自觉地在文件名中加入空格,这些看似无害的空格,在某些情况下,却可能引发诸多不便。例如,在某些软件或操作系统中,空格可…

【Java】设计模式之保护性暂停

设计模式之保护性暂停 Guarded Suspension,这个设计模式,主要用在一个线程等待另一个线程的执行结果(发请求等待响应) 有一个结果需要从一个线程传递到另一个线程,传递只进行一次,用设计模式保护性暂停。 …

使用pagehelper插件进行分页查询

一、导入mybatis和pagehelper坐标 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version> </dependency> <dependency><groupId&…

项目管理进阶之PDCA

前言 项目管理进阶系列&#xff0c;今天开始发布第一篇喽。 博主其实一直在构思&#xff0c;如何开启这个系列&#xff0c;但是我们通常项目管理讲的“五大过程十大领域”&#xff0c;往往太书面了。因此尝试从中抓取几个核心&#xff0c;以供有志之士参考。 那么&#xff0c…

史诗级长文--决策树

决策树 决策树(decision tree)是一种基本的分类与回归方法。 举个通俗易懂的例子&#xff0c;如下图所示的流程图就是一个决策树&#xff0c;长方形代表判断模块(decision block)&#xff0c;椭圆形成代表终止模块(terminating block)&#xff0c;表示已经得出结论&#xff0c;…

基于商品列表的拖拽排序后端实现

目录 一&#xff1a;实现思路 二&#xff1a;实现步骤 二&#xff1a;实现代码 三&#xff1a;注意点 一&#xff1a;实现思路 后台实现拖拽排序通常需要与前端进行配合&#xff0c;对商品的列表拖拽排序&#xff0c;前端需要告诉后端拖拽的元素和拖动的位置。 这里我们假…

Java多线程技术11——ThreadPoolExecutor类的使用1

1 概述 ThreadPoolExecutor类可以非常方便的创建线程池对象&#xff0c;而不需要程序员设计大量的new实例化Thread相关的代码。 2 队列LinkedBlockingQueue的使用 public class Test1 {public static void main(String[] args) {LinkedBlockingQueue queue new LinkedBlocki…