pdb文件名称被修改导致pdb文件加载失败的实战排查案例分享

目录

1、概述

2、问题说明

3、pdb文件加载失败的可能原因有哪些?

4、使用!sym noisy打开pdb加载详情,发现pdb文件名称确实被修改了

5、Windbg是如何知道要加载pdb文件名称的?


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       最近技群一朋友在使用Windbg分析软件异常时遇到问题,pdb文件与二进制文件的版本(时间戳)明明是一致的,但Windbg就是加载不了pdb文件。于是找到我,让我帮他看看到底是怎么回事。本文大概地讲述一下这个pdb文件加载失败问题的排查过程,以供借鉴或参考。

1、概述

       我们用Windbg排查软件异常时,无论是静态分析dump文件,还是动态调试目标进程,如果要查看详细的函数调用堆栈(比如具体的函数名、代码的行号等),就需要加载堆栈中相关模块的pdb文件,需要使用到pdb文件中的函数、变量等符号信息。

       pdb(Program Database)文件是Windows平台用于存储程序调试信息的文件格式,pdb文件中包含了编译后的可执行文件或动态链接库的符号表、源代码文件路径、局部变量和全局变量的信息等。pdb文件通常与对应的可执行文件(如.exe或.dll)一起使用,以支持程序的调试和分析。

       pdb文件的主要特点和作用:

1)符号表信息:pdb文件包含了编译后的程序的符号表信息,包括函数名、类名、结构体名、变量名等。这些符号信息可以帮助调试器在调试过程中准确地定位和查看变量的值、函数的调用关系等。
2)源代码文件路径:pdb文件记录了源代码文件的路径信息,这使得调试器能够在需要时自动加载对应的源代码文件,以便开发人员在调试过程中查看和修改源代码。
3)局部变量和全局变量信息:pdb文件还包含了局部变量和全局变量的信息,包括变量名、类型和内存地址等。这些信息对于调试器来说很重要,它们使得开发人员可以在调试过程中查看和修改变量的值,有助于分析程序中的问题。
4)回溯栈信息:pdb文件中还包含了堆栈帧和函数调用关系的信息,这对于调试器来说非常重要。通过pdb文件,调试器可以在堆栈回溯时准确地还原函数调用的顺序,帮助开发人员理解程序的执行流程。

       pdb文件是Microsoft开发工具链(如Visual Studio)生成的调试信息文件。在进行程序的调试和分析时,通常需要将pdb文件与对应的可执行文件一起使用。调试器(比如Visual Studio、Windbg等)会根据pdb文件中存放的函数符号及变量符号等信息,来展示变量值、源代码行号、函数调用堆栈等相关信息,以供调试使用。

       我们使用Windbg分析软件异常时,有时不仅要查看详细的函数调用堆栈信息,甚至还需要查看相关变量的值,这些都需要使用到pdb文件中的函数及变量的符号。

2、问题说明

       已经获取了包含异常上下文的dump文件,并拿来了exe主程序及对应时间点的pdb文件,如下所示:(dump文件比较大,是手动导出的全dump文件)

但用Windbg打开dump文件并给Windbg设置pdb路径后,一直加载不了exe主程序的pdb文件,使用.reload强制加载pdb文件也不行。

       用Windbg打开dump文件,并设置pdb的路径,查看函数调用堆栈,如下所示:

但在堆栈中始终看不到主程序Phaseye_12_01.exe模块中的具体函数应该是Phaseye_12_01.exe对应的pdb没有加载起来。pdb文件路径已经设置到Windbg中了,为啥加载不起来呢?于是尝试使用.reload /f Phaseye_12_01.exe命令去强制加载pdb,还是加载不了。

分析问题时,主要通过查看异常发生时的函数调用堆栈,去对照着源代码进行分析的,所以详细的函数调用的堆栈很重要(比如可以看到具体的函数名和代码的行号)。

       使用lm vm Phaseye_12_01*,可以查看到其pdb文件确实没加载起来:

我再三和朋友确认,Phaseye_12_01.pdb和主程序Phaseye_12_01.exe是匹配的,是同个时间点,这就奇怪了,为啥加载不起来呢?难道pdb文件被修改过?朋友说这些模块是其他同事负责维护的,pdb文件名称应该没有修改过的。


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

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

C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931

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

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

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

专栏2: 

C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战经验为基础,总结并讲解一些的C/C++基础与进阶内容,以图文并茂的方式对C++相关知识点进行详细地展开与剖析!专栏涉及了C/C++开发领域多个方面的内容,同时给出C/C++及网络方面的常见笔试面试题,并详细讲述Visual Studio常用调试手段与技巧!

专栏3: 

VC++常用功能开发汇总icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585

专栏将10多年C++开发实践中常用的功能,以高质量的代码展现出来,并对相关功能的实现细节进行了详细的说明。这些常用的代码,其质量与稳定性是有保证的,可以直接拿过去使用,可以有效地解决C++软件开发过程中遇到的问题。


3、pdb文件加载失败的可能原因有哪些?

        pdb文件加载失败可能是以下某个原因导致的:

1)没有设置正确的pdb文件路径
没有将pdb文件路径设置到Windbg中,或者设置了错误的pdb文件路径。

2)pdb文件的时间戳与二进制文件不一致
pdb文件的时间戳和对应的二进制文件(dll或exe文件)不一致,即pdb文件和二进制文件不是同一个时间点生成的。加载pdb文件时,会严格校验pdb文件的时间戳,必须要和对应的二进制文件完全一致。即便代码没修改过,不同时间点编译的pdb文件,也是不能交叉使用的。

3)pdb文件名称不能修改
在Visual Studio的工程属性中,默认配置了生成pdb文件的,pdb文件的名称默认就是工程名称。在QT Creator中编译的程序,也可以配置生成pdb文件。这些pdb生成时,会自动将pdb文件的名称写到对应的二进制文件中:


后面Windbg去根据写入的pdb名称去加载pdb文件的。一旦pdb文件生成了,其名称是不能人为修改的,人为修改后会导致pdb文件无法加载的。

4、使用!sym noisy打开pdb加载详情,发现pdb文件名称确实被修改了

       执行.reload /f Phaseye-12-01.exe命令去强制加载Phaseye-12-01.exe的pdb文件,提示加载失败:

提示可以使用!sym noisy命令打开pdb加载详情,看看搜索加载pdb的完整过程。

       于是输入!sym noisy命令打开详情开关,再次输入.reload /f Phaseye-12-01.exe命令去强制加载pdb,看到详细加载过程:

突然看到了一个关键线索,Windbg要加载的pdb名称是Phaseye.pdb,而不是当前的Phaseye_12_01.pdb,由此确定pdb文件名称肯定是被修改过了。于是手动将pdb名称由Phaseye_12_01.pdb改成Phaseye.pdb,重新去执行.reload强制加载命令,加载成功了!

        使用lm vm Phaseye_12_01*查看,看到了加载的pdb路径,如下所示:

再次使用kn命令查看函数调用堆栈,看到了Phaseye-12-01.exe模块的具体函数名和代码行号了:

所以下次遇到不确定pdb文件是否被修改时,可以直接使用!sym noisy命令打开加载详情,然后使用.reload命令去强制加载,看看Windbg加载的pdb名称即可。

5、Windbg是如何知道要加载pdb文件名称的?

       Windbg加载pdb文件时,是如何知道呀加载的pdb文件名称的呢?无论是使用Visual Studio,还是QT Creator,亦或是其他的IDE开发工具,都可以配置生成pdb文件,比如Visual Studio编译时默认生成pdb文件的。也可以不使用默认名称,可以在工程属性配置中指定pdb名称。

        IDE在编译代码时,会自动将对应的pdb文件名称写到生成的dll或exe二进制文件中,比如:

而Windbg正是通过读取二进制文件中写入的pdb名称去加载对应名称的pdb的。

        pdb名称可以在编译配置中指定(在工程属性或者编译脚本中指定),但不能在pdb文件生成后再去修改pdb文件的名称。如果修改了,Windbg就找不到pdb文件,就加载不了了。

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

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

相关文章

【html】如何给桌面设置渐变背景,通过HTML代码实现

录制的步骤 可以执行以下操作: 查看录制的步骤以幻灯片放映形式查看录制的步骤查看其他详细信息步骤 下一页 步 1: (‎2024/‎6/‎2 16:32:49) 用户在"项目视图 (列表)"上右键单击(在"G:\背景"中) 对于此步骤,没有保存任何屏幕截图。 上一个 下一页 步 …

linux进程加载和启动过程分析

我们的源代码通过预处理,编译,汇编,链接后形成可执行文件,那么当我们在终端敲下指令$ ./a.out argv1 argv2 后,操作系统是怎么将我们的可执行文件加载并运行的呢? 首先知道,计算机的操作系统的启动程序是写死在硬件上的,每次计算机上电时,都将自动加载启动程序,之后…

Java面试题:请对比synchronized和Lock接口,说明它们的优缺点和适用场景

synchronized关键字和java.util.concurrent.locks.Lock接口都是Java中用于实现线程同步的手段。它们在很多方面有相似之处,但也有一些关键的区别。以下是它们之间的对比: synchronized 优点: 使用简单:使用synchronized关键字可…

Spring Bean Request作用域:深入解析与实战洞察

1. 引言 在Spring框架中,Bean的作用域(Scope)定义了Bean的生命周期和可见性。其中,Request作用域是专为Web应用设计的,它在每个HTTP请求的生命周期内提供一个全新的Bean实例。理解Request作用域的工作机制及其背后的源…

翻译《The Old New Thing》- What a drag: Dragging a Uniform Resource Locator (URL)

What a drag: Dragging a Uniform Resource Locator (URL) - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080312-00/?p23133 Raymond Chen 2008年03月12日 麻烦的拖拽:拖拽统一资源定位符(URL) 简要 …

C++多态-联编

静态联编 静态联编支持的多态性,我们将其称为编译时的多态性,又称为静态的多态性,因为联编的过程是在程序开始执行之前进行的。在编译、连接的过程中,系统可以根据类型匹配等特征确定程序中调用与具体执行函数的关系,…

MySQL入门学习-查询进阶.分页查询

在 MySQL 中,分页查询是一种用于在查询结果中获取特定页面数据的技术。它通常用于处理大量数据的情况,以便将结果分为多个页面进行显示或处理。 以下是关于分页查询的一些关键概念和特点: 1. 分页查询的特点: - 数据量控制&…

识别同一用户

识别来自同一终端的访问技术 使用HTTP访问Web服务器时,会反复地执行页面的迁移和图像的读取等通信处理。而不同的通信都是使用不同的方式进行处理。因此服务器端就不需要对每个终端的状态进行单独的管理,可以降低服务器的负载。 另外,…

python安装phonopy教程

Phonopy 是一个用于计算材料晶格动力学性质的 Python 包。它可以用于计算声子频率、声子态密度、热力学性质等。 安装 Phonopy 步骤 1: 安装依赖项 首先,确保你已经安装了 Python 和 pip。然后,安装一些必要的依赖项: pip install numpy scipy matplotlibPhonopy 还依赖于…

AndroidStudio编译很慢问题解决

如果gradle同步、编译下载很慢,可以换一下仓库阿里云镜像 repositories {maven { url https://maven.aliyun.com/repository/google } maven { url https://maven.aliyun.com/repository/jcenter } maven { url https://maven.aliyun.com/repository/public } goog…

Java(十二)---认识异常

文章目录 前言1. 异常的概念与体系结构1.1.异常的概念1.异常的体系1.3 异常的分类 2. 异常的处理2.1 防御式编程2.2 异常的抛出2.3 异常的捕获2.3.1 异常声明throws2.3.2 try-catch捕获并处理2.3.3 finally 2.4 异常的处理流程 3. 自定义异常类 前言 这一篇就是咱们学习JavaSE…

让SDWebImage加载webp格式的图片

感谢大佬 iOS 加载webp格式的图片 pod "SDWebImage/WebP"报错的解决办法 - 简书 pod SDWebImageWebPCoder 导入文件&#xff1a; #import <SDWebImage/SDWebImage.h> #import <SDWebImageWebPCoder/SDWebImageWebPCoder.h> 实现&#xff1a;这个可以…

C++ : 模板初阶

标题&#xff1a;C : 模板初阶 水墨不写bug 正文开始&#xff1a; C语言的问题 &#xff1a; 写不完的swap函数 在学习C语言时&#xff0c;我们有一个经常使用的函数swap函数&#xff0c;它可以将两个对象的值交换。 我们通常这样实现它&#xff1a; void swap(int t1,int t…

【vue实战项目】通用管理系统:作业列表

目录 目录 1.前言 2.后端API 3.前端API 4.组件 5.分页 6.封装组件 1.前言 本文是博主前端Vue实战系列中的一篇文章&#xff0c;本系列将会带大家一起从0开始一步步完整的做完一个小项目&#xff0c;让你找到Vue实战的技巧和感觉。 专栏地址&#xff1a; https://blog…

300价值与300成长指数

300价值指数&#xff0c;看的是价值因子。价值因子包含四个变量:股息收益率&#xff0c;每股净资产与价格比率&#xff0c;每股净现金流与价格比率&#xff0c;每股收益与价格比率 根据这四个变量对沪深300指数的成份股进行打分&#xff0c;得分高的前100名&#xff0c;就纳入…

安卓Launcher启动详解

目录 一、概述1.1 核心源码1.2 主要代码作用 二、源码分析2.1 第一阶段SystemServer 启动HomeActivity的调用阶段2.2 [RootActivityContainer.java] startHomeOnDisplay()2.2.1 [ActivityTaskManagerService.java] getHomeIntent()2.2.2 [RootActivityContainer.java] resolveH…

uni-app解决表格uni-table样式问题

一、如何让表格文字只显示一行&#xff0c;超出部分用省略号表示 步骤 &#xff1a; 给table设置table-layout:fixed; 列宽由表格宽度和列宽度设定。&#xff08;默认是由单元格内容设定&#xff09;让表格元素继承父元素宽度固定table-layout: inherit;overflow: hidden;超过…

list的简单模拟实现

文章目录 目录 文章目录 前言 一、使用list时的注意事项 1.list不支持std库中的sort排序 2.去重操作 3.splice拼接 二、list的接口实现 1.源码中的节点 2.源码中的构造函数 3.哨兵位头节点 4.尾插和头插 5.迭代器* 5.1 迭代器中的operator和-- 5.2其他迭代器中的接口 5.3迭代器…

【气象常用】剖面图

效果图&#xff1a; 主要步骤&#xff1a; 1. 数据准备&#xff1a;我用的era5的散度数据&#xff08;大家替换为自己的就好啦&#xff0c;era5数据下载方法可以看这里【数据下载】ERA5 各高度层月平均数据下载_era5月平均数据-CSDN博客&#xff09; 2. 数据处理&#xff1a…

windows10系统64位安装delphiXE11.2完整教程

windows10系统64位安装delphiXE11.2完整教程 https://altd.embarcadero.com/download/radstudio/11.0/radstudio_11_106491a.iso XE11.1 https://altd.embarcadero.com/download/radstudio/11.0/RADStudio_11_2_10937a.iso XE11.2 关键使用文件在以下内容&#xff1a;windows10…