使用Process Explorer、Dependency Walker和PE信息查看工具快速排查dll动态库因库与库版本不一致导致的加载失败问题

news2025/3/12 10:02:37

目录

1、问题说明

2、使用Process Explorer查看目标dll动态库有没有动态加载起来

3、使用Dependency Walker查看xxpadll.dll库的库依赖关系,找到xxpadll.dll加载失败的原因

4、使用PE信息查看工具查看目标dll库的时间戳

5、关于xxsipstack2.dll中调用xxdatanet.dll中接口的小插曲

6、最后


C++软件异常排查从入门到精通系列教程(核心精品专栏,订阅量已达600多个,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战专栏(重点专栏,专栏文章已更新500多篇,订阅量已达数百个,欢迎订阅,持续更新中...)https://blog.csdn.net/chenlycly/article/details/140824370C++ 软件开发从入门到实战(重点专栏,专栏文章已更新300多篇,欢迎订阅,持续更新中...)https://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585分析C++软件问题的实用软件与高效工具实战案例集锦汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_2276111.html       在软件的日常开发与维护过程中,我们需要熟练使用一些常用软件分析工具去辅助排查软件运行时遇到的多个问题,常用的工具有SPY++、Dependency Walker、PE查看工具、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg和IDA等。今天我们就来讲一个项目中遇到的动态库动态加载失败的问题实例,讲述如何使用Process Explorer、Dependency Walker和PE信息查看工具来快速排查这个问题,以供大家借鉴或参考。

1、问题说明

       某天测试人员反馈,客户端软件中出现问题,导致客户端无法注册登录到平台的某个业务服务器上,导致与该业务服务器相关的业务出现异常。经维护该业务模块的同事排查,初步怀疑是客户端底层的某个业务dll动态库没有动态加载起来,导致登录业务服务器失败。我们的客户端软件,从UI层到底层业务模块,包含了上百个dll库,排查起来似乎不太容易,但实际上我们使用Process Explorer、Dependency Walker和PE信息查看工具这几个工具就能快速定位问题。在这个问题中,这三个工具的主要用途如下:

1)Process Explorer:查看目标dll在程序启动后有没有动态加载起来。
2)Dependency Walker:查看没有动态加载起来的动态库的库依赖关系,确定该动态库为什么动态加载失败。
3)PE信息查看工具:查看dll动态库的时间戳,即动态库的生成时间。

2、使用Process Explorer查看目标dll动态库有没有动态加载起来

       经维护业务模块开发人员初步排查,怀疑客户端底层的某个dll业务库没有动态启动起来。其实确认这个dll有没有动态加载起来,很简单,直接使用Process Explorer工具就可以立即看出来。打开Process Explorer,在进程列表中找到客户端进程,选中该进程,在下方显示的加载库列表中去查找目标dll库,如果找不到,就表示这个dll库没有加载起来。

      本问题没有加载起来的库是xxpadll.dll,库列表中找不到这个库:

所以该库没加载起来。

       有人可能会问,既然xxpadll.dll库没有加载起来,那程序启动时为什么没有报错呢?这里涉及到一个知识点,动态库加载有两种方式,一种是隐式加载,一种是显式加载。

       所谓隐式加载,就是在代码中包含dll动态库的头文件并引入dll动态库对应的.lib库,然后在代码中直接调用dll库的导出接口。对于隐式加载的dll库,程序启动时会优先将该dll库加载到进程空间中,如果dll库加载失败,则会弹出报错提示框,比如:

然后程序启动过程终止,程序启动失败。

       所谓显式加载,就是先调用LoadLibrary或LoadLibraryEx将库动态加载起来,然后通过函数名称去获取函数地址,然后去调用该函数。对于显式加载的动态库,不会在程序启动时加载,而是在执行到LoadLibrary或LoadLibraryEx接口调用时才会动态加载,如果库加载失败,并不会弹出报错提示框。

       在本案例中,没加载起来的xxpadll.dll库,是显式动态加载的,所以加载失败时不会弹出报错提示框。

3、使用Dependency Walker查看xxpadll.dll库的库依赖关系,找到xxpadll.dll加载失败的原因

       dll动态库加载失败,应该都是其依赖的dll库有问题导致的,比如在运行的机器上找不到依赖的某个dll库,或者是调用的某个dll库中的接口在该库中找不到(可能接口名称修改了,可能是接口参数修改了,所以找不到了)。要确定dll库加载失败的具体原因,很简单,直接用Dependency Walker打开这个加载失败的xxpadll.dll库,查看该库依赖的库关系,就能搞清楚。

       于是用Dependency Walker打开xxpadll.dll库,看到了异常,如下所示:

xxpadll.dll依赖了xxsipstack2.dll库,而这个xxsipstack2.dll库依赖了xxdatanet.dll库,在xxdatanet.dll库节点前显示异常的红色图标,具体看到xxsipstack2.dll调用了xxdatanet.dll库中的GetProductName、RetrieveVendor、strucase和SubvendorReturn2One这几个接口,但接口节点前也显示红色图标,这表示这几个接口在当前的xxdatanet.dll库中找不到(在exe主程序安装目录中的xxdatanet.dll库中找不到这些接口)。

       当前问题中的xxsipstack2.dll和xxdatanet.dll等库,属于协议层的库,而昨天协议层向我们的软件代码流上发布了新的协议库(包含了多个dll库),所以根据以往的经验,估计是xxsipstack2.dll和xxdatanet.dll这两个库的版本不一致导致的,此时需要查看这两个库的生成时间去确定。

       我之前详细总结了DLL动态库加载失败导致程序启动报错以及DLL库加载失败的常见原因,很有实战参考价值,可以查看对应的文章:

【C++动态库】DLL动态库加载失败导致程序启动报错以及DLL库加载失败的常见原因分析与总结https://blog.csdn.net/chenlycly/article/details/142714236       关于使用工具排查dll动态库加载失败的实战分析案例,可以查看我之前写的文章:

使用Process Explorer和Dependency Walker排查C++程序启动时缺少ucrtbase.dll等运行时库以及报0xC000007B错误https://blog.csdn.net/chenlycly/article/details/140731927使用Process Explorer和Dependency Walker排查dll动态库没法调试的问题(dll库加载失败导致没法动态调试)https://blog.csdn.net/chenlycly/article/details/140803687       此外,有个细节点需要注意一下,Dependency Walker打开dll库文件时会特别慢,有时甚至需要等到好几分钟才能打开,然后才能去查看库与库的依赖关系。我们当前使用的Dependency Walker是2006年的版本:

可能是这个老版本的Dependency Walker对当前的Win10系统兼容不好,所以打开的非常慢。 


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

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

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

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

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

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

专栏2:(本专栏涵盖了C++多方面的内容,是当前重点打造的专栏,订阅量已达300多个,专栏文章已经更新到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++软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。


4、使用PE信息查看工具查看目标dll库的时间戳

       上面怀疑是xxsipstack2.dll和xxdatanet.dll版本不一致导致的,可以使用PE信息查看工具查看文件的时间戳(文件编译生成时间)确定模块版本。注意,模块的时间戳不能等同于Windows系统中文件的修改时间

修改时间只代表该文件在本系统中的修改时间,并不等同于文件的生成时间。要查看文件的生成时间,应该使用PE信息查看工具查看文件的PE头中的时间戳。

       用PE信息查看工具PeViewer打开xxsipstack2.dll:

查看到该文件的生成时间(时间戳)为2025/02/21 14:59:40。用PeViewer打开xxdatanet.dll文件:

看到该文件的生成时间(时间戳)为2024/08/29 14:13:11,两个文件的生成时间相差了大半年,所以可能是版本不一致导致的。

       于是和协议组的同事确认这次发布过来的协议的库是不是都包含这两个库。协议组同事确认,这两个库应该是同一天编译生成的,即这两个库的生成时间是同一天的,而当前客户端程序的安装目录中的这两个文件的生成时间居然相差大半年,所以初步确定是dll库的版本不一致导致的。

       怀疑可能是协议组发布库时xxdatanet.dll编译失败了,导致协议组这次发布新库时没有带上xxdatanet.dll,所以在客户端程序中使用的还是大半年前老版本的xxdatanet.dll库,进而出现版本不一致的问题。经协议组同事确认,xxdatanet.dll库的编译确实有问题,于是去分析xxdatanet.dll库编译失败的原因,将最新版本的xxdatanet.dll库发布过来就好了。

       查看dll或exe二进制文件的时间戳和位数,除了使用PE工具,还可以使用Visual Studio自带的dumpbin工具,相关方法及实战使用案例可以查看我的文章:

使用Dumpbin工具查看C++二进制文件的位数、时间戳及dll库的依赖关系https://blog.csdn.net/chenlycly/article/details/140153214使用Dependency Walker和dumpbin工具定位C++软件启动时找不到接口的报错问题https://blog.csdn.net/chenlycly/article/details/125665650

5、关于xxsipstack2.dll中调用xxdatanet.dll中接口的小插曲

        在和协议组的同事排查这个问题的过程中,协议组的同事说xxsipadapter2.dll库中并没有调用GetProductName、RetrieveVendor、strucase和SubvendorReturn2One这几个接口,这个dependency walker工具显示的是否有问题?这个肯定没问题的,dependency walker是读取xxsipadapter2.dll库的PE头中导入表信息得知调用的接口及库依赖关系的,是不会有问题的。

       于是让同事在项目代码中搜索这几个接口,看看到底是哪些模块调用的。反馈是xxprotocommon库调用的,但xxsipadapter2.dll库并没有调用这几个接口!于是我估计,这个xxprotocommon库是静态库,直接编译到xxsipadapter2.dll库中了(协议组的同事可能不太了解这一点),所以dependency walker上显示xxsipadapter2.dll库调用了上述几个接口!协议组同事回复,这个xxprotocommon库确实是静态库,这样就能解释的通了。

6、最后

       Process Explorer、Dependency Walker和PE信息查看工具,这些小工具看似功能简单,但排查一些问题时确实很有用,能够快速定位问题,有必要把这些工具都学会!常用的软件工具有SPY++、Dependency Walker、PE查看工具、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg和IDA等,关于如何使用这些工具以及使用这些工具排查项目问题的实战分析案例,可以查看我的专栏文章:   

分析C++软件问题的实用软件与高效工具实战案例集锦汇总https://blog.csdn.net/chenlycly/article/details/131405795       本文的问题排查起来比较简单,但有一定的代表性,对于开发新手或者不会使用工具的人,有较大的参考价值!

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

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

相关文章

Git的命令学习——适用小白版

浅要了解一下Git是什么: Git是目前世界上最先进的的分布式控制系统。Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。Git 并不保存这些前后变化的差异数据。实际上…

如何安全处置旧设备?

每年,数百万台旧设备因老化、故障或被新产品取代而被丢弃,这些设备上存储的数据可能带来安全风险。 如果设备没有被正确删除数据,这些数据往往仍可被恢复。因此,安全处置旧设备至关重要。 旧设备可能包含的敏感数据 旧设备中可能…

Java 学习记录:基础到进阶之路(一)

今天,让我们深入到 Java 项目构建、基础语法及核心编程概念的领域,一探究竟。 软件安装及环境配置请查看之前更新的博客有着详细的介绍: IDEA软件安装&环境配置&中文插件-CSDN博客 目录 1.Java 项目构建基础 1.项目中的 SRC 目录…

系统架构设计师—系统架构设计篇—软件架构风格

文章目录 概述经典体系结构风格数据流风格批处理管道过滤器对比 调用/返回风格主程序/子程序面向对象架构风格层次架构风格 独立构件风格进程通信事件驱动的系统 虚拟机风格解释器基于规则的系统 仓库风格(数据共享风格)数据库系统黑板系统超文本系统 闭…

工厂模式加策略模式 -- 具体实现

这里写目录标题 定义接口定义抽象类定义主处理器分支处理器定义工厂demo 定义接口 public interface EntityHandler extends InitializingBean {MatchContentDTO match(MatchEntityDTO matchEntityDTO);String supportEntityType(); }定义抽象类 public abstract class Abstr…

STM32---FreeRTOS消息队列

一、简介 1、队列简介: 队列:是任务到任务,任务到中断、中断到任务数据交流的一种机制(消息传递)。 FreeRTOS基于队列,实现了多种功能,其中包括队列集、互斥信号量、计数型信号量、二值信号量…

python-leetcode-删掉一个元素以后全为 1 的最长子数组

1493. 删掉一个元素以后全为 1 的最长子数组 - 力扣(LeetCode) 可以使用滑动窗口的方式来解决这个问题。我们要找到最长的全 1 子数组,但必须删除一个元素,因此可以将问题转化为寻找最多包含一个 0 的最长子数组。 解题思路 使用双指针(滑动窗口),维护窗口内最多包含一…

【赵渝强老师】PostgreSQL的模板数据库

在PostgreSQL中,创建数据库时实际上通过拷贝一个已有数据库进行工作的。在默认情况下,将拷贝名为template1的标准系统数据库。所以该数据库是创建新数据库的“模板”。如果为template1数据库增加对象,这些对象将被拷贝到后续创建的用户数据库…

vue2中,在table单元格上右键,对行、列的增删操作(模拟wps里的表格交互)

HTML <template><div><divclass"editable-area"v-html"htmlContent"contenteditableblur"handleBlur"contextmenu.prevent"showContextMenu"></div><button click"transformToMd">点击转成M…

使用DeepSeek+蓝耘快速设计网页简易版《我的世界》小游戏

前言&#xff1a;如今&#xff0c;借助先进的人工智能模型与便捷的云平台&#xff0c;即便是新手开发者&#xff0c;也能开启创意游戏的设计之旅。DeepSeek 作为前沿的人工智能模型&#xff0c;具备强大的功能与潜力&#xff0c;而蓝耘智算云平台则为其提供了稳定高效的运行环境…

解决微信小程序中调用流式接口,处理二进制数据时 TextDecoder 不兼容的问题

问题复现 最近在开发一个 AI 问答小程序时&#xff0c;由于接口返回的是流式二进制数据&#xff0c;因此我使用了 TextDecoder 的 decode 方法将二进制数据转换为文本。在开发环境中&#xff0c;数据处理一直没有问题&#xff0c;但在真机测试及上线后&#xff0c;发现调用接口…

Java 大视界 -- Java 大数据在智慧农业农产品质量追溯与品牌建设中的应用(124)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

c++介绍信号六

信号量是c中实现对有限资源访问控制&#xff0c;现成通过信号量获得对资源访问的许可。可用资源大于0&#xff0c;线程可以对资源进行访问&#xff0c;此时计数器减1。当计数器为0时&#xff0c;不可访问资源&#xff0c;线程进入等待。当资源释放时&#xff0c;线程结束等待&a…

GStreamer —— 2.18、Windows下Qt加载GStreamer库后运行 - “播放教程 6:音频可视化“(附:完整源码)

运行效果 介绍 GStreamer 带有一组将音频转换为视频的元素。他们 可用于科学可视化或为您的音乐增添趣味 player 的本教程展示了&#xff1a; • 如何启用音频可视化 • 如何选择可视化元素 启用音频可视化实际上非常简单。设置相应的标志&#xff0c;当纯音频流为 found&#…

用Deepseek写一个 HTML 和 JavaScript 实现一个简单的飞机游戏

大家好&#xff01;今天我将分享如何使用 HTML 和 JavaScript 编写一个简单的飞机游戏。这个游戏的核心功能包括&#xff1a;控制飞机移动、发射子弹、敌机生成、碰撞检测和得分统计。代码简洁易懂&#xff0c;适合初学者学习和实践。 游戏功能概述 玩家控制&#xff1a;使用键…

Android Compose MutableInteractionSource介绍

在 Android 开发中&#xff0c;Compose 是 Google 推出的现代化 UI 工具包&#xff0c;它让开发者能够更简洁高效地构建应用界面。而 MutableInteractionSource 是 Compose 中一个重要的组件&#xff0c;它可以帮助你处理用户与界面交互时的状态变化&#xff0c;尤其在处理交互…

[杂学笔记] TCP和UDP的区别,对http接口解释 , Cookie和Session的区别 ,http和https的区别 , 智能指针 ,断点续传

文章目录 1. TCP和UDP的区别2. 对http接口解释3. Cookie和Session的区别4. http和https的区别5. 智能指针6.断点续传 1. TCP和UDP的区别 tcp的特点&#xff1a; 面向连接&#xff0c;可靠性高&#xff0c;全双工&#xff0c;面向字节流udp特点&#xff1a;无连接&#xff0c;不…

【NLP 29、项目 Ⅰ:电商评论分类(好评 / 差评) 】

目录 项目介绍 一、训练及测试数据 二、代码实现 1.配置文件 config.py 2.分割训练集和验证集 split_train_valid.py 3.数据加载文件 loader.py Ⅰ、 加载和处理数据 DataGenerator ① 初始化 ② 数据加载 ③ 文本编码 ④ 补齐 / 截断 ⑤ 获取数据集长度和指定索引的数据 Ⅱ、加…

halcon deeplearn 语义分割经验分享 1

本人因为公司遗留问题,为了解决识别错误的问题。尝试过yolo12进行目标检测。初步测试良好但是是halcon的socket通信不行。故而去测试halcon 的deeplearn。自己标注数据。 注: 这个软件使用非常无脑。推荐没有基础的人去用 语义分割 以下是halcon的调用模型 *读取模型 read_dl_…

从零开始的python学习(五)P75+P76+P77+P78+P79+P80

本文章记录观看B站python教程学习笔记和实践感悟&#xff0c;视频链接&#xff1a;【花了2万多买的Python教程全套&#xff0c;现在分享给大家&#xff0c;入门到精通(Python全栈开发教程)】 https://www.bilibili.com/video/BV1wD4y1o7AS/?p6&share_sourcecopy_web&v…