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文件,就加载不了了。

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

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

相关文章

五类数据容器对比总结 知道喔!

五类数据容器对比总结 1.五类数据容器的区别 是否支持下标索引 支持:列表、元组、字符串---序列类型 不支持:集合、字典---非序列类型 是否支持重复元素 支持:列表、元组、字符串---序列类型 不支持:集合、字典---非序列类型 是…

Ray Tracing in one Weekend But on CUDA

Ray Tracing in one Weekend But on CUDA 环境说明项目代码项目内容思路实现方法效果 环境说明 代码运行在Visual Studio 2019环境,显卡为NVIDIA GeForce GTX 1650,CUDA版本为11.6,cuDNN版本为8.4.0。具体配置方式见CUDA C/C 从入门到入土 第…

所有人都可以做的副业兼职,短剧推广,1天挣几百,附详细方法!

自从上次向大家介绍了短剧掘金项目以来,便陆续收到了众多朋友的询问:现在是否还能加入短剧掘金的大军?答案是肯定的。目前,无论是各大视频平台还是其他渠道,短剧掘金项目都呈现出蓬勃发展的态势。而且,相关…

Seq2Seq模型:详述其发展历程、深远影响与结构深度剖析

Seq2Seq(Sequence-to-Sequence)模型是一种深度学习架构,专为处理从一个输入序列到一个输出序列的映射任务设计。这种模型最初应用于机器翻译任务,但因其灵活性和有效性,现已被广泛应用于自然语言处理(NLP&a…

PageHelper多数据源无法自动切换数据源问题解决

在使用PageHelper进行分页处理的过程中,通过配置autoRuntimeDialect: true发现,在执行MySQL分页处理后,继续执行SqlServer的分页,使用的仍然是MySQL的语法,PageHelper并没有进行自动切换数据源处理。 在查看源码的时候…

Kaggle线上零售 CRM分析(RFM+BG-NBD+生存分析+PySpark)

数据集地址:数据集地址 我的NoteBook地址:NoteBook地址 这个此在线零售数据集包含2009年12月1日至2011年12月9日期间的在线零售的所有交易。该公司主要销售独特的各种场合礼品。这家公司的许多客户都是批发商。本文将通过pyspark对数据进行导入与预处理&…

TVS管的功率计算与选型

“选择多大功率的TVS管才算合适?”。关于TVS功率的选择,不晓得之前你考虑过没。反正我这边是感觉网上关于TVS管参数、选型等文章比较多,但关于TVS管功率计算及功率选型的文章比较少。但往往在这些点上更能体现面试者的功力。 研究过TVS规格书…

9-Django项目--验证码操作

目录 templates/login/login.html utils/code.py views/login.py 验证码 生成验证码 code.py 应用验证码 views.py login.html templates/login/login.html {% load static %} <!DOCTYPE html> <html lang"en"> <head><meta charset&q…

Polar Web【简单】login

Polar Web【简单】login 本文旨在记录此题的探索和解决过程。 Contents Polar Web【简单】login探索&思路EXP (python)结果&总结 探索&思路 查看源码&#xff0c;发现存在用户信息泄露。尝试用获取信息登录&#xff0c;显示成功&#xff0c;但其后没有可做的操作。…

【力扣】不相交的线

一、题目描述 二、题目解析 根据上图及题目给出的示例&#xff0c;我们不难发现&#xff0c;我们其实要找的就是两个数组中的最长公共子序列的长度。 因此&#xff0c;本题我们就可以直接转化为求两个数组中的最长公共子序列的长度。 对于 最长公共子序列问题&#xff0c;可…

Java Socket 网络编程实例(阻塞IO、非阻塞IO、多路复用Selector、AIO)

文章目录 1. 概述2. TCP 阻塞式IO 网络编程实例2.1 TCP网络编程服务端2.2 ByteBufferUtil2.3 客户端代码2.4 运行截图 3. TCP 非阻塞式IO 网络编程实例3.1 服务端3.2 客户端3.3 运行截图 4. 多路复用4.1 服务器端4.2 客户端4.3 运行截图 5. AIO5.1 AIO 服务端5.2 客户端5.3 运行…

【Python】Python异步编程

Python 异步编程 异步编程 异步编程是一种编程范式&#xff0c;通过非阻塞的方式执行任务&#xff0c;允许程序在等待某些操作&#xff08;如I/O操作、网络请求、数据库查询等&#xff09;完成时&#xff0c;继续执行其他任务。这与同步编程&#xff08;或阻塞编程&#xff09…

【图像处理与机器视觉】XJTU期末考点

题型 选择&#xff1a;1 分10 填空&#xff1a;1 分15 简答题&#xff08;也含有计算和画图&#xff09;&#xff1a;10 分*4 计算题&#xff1a;15 分20 分 考点 选择题&#xff08;部分&#xff09; 数字图像处理基础 p(x,y),q(s,t)两个像素之间的距离由公式&#xff1a…

知乎x-zse-96、x-zse-81

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章未…

GraphQL(2):使用express和GraphQL编写helloworld

1 安装express、graphql以及express-graphql 在项目的目录下运行一下命令。 npm init -y npm install express graphql express-graphql -S 2 新建helloworld.js 代码如下&#xff1a; const express require(express); const {buildSchema} require(graphql); const grap…

spring mvc 中怎样定位到请求调用的controller

前言 在java web开发过程中&#xff0c;正常情况下controller都是我们自己写的&#xff0c;我们可以很方便的定位到controller的位置。但是有些时候我们引入的其他依赖中可能也有controller&#xff0c;为了找到并方便的调试jar包中的controller&#xff0c;我们一般会进行全局…

基于Java的零食管理系统的设计与实现(论文+源码)_kaic

摘 要 随着科技的进步&#xff0c;以及网络的普及&#xff0c;都为人们的生活提供了极大的方便。因此&#xff0c;在管理”三姆”宿舍在线零食商店时&#xff0c;与现代的网络联系起来是非常必要的&#xff0c;本次设计的系统在研发过程中应用到了Java技术&#xff0c;这在一定…

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…

现代信号处理12_谱估计的4种方法(CSDN_20240602)

Slepian Spectral Estimator(1950) 做谱估计的目标是尽可能看清楚信号功率谱在某一个频率上的情况&#xff0c;假设我们想了解零频时的分布&#xff0c;最理想的情况是滤波器的传递函数H(ω) 是一个冲激函数&#xff0c;这样就没有旁瓣&#xff0c;也就没有泄漏&#xff1b;其次…

回溯算法 -- 216. 组合总和 III

目录 一.题目描述 二.解题思路 三.回溯三部曲 3.1确定递归函数的参数 3.2确认递归的终止条件 3.3确定单层循环逻辑 四.具体的代码 一.题目描述 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返…