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

news2024/11/17 9:27:01

目录

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.coloradmin.cn/o/734466.html

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

相关文章

深度剖析线上应用节点流量隔离技术

作者:谢文欣(风敬) 为什么要做流量隔离 源于一个 EDAS 客户遇到的棘手情况:他们线上的一个 Pod CPU 指标异常,为了进一步诊断问题,客户希望在不重建此 Pod 的情况下保留现场,但诊断期间流量还…

Element-UI 实现动态增加多个输入框并校验

文章目录 前言实现通过按钮动态增加表单并验证必填实现动态多个输入框为行内模式,其它为行外模式 前言 在做复杂的动态表单,实现业务动态变动,比如有一条需要动态添加的el-form-item中包含了多个输入框,并实现表单验证&#xff0…

非线性激活函数

目录 理论介绍 常见的激活函数 A. sigmoid函数 B. tanh C.ReLu Leaky Relu 函数 Parametric ReLU (PReLU) Exponential Linear Unit (ELU) 实验结果及分析 理论介绍 在神经网络的计算中,无非就是矩阵相乘,输入的是线性,不论输出层有…

如何修复ssh漏洞进行版本升级

目录 一、ssh低版本漏洞信息 OpenSSH GSSAPI 处理远端代码执行漏洞 OpenSSH GSSAPI认证终止信息泄露漏洞 OpenSSH X连接会话劫持漏洞 二、升级ssh版本进行修复漏洞 第一步 安装Telnet服务 第二步 重启服务 第三步 安装依赖环境 第四步 备份ssh老版本文件 第五步 导入…

【JavaEE进阶】Spring 创建与使用

Spring 创建与使用 1,Spring项目的创建 使用Maven方式来创建一个Spring项目,创建Spring项目和Servlet类似,总共分为以下3步: 创建一个普通Maven项目添加 Spring 框架⽀持(spring-context、spring-beans)添…

UE特效案例 —— 魔法翅膀

一,环境配置 创建默认地形Landscape,如给地形上材质需确定比例;添加环境主光源DirectionalLight,设置相应的强度和颜色;PostProcessVolume设置曝光,设置Min/Max Brightness为1; 与关闭Game Sett…

【二分查找】35. 搜索插入位置

35. 搜索插入位置 解题思路 使用二分查找算法当找到元素之后直接返回位置即可当没找到元素&#xff0c;将该元素插入到left位置即可 class Solution {public int searchInsert(int[] nums, int target) {// 二分查找int left 0;int right nums.length - 1;while(left < …

数组扁平化flat方法的多种实现

flat() let arr [[1],[2, 3],[4, 5, 6, [7, 8, [9, 10, [11]]]],12 ];// 参数指要提取嵌套数组的结构深度&#xff0c;默认值为 1。 // Infinity 指递归嵌套的所有层级。 let flattedArr arr.flat(Infinity); console.log(flattedArr);执行效果&#xff1a; toString() 注意…

FreeRTOS ~(六)信号量 ~ (2/3)信号量解决互斥缺陷

前情提要 FreeRTOS ~&#xff08;四&#xff09;同步互斥与通信 ~ &#xff08;2/3&#xff09;互斥的缺陷 FreeRTOS ~&#xff08;五&#xff09;队列的常规使用 ~ &#xff08;2/5&#xff09;队列解决互斥缺陷 举例子说明&#xff1a;利用信号量解决前述的"互斥的缺陷&…

SQL Server数据库 -- 表的高级查询

文章目录 一、子查询 嵌套子查询相关子查询二、查询运算 并运算union交运算intersect差运算except三、函数的使用 if语句while语句case语句四、总结 前言 高级子查询是对查询更灵活的运用&#xff0c;学会了高级查询将对数据库使用有很大的帮助。 一、子查询 1、子查询简介 在…

MATLAB画等深度构造图

clc;clear;close all; data xlsread(J_UNCONFORMITY等深度.xlsx); x data(:,1) xmax max(x); xmin min(x); y data(:,2) ymax max(y); ymin min(y); z data(:,3); N 45…

天天刷题-->LeetCode(两数相加)

个人名片&#xff1a; &#x1f405;作者简介&#xff1a;一名大二在校生&#xff0c;热爱生活&#xff0c;爱好敲码&#xff01; \ &#x1f485;个人主页 &#x1f947;&#xff1a;holy-wangle ➡系列内容&#xff1a; &#x1f5bc;️ tkinter前端窗口界面创建与优化 &…

MachineLearningWu_7+8_LogisticRegression/Classification

x.1 logistic regression 对于诸如分辨细胞是恶性肿瘤细胞与否的类似分类问题&#xff0c;我们使用Linear Regression的模型并不合适&#xff0c;所以引入Logistic Regression的模型&#xff0c;并绘制decision boundary&#xff0c;如下&#xff0c; Classification的最后一层…

mysql多表查询内连接,左外连接,排序,having

多表连接查询 use mydb3; -- 创建部门表 create table if not exists dept3(deptno varchar(20) primary key , -- 部门号name varchar(20) -- 部门名字 );– 创建员工表 create table if not exists emp3(eid varchar(20) primary key , -- 员工编号ename varchar(20), -- 员…

python接口自动化(二十二)--unittest执行顺序隐藏的坑(详解)

简介 大多数的初学者在使用 unittest 框架时候&#xff0c;不清楚用例的执行顺序到底是怎样的。对测试类里面的类和方法分不清楚&#xff0c;不知道什么时候执行&#xff0c;什么时候不执行。虽然或许通过代码实现了&#xff0c;也是稀里糊涂的一知半解&#xff0c;这样还好&am…

基于深度学习的高精度Caltech行人检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度Caltech数据集行人检测识别系统可用于日常生活中或野外来检测与定位行人目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的行人目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv…

部署HAproxy + Nginx负载均衡集群

目录 一、常规Web集群调度器 HAproxy概念&#xff08;主要特性&#xff09; HAproxy负载均衡八种策略 二、LVS、Nginx、HAproxy区别 Nginx服务 LVS服务 HAproxy服务 三、部署HAproxy Nginx负载均衡集群 第一步 关闭防火墙和安全机制 第二步 安装依赖环境 第三步 导…

基于paddelOCR的车票识别以及在PCB板上应用

基于paddelOCR的车票识别 任务简介 车牌识别就是从图片或者视频中提取车牌信息 任务难点 尺度差异大&#xff0c;悬挂位置不固定&#xff1b;角度倾斜&#xff0c;图片模糊&#xff0c;光照不足&#xff0c;过曝等问题&#xff1b;边缘和端测场景应用对模型大小有限制&#…

C++之装饰器适配器模式

目录 一、装饰器模式 模式思想 模式简介 模式优点 模式缺点 代码实现 情景模拟 代码实现 运行结果 二、适配器模式 模式简介 介绍 优点 缺点 代码实现 情景模拟 一、装饰器模式 模式思想 模式简介 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向…