使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错问题
目录
1、问题说明
2、问题分析思路
3、问题分析过程
3.1、使用Dependency Walker打开软件主程序,查看库与库的依赖关系,查看出问题的库
3.2、使用PE工具查看dll库的时间戳
3.3、解决办法
4、最后
VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)
https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)
https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_11931267.html开源组件及数据库技术(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_2276111.html 安装了新版本的安装包之后,启动程序时会报错,导致程序启动失败。这是日常工作中比较常见的一类问题,本文详细讲述如何使用PE信息查看工具和Dependency Walker工具去分析这类问题的完整过程,给大家提供一个借鉴或参考。
1、问题说明
测试同事安装新版本的安装包之后,一启动程序就会报错,弹出如下的报错提示框:
导致程序启动失败。提示无法在xxsysctrldll.dll库中找不到InitMtDsc接口,这是一类比较常见的问题,一般都是因为主程序中有dll库的版本不一致引起的。比如A.dll依赖了B.dll库,出现接口找不到的问题,可能的原因有:
1)B.dll中的function接口不存在或者已经被删除了。比如老版本的A.dll和新版本的B.dll混在一起使用,老版本A.dll调用了function接口,但该接口在新版本的B.dll中已经删除或者已经更改名称了,所以会出现找不到接口的问题。比如新版本的A.dll和老版本的B.dll混在一起使用,新版本的A.dll调用了新版本的B.dll中新增的接口,但当前软件打包的还是老版本的B.dll,所以程序运行时在老版本B.dll中找不到接口。
2)B.dll中的function接口参数修改了。C++中支持函数重载(函数名称一样,但参数不一样),在编译时默认情况下会对函数名称进行改编,在生成的函数符号中融入了参数信息,比如上面截图中的 ?lnitMtDsc@@YAXGH@Z。
在B.dll中的function接口还在,但是参数修改了,函数符号发生了变化,所以找不到了。
在这里,给大家重点推荐一下我的几个热门畅销专栏:
专栏1:(该专栏订阅量接近350个,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!)
C++软件调试与异常排查从入门到精通系列文章汇总https://blog.csdn.net/chenlycly/article/details/125529931
本专栏根据近几年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的实战问题分析实例,带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!
专栏中的文章均是通过项目实战总结出来的(通过项目实战积累了大量的异常排查素材和案例),有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!
专栏2:
C/C++基础与进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html
以多年的开发实战为基础,总结并讲解一些的C/C++基础与进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域的多个方面的内容,同时给出C/C++及网络方面的常见笔试面试题,并详细讲述Visual Studio常用调试手段与技巧!
专栏3:
开源组件及数据库技术https://blog.csdn.net/chenlycly/category_12458859.html
以多年的开发实战为基础,分享一些开源组件及数据库技术!
2、问题分析思路
对于上述这类问题,基本就是库的版本不一致导致的,具体是哪个库的版本有问题,我们使用PE信息查看工具和Dependency Walker工具就能快速排查出来。
先使用Dependency Walker打开exe主程序,查看库与库的依赖关系,比如:
确定问题出在哪些个库中,同时可以进一步的确定是找不到库,还是调用的接口在目标dll库中找不到,亦或是要调用的接口在目标dll库中修改了参数。
然后使用PE信息查看工具打开出问题的dll库文件,查看库文件的时间戳,比如:
即库文件(二进制文件)的编译生成时间,这样我们就能确定到底是哪个库的版本不对了。
另外,在这个分析过程中,我们可能需要在svn或git上查看库文件的发布记录,和相关模块开发维护团队确认库与库之间的版本对应关系。
3、问题分析过程
3.1、使用Dependency Walker打开软件主程序,查看库与库的依赖关系,查看出问题的库
首先我们使用Dependency Walker打开软件的exe主程序,查看库与库之间的依赖关系,看看问题具体出在哪些库中。
Dependency Walker打开exe主程序后,会以树状结构将exe主程序依赖的库以及这些库依赖的其他库展示出来。默认情况下,会自动将树中的节点全部展开。
注意一下,当前最新的Dependency Walker还是2016年的,当运行在Win10等新的系统中时,打开文件可能会比较慢,甚至要等好几分钟才能打开完成。要稍微耐心等待一下。
在展开的树中,节点太多,除了软件的业务库,还包含大量的Windows系统库,为了方便查看,我们可以将系统库的节点给折叠起来。这就要求我们要识别出来哪些库是系统库,比如常见的user32.dll、ntdll.dll、kernel32.dll,还有以API-MS-WIN开头的系统库:
这对于经常搞Windows软件开发的人很简单,但对于新手或者不熟悉Windows软件开发的人来说,可能很难分辨
在Dependency Walker中,如果库找不到或者库中的接口有问题,问题节点前面会显示特别的异常图标:
1)在运行的机器中找不到某个库,会在该库的节点前显示一个黄色的问号图标,如下所示:
这可能是打包软件时,没有将程序依赖的库打包进安装包中。比如忘记将一个新增的dll库打包到安装包中、没有将运行时库打包到安装包中。注意,不同版本的Visual Studio使用的运行时库名称是不一样的,比如Visual Studio 2010的运行时库是msvcr100.dll和msvcp100.dll,Visual Studio 2017的运行时库是msvcp140.dll、vcruntime140.dll和ucrtbase.dll(不再有msvcr140.dll、新增了vcruntime140.dll和ucrtbase.dll)。
使用Visual Studio编译出来的程序,在打安装包时都需要把对应版本的运行时库打包进去。关于不同Visual Studio版本对应的运行时库的详细说明,可以参见我的文章:使用Dependency Walker和Process Explorer排查程序启动时缺少ucrtbase.dll等运行时库以及报0xC000007B错误
https://blog.csdn.net/chenlycly/article/details/131505299此外,很多系统库节点前面也会显示一个黄色的问号图标,这些系统库一般可以忽略掉,不用管。
2)在某个库中找不到调用的接口,会在对应的接口行前面显示一个红色的图标,如下所示:
可能这个接口在库中已经不存在了(被删除了),也可能是接口的参数修改了,生成的函数符号变了。
在本案例中,最开始启动程序报错的截图如下:
从这个截图可以看出,问题与xxsysctrldll.dll库有关。用Dependency Walker打开exe主程序后,显示出问题的两个库的截图如下所示:
首先看到xxsysctrldll.dll依赖了xxdscdll.dll,之所以依赖,肯定是xxsysctrldll.dll库中调用了xxdscdll.dll库中的接口。然后我们看到xxdscdll.dll节点前面有淡红色的异常图标,所以我们点击xxdscdll.dll节点,此时右边实现两块信息,上面PI部分是依赖该库的xxsysctrldll.dll从该库中引入了哪些接口,即xxsysctrldll.dll库中调用了xxdscdll.dll库中的那些接口;下面的E部分,是当前xxdscdll.dll库有哪些导出接口。
关于导出导入,对于dll动态库本身,接口是导出的,是要提供给其他库调用的;对于使用到该库的其他库,需要引入当前库的接口,然后调用这些接口的。一般可以使用#import导入dll库对应的.lib库,比如#pragma comment( lib, "winmm.lib" ) ,这个是在编译链接时会用到,如果找不到调用的接口符号,则会编译报错。接口的运行调用则时发生在程序运行阶段的。
看到导入列表中的接口?InitMtDsc@@YAXGH@Z(这是经过编译器名称改编后的函数名称,带了参数信息)所在行前面显示了红色的图标,应该是该接口符号,在当前的xxdscdll.dll中没有。可以翻看下方的xxdscdll.dll的导出函数列表,看看xxdscdll.dll有没有导出InitMtDsc接口。在xxdscdll.dll导出接口的列表中确实找到了InitMtDsc接口,但包含了参数信息的改编后的名称是不一样的,即?InitMtDsc@@YAXG@Z,所以应该是该接口的参数修改了。
目前可以确定是xxdscdll.dll与xxsysctrldll.dll两个库不匹配,但具体是哪个库有问题,还是看这两个库的时间戳(库的编译生成时间)。
3.2、使用PE工具查看dll库的时间戳
此时我还要使用到PeViewer PE信息查看工具。打开PeViewer工具,点击打开按钮,找到xxdscdll.dll与xxsysctrldll.dll文件的路径,打开文件查看到文件的时间戳:(点击左侧列表中的头部 -> NT头 -> 文件头,右侧就会显示文件的时间戳)
从上图中可以看到,xxdscdll.dll库的时间戳为2023/12/07[04:29:53],xxsysctrldll.dll库的时间戳为2023/12/15[15:29:37]。
我这边经常使用的PE信息查看工具叫PeViewer,以前排查问题时,用该工具打开64位二进制文件发生了闪退。后来在网上搜到了MiTeC EXE Explorer工具,这个工具兼容性比较好,打开64位二进制文件没有问题。大家后面遇到问题时,可以使用更强大的MiTeC EXE Explorer。
最近底层的组件有多个模块有改动,12月15日有发布新库过来,查看了svn上的发布记录:
发布说明中提及到的发布模块中有提到xxdscdll模块和xxsysctrldll模块,但实际上并没有发布库文件xxdscdll.dll,xxsysctrldll.dll库文件发布过来了。所以结合上面的PE工具查看的时间戳,xxsysctrldll.dll是最新版本,但xxdscdll.dll是老版本。
那明明发布说明中指出要发布xxdscdll模块过来,为啥没发布成功呢?先到文件服务器上查看编译日志,看看是不是xxdscdll模块代码编译失败了。经查看,xxdscdll模块编译没有错误的,文件有生成的。于是找了一下配置管理员,他查看了一下发布模块配置,发现了问题:
在配置发布模块xxdsc的名称时,错误地将xxdscdll.dll写成了xxdssdll.dll(将dsc写成dss),导致了自动执行发布脚本时没有拷贝xxdscdll.dll到指定产品的代码流上。
3.3、解决办法
所以在该问题场景中,新版本的xxsysctrldll.dll使用了老版本的xxdscdll.dll,新版本的xxsysctrldll.dll调用了新版本的xxdscdll.dll中的InitMtDsc接口,在新版本的xxdscdll.dll中修改了InitMtDsc接口的参数,即新版本的xxdscdll.dll调用了修改参数后的InitMtDsc接口,所以在老版本的xxdscdll.dll中找不到修改参数后的InitMtDsc接口,所以程序启动时弹出了文章最开始说到的错误提示框:
解决办法很简单,只需要将漏发的xxdscdll.dll文件发布过来就好了。
4、最后
本案例中详细介绍了如何使用PE信息查看工具与Dependency Walker去排查程序启动报错的问题,希望能给大家提供一定的借鉴或参考。
相关文章:

使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错问题
目录 1、问题说明 2、问题分析思路 3、问题分析过程 3.1、使用Dependency Walker打开软件主程序,查看库与库的依赖关系,查看出问题的库 3.2、使用PE工具查看dll库的时间戳 3.3、解决办法 4、最后 VC常用功能开发汇总(专栏文章列表&…...
Python编程题目答疑「Python一对一辅导考试真题解析」
你好,我是悦创。 待会更新~ 更新计划 答案 题目 记得点赞收藏! 题目 之后更新 Solution Question 1 # 读取输入 a float(input("请输入实数 a: ")) b float(input("请输入实数 b: ")) c float(input("请输…...

Python---搭建Python自带静态Web服务器
1. 静态Web服务器是什么? 可以为发出请求的浏览器提供静态文档的程序。 平时我们浏览百度新闻数据的时候,每天的新闻数据都会发生变化,那访问的这个页面就是动态的,而我们开发的是静态的,页面的数据不会发生变化。 …...
在服务器上部署SpringBoot项目jar包
以下是在服务器上部署Spring Boot项目jar包的步骤: 打包项目: 使用IDEA或者命令行工具(如Maven或Gradle)将Spring Boot项目打包为一个可执行的jar文件。如果使用Maven,可以在项目的根目录下运行以下命令来打包项目&…...

[python]python实现对jenkins 的任务触发
目录 关键词平台说明背景一、安装 python-jenkins 库二、code三、运行 Python 脚本四、注意事项 关键词 python、excel、DBC、jenkins 平台说明 项目Valuepython版本3.6 背景 用python实现对jenkins 的任务触发。 一、安装 python-jenkins 库 pip install python-jenkin…...

Python生成圣诞节贺卡-代码案例剖析【第18篇—python圣诞节系列】
文章目录 ❄️Python制作圣诞节贺卡🐬展示效果🌸代码🌴代码剖析 ❄️Python制作圣诞树贺卡🐬展示效果🌸代码🌴代码剖析🌸总结 🎅圣诞节快乐! ❄️Python制作圣诞节贺卡 …...

深度剖析Ajax实现方式(原生框架、JQuery、Axios,Fetch)
Ajax学习 简介: Ajax 代表异步 JavaScript 和 XML(Asynchronous JavaScript and XML)的缩写。它指的是一种在网页开发中使用的技术,通过在后台与服务器进行数据交换,实现页面内容的更新,而无需刷新整个…...

任天堂,steam游戏机通过type-c给VR投屏与PD快速充电的方案 三type-c口投屏转接器
游戏手柄这个概念,最早要追溯到二十年前玩FC游戏的时候,那时候超级玛丽成为了许多人童年里难忘的回忆,虽然长大了才知道超级玛丽是翻译错误,应该是任天堂的超级马里奥,不过这并不影响大家对他的喜爱。 当时FC家用机手柄…...

Flink系列之:Checkpoints 与 Savepoints
Flink系列之:Checkpoints 与 Savepoints 一、概述二、功能和限制 一、概述 从概念上讲,Flink 的 savepoints 与 checkpoints 的不同之处类似于传统数据库系统中的备份与恢复日志之间的差异。 Checkpoints 的主要目的是为意外失败的作业提供恢复机制。 …...

【优质书籍推荐】LoRA微调的技巧和方法
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。…...

Linux一行命令配置jdk环境
使用方法: 压缩包上传 到/opt, 更换命令中对应的jdk包名即可。 注意点:jdk-8u151-linux-x64.tar.gz 解压后名字是jdk1.8.0_151 sudo tar -zxvf jdk-8u151-linux-x64.tar.gz -C /opt && echo export JAVA_HOME/opt/jdk1.8.0_151 | sudo tee -a …...
从0开始刷剑指Offer
剑指Offer题解 剑指 Offer 11. 旋转数组的最小数字 思路: 二分O(logn) class Solution {public int stockManagement(int[] stock) {int l 0;int r stock.length - 1;while(l < r && stock[0] stock[r]) r --;if(stock[r] > stock[l]) return stock[0];whi…...

使用Java语言中的算法输出杨辉三角形
一、算法思想 创建一个名为YanghuiTest的类,然后创建二维数组,然后遍历二维数组的第一层,然后初始化第二层数组的大小,然后遍历第二层数组,然后将两侧的数组元素赋为1,然后其它数值通过公式计算,最后可以输…...

人工智能_机器学习071_SVM支持向量机_人脸识别算法_LFW人脸数据加载_与理解---人工智能工作笔记0111
然后我们继续来看 这里有个lfw_home可以看到这个数据是,包含了人脸数据 然后我们继续看,在我们的顶你用户目录下,如果安装了,sklearn就会有这样一个目录, scikit_learn_data目录,这个里面可以看到 可以看到这个文件夹中有个 lfw_home文件夹是对.zip文件夹的解压,这个下载以后…...
Java 8中流Stream API详解
先给个示例,展示Java 8流API的优势 假设我们有以下任务: 给定一个字符串列表,我们需要执行以下操作: 筛选出所有以"A"开头的字符串。 将这些字符串转换为大写。 对这些字符串按照长度进行排序。 最后,将…...
通过 xlsx 解析上传excel的数据
一、前言 在前端开发中,特别是在后台管理系统中,导入数据(上传excel)到后端是是否常见的功能;而一般的实现方式都是通过接口将excel上传到后端,再有后端进行数据解析并做后续操作。 今天,来记录…...
Flink系列之:JDBC SQL 连接器
Flink系列之:JDBC SQL 连接器 一、JDBC SQL 连接器二、依赖三、创建 JDBC 表四、连接器参数五、键处理六、分区扫描七、Lookup Cache八、幂等写入九、JDBC Catalog十、JDBC Catalog 的使用十一、JDBC Catalog for PostgreSQL十二、JDBC Catalog for MySQL十三、数据…...

OpenCV与YOLO学习与研究指南
引言 OpenCV是一个开源的计算机视觉和机器学习软件库,而YOLO(You Only Look Once)是一个流行的实时对象检测系统。对于大学生和初学者而言,掌握这两项技术将大大提升他们在图像处理和机器视觉领域的能力。 基础知识储备 在深入…...
hive中map相关函数总结
目录 hive官方函数解释示例实战 hive官方函数解释 hive官网函数大全地址: hive官网函数大全地址 Return TypeNameDescriptionmapmap(key1, value1, key2, value2, …)Creates a map with the given key/value pairs.arraymap_values(Map<K.V>)Returns an un…...
HttpServletRequestWrapper、HttpServletResponseWrapper结合 过滤器 实现接口的加解密、国际化
目录 一、HttpServletRequestWrapper代码 二、HttpServletRequestWrapper代码 三、加解密过滤器代码 四、国际化过滤器代码 一、HttpServletRequestWrapper代码 package com.vteam.uap.security.httpWrapper;import jakarta.servlet.ReadListener; import jakarta.servlet.…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...