使用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]…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...


