使用Process Explorer和Dependency Walker排查程序启动时缺少ucrtbase.dll等运行时库以及报0xC000007B错误

news2024/11/24 5:49:19

目录

1、问题描述

2、分析软件问题的常用分析工具

3、使用Dependency Walker排查启动程序时报找不到ucrtbase.dll、vcruntime140.dll等运行时库的问题

3.1、使用Dependency Walker查看exe程序的库依赖关系,排查找不到ucrtbase.dll、vcruntime140.dll库问题

3.2、C/C++运行时库介绍

3.3、发布版本时除了要带上Visual Studio的C/C++运行时库,最好带上系统的通用运行时库(the Universal CRT)

4、拷贝缺少的dll库到出问题的机器上,但启动时报0xC000007B错误

5、使用Process Explorer工具在开发人员的机器上查看缺少库的路径

6、最后


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_2276111.html        最近一个同事在运行他们开发的一个工具软件时软件始终启动不起来,先是启动时报找不到ucrtbase.dll、vcruntime140.dll等运行时库的问题,接着启动时又报0xC000007B的错误,于是用Dependency Walker和Process Explorer两个工具帮同事大概地分析了一下,很快定位了问题。今天详细讲一下这一软件启动失败问题的排查过程,也通过这个案例详细地介绍一下如何使用Dependency Walker和Process Explorer这两个工具。此外,也重点讲述一下发布软件版本时C/C++运行时库及系统通用时库部署问题。

1、问题描述

       某天,硬件研发中心的一个负责自动化测试开发的同事找到我,让我帮他们排查个问题。他们使用Visual Studio 2017开发的一个工具软件,拿到硬件生产线上的同事的电脑上运行,软件始终运行不起来,启动时老是报错。先是启动时报找不到ucrtbase.dll、vcruntime140.dll等运行时库:

 接着启动时又报0xC000007B错误:

他们折腾一天了,始终没找出问题,所以让我帮他们看一下到底是怎么回事。

       同事说,软件在他们开发机器上是能正常运行的,但在生产线的同事电脑上就是运行报错。他们是自动化测试部门的,不是专业做软件开发的,对这类问题不太了解。其实对于我们做软件开发的来讲,这类问题很简单,使用下面方法能快速找到问题:

1)直接在有问题的机器上运行Dependency Walker工具,查看缺少哪些dll库;
2)在开发机器上运行Process Explorer(开发机器上可以正常运行),查看软件加载的这些在问题机器上缺少的dll库在开发机器上的路径,然后将这些缺少的dll库拷贝到问题机器上就可以了。

       这类问题很多初学者或者刚参加工作的朋友,可能也会遇到,可能也搞不清楚怎么回事(当然这类问题对开发老司机来说肯定很easy!),所以通过这篇文章给这类朋友系统地普及一下,以供参考。

2、分析软件问题的常用分析工具

       此处有必要再给大家强调一下日常工作中常用的一些软件分析工具!之前我在讲C++软件调试技术时,经常讲我们需要熟练使用一些常用的软件分析工具,比如:

1)查看二进制文件时间戳等PE工具;
2)查看窗口信息的SPY++工具;
3)查看模块依赖库关系的Dependency Walker工具;
4)查看进程加载模块信息、查看进程中线程信息的Process Explorer工具;
5)监测进程的文件读写活动和注册表读写活动的Process Monitor工具;
6)监测对系统API或第三方API接口调用情况的API Monitor;
7)用来分析GDI函数绘制窗口时的GDI对象泄漏问题的GDIView;
8)用来模拟弱网环境的Clumsy工具;
9)用来分析C++软件异常崩溃的Windbg调试器(静态分析dump文件或动态调试目标进程);
10)用来查看二进制文件汇编代码的反汇编工具IDA。

熟练掌握这些工具的使用,能够快速地辅助分析C++软件运行过程中遇到的多种问题,能够有效地提高排查问题和处理问题的效率。

       我之前专门写了一篇关于这些工具的文章,可以去查看:
C++软件开发值得推荐的十大高效软件分析工具icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/127608247还把日常工作中使用这些工具处理项目中遇到的问题案例整理出来,形成了一个叫做《C++软件分析工具案例集锦》的专栏,旨在通过这些项目中的实战案例,教大家如何巧妙地使用这些工具并熟练掌握这些工具的使用!专栏地址如下:

C++软件分析工具案例集锦icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12279968.html       对于本案例中的问题,之前也有和这个同事简单地交流过,建议他们用Dependency Walker和Process Explorer这两个工具去分析一下。其实这两个工具很简单,但他们没用过,不知道如何去使用它们去分析问题。

上面讲到的多种工具除了Windbg和IDA比较复杂之外,基本都比较简单实用,很容易入门上手,所以建议大家多琢磨琢磨,或者跟着我的文章学一学,尽量把这些工具用到自己的工作实践中去。用的多了,就熟练了,就能更加巧妙地去应用了!

       其实,很多工具最开始我也不会用,也都是跟着其他同事后面学的。无论对技术还是对工具,要保持足够的好奇心,想要尝试去像其他同事那样去熟练的使用,去高效的排查问题!工具学会了,就是自己的技能了!好奇心有时是一种源源不断的动力!

3、使用Dependency Walker排查启动程序时报找不到ucrtbase.dll、vcruntime140.dll等运行时库的问题

       最开始同事将程序拷贝到出问题的电脑上,双击启动即弹出找不到ucrtbase.dll的提示,程序启动失败。其实这个问题很简单,使用Dependency Walker查看exe程序的库依赖关系便知。

3.1、使用Dependency Walker查看exe程序的库依赖关系,排查找不到ucrtbase.dll、vcruntime140.dll库问题

        Dependency Walker工具可以直接到其官网上下载。启动Dependency Walker,将exe程序文件拖入到Dependency Walker中,然后等待Dependency Walker解析出依赖关系。

这个地方注意一下,可能Dependency Walker版本太老,对Win10系统兼容性不好,Dependency Walker打开文件可能需要等上好几分钟才行。这个也没办法,将文件拖入后,就去干其他事情,然后过一会来查看即可。

       以缺少vcruntime140.dll为例,使用Dependency Walker打开主程序,如下:

Dependency Walker默认会展开所有节点,需要将根节点下的子节点都折叠起来,然后主要关注应用层的dll库(非系统库)。图中显示黄色感叹号的以API-MS开头的库都是系统库,一般我们不需要去关注,我们只需要去关注ucrtbase.dll、vcruntime140.dll、msvcp100.dll、mcvcr100.dll等运时库。将系统库折叠起来后,如下所示:

看到exe程序在问题机器上找不到vcruntime140.dll。这个库是VS2017版本引入的一个新的C运行时库。

       系统在启动exe程序时,系统会读取exe文件中的PE信息,查看exe所依赖的dll库,在加载exe主程序(进入main函数)之前,会优先将exe主程序依赖的所有的dll文件加载到进程空间中。在加载dll库时,会优先到exe程序所在的目录中去搜索查找;如果找不到,则会到系统路径C:\Windows\System32或C:\Windows\SysWOW64中去查找;如果还找不到,应该就找不到了,就会报系统中找不到dll库的弹框。

3.2、C/C++运行时库介绍

        我们代码中调用的很多C/C++基本库函数都位于C/C++运行时库中,比如abort、system、strlen、strcpy等运行时库函数。一般运行时库是以msvcr(C运行时库)或msvcp(C++运行时库)开头的。不同版本的Visual Studio携带的C/C++运行时dll库的版本可能也不一样,这些运行时库一般要打包到安装程序中,安装时要拷贝到exe主程序的安装目录中。

       关于不同版本的Visual Studio对应的运行时库版本,很多人可能分不清楚,会有疑惑,这里详细给大家介绍一下:(以d结尾的是Debug版本的运行时库)

1)VS2010对应的运行时库文件(对应100版本):msvcp100.dll(msvcp100d.dll)、msvcr100.dll(msvcr100d.dll);
2)VS2012对应的运行时库文件(对应110版本):msvcp110.dll(msvcp110d.dll)、msvcr110.dll(msvcr110d.dll);
3)VS2013对应的运行时库文件(对应120版本):msvcp120.dll(msvcp120d.dll)、msvcr120.dll(msvcr120d.dll);
4)VS2017对应的运行时库文件(对应140版本):msvcp140.dll(msvcp120d.dll)、ucrtbase.dll(ucrtbased.dll)、vcruntime140.dll(vcruntime140d.dll); (VS2017引入了两个新库ucrtbase.dll、vcruntime140.dll,不再有msvcr140.dll库,只保留了msvcp140.dll库)

       以msvcp110.dll文件,在文件属性中可以看到其对应的版本为VS2012,如下所示:

对于上述运行时库相关内容,大家可以简单了解一下。

3.3、发布版本时除了要带上Visual Studio的C/C++运行时库,最好带上系统的通用运行时库(the Universal CRT)

       几年前,我们还在用Visual Studio 2010开发程序,底层有个库是用VS2017编译的,结果将程序拿到某些电脑上运行,会报如下的错误:

后来到网上搜索得知,使用VS2017开发的程序不仅要依赖Visual Studio自带的C/C++运行时库,还要依赖以“api-ms-win”开头的系统通用运行时库(the Universal CRT,而有些电脑上的系统运行时库不全或者版本不对,导致程序启动报错,就像这个截图一样。

       所以在发布大型程序时,要带上这些系统通用运行时库,这些系统运行时库都放在程序的安装目录中,比如我们在腾讯会议的安装目录中能看到自带的系统运行时库:

        我们在发布产品时如何找到这些库呢?我们可以到Windbg安装中去找,比如我机器上的安装Windbg的路径为C:\Program Files (x86)\Windows Kits\10\Debuggers,我们可以到上级目录C:\Program Files (x86)\Windows Kits中以api-ms为关键字搜索,可以找到相关的路径:

以x86版本为例,打开可以看到这些系统运行时库:

可以根据自己程序的位数去选择拷贝对应版本的系统运行时库。

       关于如何获取这些以“api-ms-win”开头的the Universal CRT系统通用运行时库,有人在微软的技术论坛中反馈过,如下:
Missing API DLL API STUB Set for Windowsicon-default.png?t=N7T8https://social.technet.microsoft.com/Forums/windows/en-US/327da89c-9d1c-4dca-9371-9771eabc3df9/missing-api-dll-api-stub-set-for-windows?forum=win10itprogeneral其中有人回复,可以参照这篇文章中的说明:
Introducing the Universal CRTicon-default.png?t=N7T8https://devblogs.microsoft.com/cppblog/introducing-the-universal-crt/其中下面一段话讲到了如何去获取the Universal CRT系统通用运行时库,如下所示:

之前我机器上安装过Windbg(使用Windows SDK包安装的),所以在我机器上可以找到这个路径。

       发布由VS2017及以上Visual Studio版本编译出来的软件版本时,要带上系统通用运行时库(the Universal CRT,将这些dll库放置在程序安装目录中。还需要带上C/C++运行时库,对于C/C++运行时库,有两种处理办法,一种是直接将依赖的运行时库打包到安装包中,安装时拷贝到程序安装目录中;一种是使用微软官方提供的Microsoft Visual C++ 发行程序包VC_redist.x86.exe / VC_redist.x64.exe(要找编译程序的Visual Studio版本对应的VC_redist.x86.exe / VC_redist.x64.exe版本),在执行安装包安装时自动安装VC_redist.x86.exe / VC_redist.x64.exe,一般是安装到系统路径下。

         关于Microsoft Visual C++ 发行程序包VC_redist.x86.exe / VC_redist.x64.exe详细说明及下载地址,可以参见我之前写的文章:

下载最新版 VC_redist.x86.exe / VC_redist.x64.exe for Visual Studio 2015, 2017, 2019, and 2022icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131451865

4、拷贝缺少的dll库到出问题的机器上,但启动时报0xC000007B错误

       为啥程序在开发同事的机器上运行没问题,在生产线同事的机器上运行有问题呢?因为在开发人员的机器上安装了Visual Studio IDE开发工具,在安装Visual Studio时会自动将C/C++运行时库拷贝到系统路径C:\Windows\System32(64位库拷贝到该目录中)和C:\Windows\SysWOW64(32位库拷贝到该目录中)中,所以在开发人员的电脑上运行程序,能搜索到运行时库,所以能正常运行!

       上面通过Dependency Walker已经确定缺少哪几个库,于是同事手动从其开发的电脑上将这几个库拷贝到出问题的电脑上(拷贝到exe程序的所在目录中),重新启动程序,结果报0xC000007B的错误如下:

这个报0xC000007B错误的问题,我之前排查过,还整理成了文章,如下:
C++程序启动时报“0xC000007B”无法启动的问题排查icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/126298265这个0xC000007B错误,对应的标识为STATUS_INVALID_IMAGE_FORMAT,即无效的二进制文件格式:

最终原因是,手动拷贝的几个库是64位的,而我们的exe程序是32位的,64位模块是不能和32位混用的,混用的话就会报0xC000007B错误的。

        现在基本用的都是Win10版本的Windows系统,Win10系统都是64位的,天然支持运行64位程序,也支持运行32程序。为了支持32程序的运行,还专门搞了个C:\Windows\SysWOW64目录,目录中存放的是32位系统库,供32位程序使用。对于64程序,则使用C:\Windows\System32目录中的系统库。

我们在编写代码时,涉及到系统路径时,没必要指定是C:\Windows\System32目录还是C:\Windows\SysWOW64目录,操作系统会根据程序的位数重定向到对应的路径中。

5、使用Process Explorer工具在开发人员的机器上查看缺少库的路径

       为什么会拷贝64位系统库呢?我估计他们可能是直接使用Everything工具直接搜索ucrtbase.dll、vcruntime140.dll等文件,如下所示:

同事手动拷贝的是C:\Windows\System32路径中的这些库,这些库是64位的,而我们的exe程序是32位的,所以不匹配报错了!

       有时,大家可能不知道到底该拷贝哪个路径下的运行时库,有个很简便的方法。直接在能运行的开发人员的电脑上,运行Process Explorer,在进程列表中找到我们的程序,点击选中,在下方的列表中就会显示加载的dll库列表,如下:

找到目标dll库,查看其路径,到路径中拷贝即可。

如果是第一次使用Process Explorer工具,要查看进程加载的dll库列表,需要点击工具栏中的“View DLLs”图标按钮:

         当然,Process Explorer工具远不止这点功能,其他功能,可以参考我其他的文章:
使用Process Explorer和Dependency Walker排查C++程序中dll库动态加载失败问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/130198751使用Process Explorer和Clumsy工具定位软件高CPU占用问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/130038272

6、最后

        这次正好借同事遇到的这个问题实例,给大家讲讲如何使用Dependency Walker和Process Explorer来处理这类问题,以供大家借鉴或参考。这类问题其实比较简单,只要会使用这两个工具很快就能排查出来,对初学者或者刚参加工作的朋友,有一定的参考价值。

       虽然本例中的问题比较简单,但涉及到的一些细节点还是有一定价值的,建议大家详细阅读一下!

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

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

相关文章

指针的含义、表示、规范、存储、运用

指针的含义、表示、规范、存储、运用 指针的含义指针的表示指针的规范先声明再定义声明和定义一起表示错误表示 指针的存储理解一个变量的存储过程和原理理解一个指针的存储过程和原理理解多个指针的存储过程和原理 指针的运用 指针的含义 表示某个变量或数据所在的内存地址 注…

大模型笔记 【1】 大模型初探

以下是Andrej Karpathy一小时讲解chatgpt的笔记。 Andrej Karpathy做自动驾驶的人应该比较熟悉,他是李飞飞的学生。在openAI做了一年半的科学家之后,去了特斯拉。在Tesla AI day讲解tesla自动驾驶方案的就是他。 这里我的主要收获是两个 大模型是一个有…

12V 全桥驱动芯片GC9008——可替代TMI8118,应用于摄像机、消费类产品上

GC9008 是一款 12V 全桥驱动芯片,为提供高性价比的方案。它能提供 0.1A 的持续输出电流。可以工作在 4.5~15V 的电源电压上。 具有 PWM(IN1/IN2)输入接口,与行业标准器件兼容.是 SOP8封装,GC9008D是DIP封装芯片特点 ● H 桥电机驱…

关于burpsuite对app(移动端)进行抓包的配置

可以使用手机模拟器,我这里以自己手机(物理机)演示配置过程 如果是使用的模拟器那么肯定和电脑是在同一局域网 如果使用物理机,那么可以通过连接同一WiFi确保在同一局域网环境下 查看电脑内网ip:192.168.1.105 &am…

2023 年精选:ChatGPT 会取代开发者吗?

由于最近发布了ChatGPT,人工智能再次热闹起来,ChatGPT 是一种自然语言聊天机器人,人们用它来写电子邮件、诗歌、歌词和大学论文。早期采用者甚至用它来编写Python 代码,以及对 shellcode 进行逆向工程并用 C 重写。ChatGPT 给那些…

Docker实战09|使用AUFS包装busybox

前几篇文章中,重点讲解了如何实现构建容器,需要回顾的小伙伴可以看以下文章: 《Docker实战06|深入剖析Docker Run命令》《Docker实战07|Docker增加容器资源限制》《Docker实战08|Docker管道及环境变量识别…

1879_什么是丝印

Grey 全部学习内容汇总: GitHub - GreyZhang/g_hardware_basic: You should learn some hardware design knowledge in case hardware engineer would ask you to prove your software is right when their hardware design is wrong! 1873_什么是丝印 丝印这个词…

Android平板浏览器远程Ubuntu服务器使用code-server编程写代码

文章目录 1.ubuntu本地安装code-server2. 安装cpolar内网穿透3. 创建隧道映射本地端口4. 安卓平板测试访问5.固定域名公网地址6.结语 1.ubuntu本地安装code-server 准备一台虚拟机,Ubuntu或者centos都可以,这里以VMwhere ubuntu系统为例 下载code server服务,浏览器…

我在工作一年时怎么都看不懂的编程写法。今天手把手教给你

作为一名程序员,你一定遇到或亲自写过这样的代码。有人将它形象的形容为shi山,或者被戏称为“面向保就业编程”。 以下面这个代码为例,其中的问题也显而易见,当越来越多的条件判断时,代码会变得非常臃肿,难…

记录汇川:H5U与Fctory IO测试5

主程序: 子程序: IO映射 子程序: 自动程序 Fctory IO配置: 触摸屏如下: 实际动作如下: Fctory IO测试5

mybatis plus相同Id与xml配置错误时,mybatis plus解决逻辑

前言 处理做项目的问题,其中不乏奇奇怪怪的问题,其中mybatis plus的问题感觉有点隐蔽,有些是运行时出现,有些是运行到具体的逻辑触发,对于应用的状态监控提出了极大的挑战,应用的状态由健康检查接口提供&a…

VMware复制粘贴共享文件夹

win和虚拟机之间,无法复制粘贴,共享文件夹的解决方案。 安装VMware tools 1,先检查虚拟机设置部分。共享文件夹已启用。复制粘贴已启用。 2,安装tools.选择重新安装VMware tools. (此图片为安装过的截图) 成功后会显示如图。…

【Python书籍】字节大佬爆肝整理的Python背记手册最佳入门书籍,刷爆这本书你的Python就牛了!

前言: 现今有很多人都想学习Python,但是不乏有一些英语不好和非计算机专业的小伙伴,在最基础入门阶段会跟不上被甩在身后,就是在知识点的理解方面有所缺失,对于计算机的运算,计算机语言,计算机…

家政服务系统有哪些优势及特点

🌈家政系统小程序,有哪些功能优势! 1、平台依托:🌍小程序极速开发。 2、人员保障:顾客轻松注册,家政服务人员也有独立账号。 3、地域无忧:后台自定义开放城市范围。🌟 4、…

MySQL决战:MySQL数据导入导出

目录 前言 一.navact数据导入导出(第三方工具) 1.导入数据 2.数据导出 二. mysqldump命令导入导出数据 1.mysqldump介绍 2.数据导出 3.数据导入 三.load data file进行数据导入导出(只限于单表) 1.数据导出 增加导出权…

SpringCloud系列篇:核心组件之网关组件

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于SpringCloud的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 一.网关组件是什么 二. 网关组件的…

C++学习笔记——string类和new函数

目录 string类 1.功能增强 1.1 子字符串提取 1.2 字符串拼接 1.3 大小写转换 1.4 字符串比较 2.性能优化 3.使用示例 下面是一个简单的使用示例,展示了如何使用改进后的String类: NEW函数 2.1NEW函数的基本用法 2.2NEW函数的注意事项 2.3避…

大数据毕业设计:图书推荐系统+可视化+Django框架 图书管理系统 (附源码+论文)✅

毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏) 毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总 🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题&#xff…

Vue3插件开发教程:步步指导如何编写Vue3插件

关注⬆️⬆️⬆️⬆️ 专栏后期更新更多前端内容 文章目录 Vue3 插件插件注册形式插件主要的场景使用插件Vue3 插件 插件 (Plugins) 是一种能为 Vue 添加全局功能的工具代码。 插件注册形式 一个插件可以是一个拥有 install() 方法的对象,也可以直接是一个安装函数本身。 i…

数 据 分 析 1

1.使用Wireshark查看并分析靶机桌面下的capture.pcapng数据包文件,找到黑客的IP地址,并将黑客的IP地址作为Flag值(如:172.16.1.1)提交;172.16.1.41 查找:tcp.connection.syn 2.继续分析captu…