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

目录

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       本文的问题排查起来比较简单,但有一定的代表性,对于开发新手或者不会使用工具的人,有较大的参考价值!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python设计模式 - 建造者模式

定义 建造者模式是一种创建型设计模式,主要用于构建包含多个组成部分的复杂对象。它将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的对象表示。 结构 抽象建造者(Builder):声明创建产品的各个部件的方…

sparkTTS window 安装

SparkTTS 的简介 Spark-TTS是一种基于SpardAudio团队提出的 BiCodec 构建的新系统,BiCodec 是一种单流语音编解码器,可将语音策略性地分解为两种互补的标记类型:用于语言内容的低比特率语义标记和用于说话者特定属性的固定长度全局标记。这种…

高效微调算法 (Parameter-Efficient Fine-tuning, PEFT) 详解

引言 随着预训练语言模型 (Pre-trained Language Models, PLMs) 规模的持续膨胀,全参数微调 (Full Fine-tuning) 模式的局限性日益凸显。 全参数微调在下游任务上取得了显著的性能提升,但其高昂的计算和存储成本,以及为每个下游任务维护完整…

第十五届蓝桥杯大学B组(握手问题、小球反弹、好数)

一、握手问题 思路1&#xff1a; 1)先让所有人相互握手 第一个人49次 第二个人48次 第五十个人0次 共计01249 2)减去7个没握手的 016 #include<stdio.h> int main() {int a 50*49/2 - 7*6/2;printf("%d\n",a);return 0; } 运行结果&#xf…

若依框架-给sys_user表添加新字段并获取当前登录用户的该字段值

目录 添加字段 修改SysUser类 修改SysUserMapper.xml 修改user.js 前端获取字段值 添加字段 若依框架的sys_user表是没有age字段的&#xff0c;但由于业务需求&#xff0c;我需要新添加一个age字段&#xff1a; 修改SysUser类 添加age字段后&#xff0c;要在SysUser类 …

基于langchain+llama2的本地私有大语言模型实战

Langchain功能 LangChian 作为一个大语言模型&#xff08;LLM, Large Language Model&#xff09;开发框架&#xff0c;是 LLM 应用架构的重要一环。借助 LangChain&#xff0c;我们可以创建各种应用程序&#xff0c;包括聊天机器人和智能问答工具。 AI模型&#xff1a;包含各…

再聊 Flutter Riverpod ,注解模式下的 Riverpod 有什么特别之处,还有发展方向

三年前我们通过 《Flutter Riverpod 全面深入解析》 深入理解了 riverpod 的内部实现&#xff0c;而时隔三年之后&#xff0c;如今Riverpod 的主流模式已经是注解&#xff0c;那今天就让我们来聊聊 riverpod 的注解有什么特殊之处。 前言 在此之前&#xff0c;我们需要先回忆…

uniapp+Vue3 组件之间的传值方法

一、父子传值&#xff08;props / $emit 、ref / $refs&#xff09; 1、props / $emit 父组件通过 props 向子组件传递数据&#xff0c;子组件通过 $emit 触发事件向父组件传递数据。 父组件&#xff1a; // 父组件中<template><view class"container">…

Kafka×DeepSeek:智能决策破取经八十一难!

《西游记》的故事中&#xff0c;唐僧师徒四人历经九九八十一难&#xff0c;从东土大唐前往西天取经。一路上&#xff0c;火焰山酷热难耐、通天河水位忽高忽低、妖怪神出鬼没…… 现在&#xff0c;唐僧师徒取经路上的种种难题&#xff0c;在KafkaDeepSeek双引擎加持下有了全新解…

C# 委托使用详解

总目录 前言 在C#中&#xff0c;委托&#xff08;Delegate&#xff09; 是一种类型安全的函数指针机制&#xff0c;它允许我们将方法作为参数传递给其他方法&#xff0c;或者将方法存储在变量中。委托在 C# 中有广泛的应用&#xff0c;特别是在事件处理、异步编程和回调机制中…

axure11安装教程包含下载、安装、汉化、授权(附安装包)图文详细教程

文章目录 前言一、axure11安装包下载二、axure11安装教程1.启动安装程序2.安装向导界面3.安装协议协议页面2.选择安装位置3.开始安装4.完成安装 三、axure11汉化教程1.axure11汉化包2.axure11汉化设置 四、axure11授权教程1.打开axure112.设置使用方式3.输入许可证号4.axure11安…

如何使用Opentelemetry+jaeger对Go与Java项目实现分布式链路追踪

本文介绍![如何使用Opentelemetryjaeger实现分布式链路追踪] 关于opentelemetry的介绍可以看下面的文章 https://blog.csdn.net/qq_62368250/article/details/143516314本文中相关图片以及源代码地址 https://github.com/wuchenyanghaoshuai/others/blob/main/step39/README.…

【数据分享】2001-2024年我国逐年植被净初级生产力(NPP)数据

植被净初级生产力&#xff08;Net Primary Productivity&#xff0c;NPP&#xff09;是生态学中的一个重要概念&#xff0c;表示单位面积植被在特定时间内吸收的净光合有机物&#xff0c;是衡量生态系统中植物通过光合作用所产生的有机物质减去植物呼吸作用消耗的有机物质的量&…

靶场(七)---靶场精做小白思考

启程&#xff1a; 先扫一遍全端口发现&#xff0c;有很多tcp端口全部被关闭了&#xff0c;于是我又去看看他们的udp端口&#xff0c;发现也是半死不活的样子&#xff0c;那没办法只能把udp端口当作备选方案&#xff08;其实这个udp什么用都没有就是关闭的状态不用关&#xff0…

Linux开发工具----vim

目录 Linux编辑器-vim使用 1. vim的基本概念 正常/普通/命令模式(Normal mode) 插入模式(Insert mode) 底行模式(last line mode) 2. vim的基本操作 3. vim正常模式命令集 4. vim底行模式命令集 5. vim操作总结 (本篇文章相当于vim常用命令字典) Linux编辑器-vim使用 我们先来看…

【设计模式】设计模式的分类与组织

文章目录 前言一、设计模式的分类1. 目的准则2. 范围准则 二、设计模式的细分1.创建型模式的细分2.结构型模式的细分3.行为型模式的细分 三、设计模式的关联结论 前言 在软件开发中&#xff0c;设计模式是一种解决特定问题的最佳实践。由于设计模式种类繁多&#xff0c;理解它…

Vue3实战学习(Element-Plus常用组件的使用(输入框、下拉框、单选框多选框、el-image图片))(上)(5)

目录 一、Vue3工程环境配置、项目基础脚手架搭建、Vue3基础语法、Vue3集成Element-Plus的详细教程。(博客链接如下) 二、Element-Plus常用组件使用。 &#xff08;1&#xff09;el-input。(input输入框) <1>正常状态的el-input。 <2>el-input的disable状态。 <3…

AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘

AttributeError: module backend_interagg has no attribute FigureCanvas 这个错误通常是由于 Matplotlib 的后端配置问题引起的。具体来说&#xff0c;Matplotlib 在尝试加载某个后端时&#xff0c;发现该后端模块中缺少必要的属性&#xff08;如 FigureCanvas&#xff09;&a…

网络安全基础与应用习题 网络安全基础答案

1.列出并简要给出SSH的定义。 正确答案&#xff1a; 答&#xff1a;6.10传输层协议&#xff1a;提供服务器身份验证、数据保密性和数据完整性&#xff0c;并具有前向保密性&#xff08;即&#xff0c;如果在一个会话期间密钥被破坏&#xff0c;则知识不会影响早期会话的安全性&…

文件上传复现

1、什么是文件上传漏洞&#xff1f; 答&#xff1a;文件上传漏洞是指攻击者通过上传恶意文件到服务器、从而执行任意代码、获取系统权限或者破坏系统安全的漏洞、常见于允许用户上传文件的Web应用程序中。 2. 文件上传漏洞形成原因 未验证文件类型&#xff1a;未对上传文件的…