哪些软件分析工具需要使用到pdb符号文件?

目录

1、什么是pdb文件?pdb文件有哪些用途?

2、pdb文件的时间戳与pdb文件名称

3、常用软件分析工具有哪些?

4、使用Windbg调试器查看函数调用堆栈时需要加载pdb文件

4.1、给Windbg设置pdb文件路径

4.2、为什么要设置系统库pdb文件下载服务器地址?

5、使用IDA反汇编工具查看二进制文件的汇编代码时需要加载pdb文件

6、使用Process Explorer查看线程的函数调用堆栈时需要加载pdb文件

7、使用Process Monitor查看函数调用堆栈时需要使用到pdb文件

8、API Monitor可以查看函数调用堆栈,但不支持加载pdb文件

9、最后


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具案例集锦(专栏文章正在更新中...)https://blog.csdn.net/chenlycly/article/details/131405795       日常工作中分析C++软件问题时,有些分析工具是可以查看发生问题时的线程函数调用堆栈,比如Windbg、IDA、Process Explorer/Process Hacker、Process Monitor和API Monitor等。如果要在函数调用堆栈中能看到具体的函数名,甚至代码的行号,则需要加载pdb符号文件。今天我们就来详细讲讲哪些分析工具需要加载pdb符号文件。

1、什么是pdb文件?pdb文件有哪些用途?

       PDB - Program Databse File,程序数据库文件,存放了二进制文件中所有函数及变量的符号,还有一些调试用的信息,要查看完整的函数调用堆栈信息及变量信息,都需要用到pdb文件。pdb文件是在编译C++工程代码时产生的,它是与对应的exe或dll模块一起生成的。

       在Visual Studio中,不管是Debug还是Release下,默认都会生成pdb文件,默认配置如下所示:

本地程序之所以能调试,是因为其二进制文件在本地编译生成时会自动写入对应的pdb文件的绝对路径,而pdb文件中存放着用于调试的各种调试信息。启动调试时调试器会根据二进制文件中记录的pdb文件路径去尝试加载pdb文件,加载成功后,就能获取pdb文件中的调试信息,这样就可以调试了。

如果手动将对应目录中的pdb文件删除,在没有重新生成的情况下,程序肯定是无法调试的!

2、pdb文件的时间戳与pdb文件名称

        在使用pdb文件时,有两点需要注意一下,一个是pdb文件的时间戳,一个是pdb文件的名称。

        加载pdb文件时会严格校验pdb文件的时间戳(就是生成pdb文件的时间),必须要和二进制文件完全一致。即使是同样的代码,没有修改任何代码,在不同时间点编译生成的pdb文件,也是不能交叉使用的。

       pdb文件的名称必须和工程的名称一致,否则也是无法加载的。比如某个工程名称为videocodec_hp.vcxproj,生成的pdb文件的名称默认应为videocodec_hp.pdb(不区分大小写的),但在执行文件拷贝时将文件名称改成videocodec.pdb,这种情况下Windbg也是无法加载的。必须手动将pdb文件的名称改成Visual Studio工程文件的名称后,pdb文件才能正常加载。这个问题我们遇到过几次,就是因为pdb文件名称与工程名称不一致导致pdb加载不起来的。

3、常用软件分析工具有哪些?

       在日常工作中,常用的软件分析工具有PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、DebugDiag、Windbg、IDA等,关于这些工具的详细介绍与说明,可以参见我之前写的文章:

C++软件开发值得推荐的十大高效软件分析工具https://blog.csdn.net/chenlycly/article/details/127608247这些工具中不是都要使用pdb,一般可以查看函数调用堆栈的,都要使用到pdb文件。Process Explorer、Process Monitor、DebugDiag、Windbg和IDA需要使用到,下面就来详细讲述一下。

4、使用Windbg调试器查看函数调用堆栈时需要加载pdb文件

       Windbg分析软件异常有两种方式,一种是静态分析dump文件,一种是动态调试目标进程。一般都需要在Windbg中查看发生异常时的函数调用堆栈,然后将函数调用堆栈与C++源码对照起来看,去分析软件异常。

       但光看到函数调用堆栈是不够的,需要在堆栈中看到具体的函数名,甚至代码行号,这样才好去分析问题。如果没有pdb文件,则堆栈中显示的是相对模块(起始地址)的偏移,或者相对于模块导出函数的偏移(模块的导出函数符号是公开的,外部是可见的),一般看不到真实具体的函数名。要看到包含具体函数名和代码行号的函数调用堆栈,则需要加载相关dll或exe二进制文件的pdb符号文件。通过pdb文件中包含的函数及变量的符号,去显示更为详细的函数调用堆栈。

4.1、给Windbg设置pdb文件路径

       在未加载pdb文件之前,通过查看函数调用堆栈中的模块名称,然后使用lm命令去查看模块的生成时间戳去找对应时间点的pdb文件。要让Windbg加载pdb文件,则需要将pdb文件所在的路径设置到Windbg中。可以将多个模块的pdb文件统一拷贝到本机的某个文件夹中,然后在Windbg菜单栏中点击File -> Symbol File Path...,会打开设置pdb文件路径的窗口:

将pdb文件路径设置给Windbg。

        一般我们设置如下格式的pdb文件路径组合:

C:\Users\Administrator\Desktop\pdbdir;srv*f:\mss0616*http://msdl.microsoft.com/download/symbols

这个一长串组合路径主要由下面两个路径构成:(多个路径之间使用分号隔开)

1)应用程序库的pdb文件路径(非系统库):
C:\Users\Administrator\Desktop\pdbdir。我们将相关开发模块的pdb文件集中拷贝到该路径中,然后将路径设置进来。多个pdb文件也可以放在不同路径下,可以设置多个路径,路径之间使用分号隔开。
2)Windows系统库的pdb文件在线下载地址
srv*f:\mss0616*http://msdl.microsoft.com/download/symbols,其中http://msdl.microsoft.com/download/symbols,是微软提供的在线系统pdb文件下载服务器。如果设置了该地址,Windbg会自动连接该服务器,去自动下载与当前dump文件中用到的系统库版本一致的pdb文件。另外,f:\mss0616路径是从微软pdb文件服务器上下载下来的pdb文件的存放路径。

4.2、为什么要设置系统库pdb文件下载服务器地址?

       设置系统库的pdb文件下载服务器地址,是为了让Windbg自动去下载Windows系统库的pdb文件,并自动将系统库的pdb文件加载进去。加载系统库的pdb符号库文件之后,不仅能看到具体的系统接口的调用,甚至还可以看到更多行的函数调用:

看到的可能是更多的系统层函数的调用记录,也可能是更多的应用层函数的调用记录。有时能直接从具体的系统函数调用接口中能得到一定的线索。另外,看到更多行的函数调用,可能更有利于快速定位发生崩溃的具体位置。

       关于设置系统库pdb下载地址去看到更多函数调用堆栈的典型问题实例,可以参见我之前写的一篇文章:
播放WebRTC开源库回调出来的视频码流时遇到的内存越界问题排查https://blog.csdn.net/chenlycly/article/details/131222627       此外,这里有个细节需要注意一下,有时微软这个服务器会有连接不上或卡顿的情况,会直接导致Windbg卡顿,这个问题我们之前遇到过很多次。所以遇到Windbg严重卡顿的时候,可以先将该服务器下载地址删除掉。但有时我们需要设置该在线地址,因为有时我们想去看到底是调用了系统库中的哪个接口触发的崩溃。

5、使用IDA反汇编工具查看二进制文件的汇编代码时需要加载pdb文件

       有时我们需要使用IDA反汇编工具去查看二进制文件的汇编代码上下文,去辅助分析C++软件异常问题。在分析问题时,要看懂汇编代码的片段或者上下文,需要将汇编代码和程序源码对应起来,但直接查看汇编很难和程序关联起来。所以在查看汇编代码时,需要和C++源码对照着看,即通过源码去辅助汇编代码的阅读。但C++代码在编译时,Release下编译器会对代码进行优化,有些代码会被优化掉,所以C++源码很难完全和汇编代码对应起来。

关于编译器优化的例子,比如C++源码中有个函数调用(调用了某个函数),编译器在编译时为了避免函数调用的开销(传递的参数要入栈出栈,要保护现场和恢复现场),直接将函数调用给优化掉,使用几句汇编代码将函数调用替换掉了。

       正因为汇编代码很难完全和C++源码对应起来,我们希望借助其他信息去将对应关系找出来。如果没有pdb文件,IDA中显示的汇编代码看不到具体的函数及变量信息,一般较难去直接阅读汇编代码上下文,是需要很强的汇编功底才行。

       如果IDA加载了当前二进制文件的pdb文件后,汇编代码中会显示具体的函数及变量信息,还会在汇编代码中额外添加一些注释,比如:

有了这些信息,阅读汇编代码上下文会显得容易很多,能够较容易地将汇编代码与C++源码对应起来。如果有pdb文件,只要将pdb文件放在二进制文件的同级目录中,这样在Windbg打开二进制文件时会自动到二进制文件所在的目录中去搜索,搜索到即会自动去加载pdb文件。

       也可以到IDA的安装路径下找到cfg文件夹,在该文件夹中找到pdb.cfg配置文件,在配置文件中设置pdb路径,不过这个操作略显麻烦,没有直接放到安装路径下简单。

6、使用Process Explorer查看线程的函数调用堆栈时需要加载pdb文件

       在使用Process Explorer工具排查程序CPU占用高的问题时,在Process Explorer显示的进程列表中双击目标进程,在打开的进程属性窗口中点击Threads标签页,切换到进程的线程列表页面,就能看到进程中的所有线程信息,找到那个CPU占用高的线程:

双击查看该线程的函数调用堆栈,然后根据函数调用堆栈去查看C++源码,去分析为什么会占用较高的CPU。如果没有pdb文件,显示出来的函数调用堆栈中看不到具体的函数名,看不到具体的函数名就没法去做跟踪分析了

       此时如何去查看相关模块的pdb文件呢?此时没用Windbg,所以没法使用Windb的lm命令去查看二进制模块的时间戳,那如何获取去获取二进制文件的时间戳呢?直接查看文件属性中的修改时间是不靠谱的,它只代表系统中该文件的修改时间,和文件的编译生成时间没关系的。其实很简单,我们只要下载个PE工具,然后将二进制文件拖入到PE工具中即可查看文件的生成时间戳,如下所示:

然后通过该时间戳找到二进制模块对应时间点的pdb文件。

        只要将pdb文件放在对应模块所在的文件夹中,Process Explorer就会自动去搜索加载的。当然也可以在Process Explorer中配置pdb文件的路径,点击Process Explorer菜单栏中的Options -> Configure Symbols...,打开如下的配置窗口:

配置pdb文件的路径即可。

7、使用Process Monitor查看函数调用堆栈时需要使用到pdb文件

        Process Monitor主要用来监测目标进程的注册表活动和文件活动的,如果监测到要监测的条目,双击即可查看执行注册表或文件操作的函数调用堆栈,通过函数调用堆栈就可以知道是哪个函数操作了注册表或文件了。

       涉及到显示线程的函数调用堆栈,就需要pdb文件,否则函数调用堆栈中就看不到具体的函数名,看不到具体的函数就较难定位问题的。与Process Explorer工具类似,pdb文件可以直接放置在二进制模块所在的文件夹中,Process Monitor会自动去搜索并加载。

       Process Monitor中也支持设置pdb文件路径,点击Process Monitor菜单栏中的Options -> Configure Symbols...,打开配置pdb文件路径的窗口,如下所示:

默认已经将微软系统库pdb下载地址设置进去了,如果要新增路径,以分号隔开就好了。

8、API Monitor可以查看函数调用堆栈,但不支持加载pdb文件

       API Monitor主要用来监测目标进程对系统API函数或者第三方库接口的调用情况。在监测到调用记录时,在call stack窗口中会显示所在线程的调用堆栈,默认只显示5条:

可以点击API Monitor菜单栏中的Tools -> Options...,在打开的Options配置窗口中点击Monitoring按钮,进入对应的标签页,如下所示:

在页面中可以配置显示函数调用堆栈的条目个数,好像最多只显示15个。

       有函数调用堆栈的地方,为了查看更详细的函数调用堆栈,需要pdb文件,但不幸的是,API Monitor不支持加载pdb文件,所以也就没有设置pdb文件路径的入口。其实这类监测接口调用的场景,函数调用堆栈的作用不大,我们只关注是否调用了接口,调用接口时传递了哪些参数。

9、最后

       本文详细介绍了Windbg、IDA、Process Explorer和Process Monitor等工具使用pdb的场景,希望能给大家提供一些借鉴和参考。

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

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

相关文章

【JAVA】生成视频缩略图并上传至Minio

需求 (1)使用照片墙方式将图片上传到Minio (2)将上传的图片生成缩略图 (3)将缩略图上传到Minio 目的:节省空间、避免图片过多加载不出来 Java端 (1)pom.xml引入依赖 &…

华为OD机试真题 Java 实现【查找树中元素】【2023 B卷 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、补充说明五、Java算法源码六、效果展示1、输入2、输出 一、题目描述 已知树形结构的所有节点信息,现要求根据输入坐标(x,y)找到该节点保存的内容值; 其中: x表示节点…

VSCode中打开NodeJS项目自动切换对应版本的配置

这几年搞了不少静态站点,有的是Hexo的,有的是VuePress的。由于不同的主题对于NodeJS的版本要求不同,所以本机上不少NodeJS的版本。 关于如何管理多个NodeJS版本,很早之前就写过用nvm来管理的相关文章,这里就不赘述了&a…

迁移学习入门,新手该如何下手?

推荐迁移学习技术的实用入门图书:《自然语言处理迁移学习实战》 [加纳] 保罗阿祖雷(Paul Azunre) 著,李想,朱仲书,张世武 译 一本书带你读懂ChatGPT背后的技术,自然语言处理迁移学习,解锁机器学…

WiFi 时钟+本地温度

[ WiFi 时钟 ] [ WiFi 天气时钟 ] [ WiFi 时钟本地温度 ] 夏天到了,显示器上放一个时钟,顺便实时测量本地室温,看看空调工作是否正常也算是个实用制作。 用到零件共 4 个: 400孔面包板 ( 大号…

RabbitMQ系列(29)--RabbitMQ搭建Shovel

前言: Federation具备的数据转发功能类似,Shovel能够可靠、持续地从一个Broker中的队列(作为源端,即source)拉取数据并转发至另一个Broker中的交换器(作为目的端,即destination)。作为源端的队列和作为目的端的交换器可以同时位于…

windows设置右键一键打开文件的配置

在安装软件时一般通过msi或者exe安装,这是一般会有提示绑定到鼠标右键,如果没有勾选则安装后就无法通过右键打开,这是需要把文件拖到快捷方式上面才可以使用该软件打开。 另外如何下载的是zip的压缩包源码格式根本没有设置的选项&#xff0c…

MySQL数据库——表操作的练习

题目一 (1) mysql> create database Market; (2) mysql> use Market; Database changed mysql> create table customers(->c_num INT(11) primary key auto_increment,->c_name varchar(50),->c_contact varcha…

45. 跳跃游戏 II (贪心)

题目链接:力扣 解题思路:贪心,尽可能地找到下一跳能够跳到的最远距离,这样到达终点时,所需跳跃次数最少 以nums [2,3,1,1,4,2]为例: 以当前位置begin作为起跳点,能够跳跃的最远距离为m&#…

B067-基础环境-抽取Basegit

目录 抽取base抽取domain和querymapper接口抽取service抽取 Git优点:Git安装及操作Git Bash命令行操作图形化客户端TortoiseGit操作Git集成Idea操作idea会把workspace作为本地仓库gitee操作idea解决代码冲突 抽取base 抽取domain和query domain:所有实体…

抖音seo矩阵源码*开发搭建*代码打包部署(开源)分享

1一、 抖音seo矩阵源码开发搭建(支持二开)概述 抖音SEO矩阵指的是一系列通过搜索引擎优化(SEO)技术和策略来提升抖音账号在搜索结果中排名的方法和工具。在抖音上,用户可以通过搜索关键词来查找与其相关的视频和账号…

Oracle-奇怪的expdp备份报错LPX-00217

问题背景: 接用户报障,数据库每天晚上正常的expdp备份,从2天前开始出现奇怪的备份报错LPX-00217: invalid character 3 问题分析: 检查expdp备份的日志,从2天前晚上开始的备份均出现LPX-00217: invalid character 3的报错,报错均…