大家好,又见面了,我是你们的朋友全栈君。
PDB
文件
什么是 PDB
文件
PDB (Program Data Base)
即程序的基本数据,是 VS
编译链接时生成的文件,每个程序集(EXE
或 DLL
)都有一个与之对应的 PDB 文件。DPB
文件主要存储了 VS
调试程序时所需要的基本信息,主要包括源文件名、变量名、函数名、对应的行号等等。因为存储的是调试信息,所以一般情况下 PDB
文件是在 Debug
模式下才会生成。有了这个文件,我们才能对程序进行 断点调试
,才能一步步执行程序。
为了直观地展示 PDB
文件的内容,我们来做一个小实验。创建一个 WPF
程序(取名为 CrashMe
),在主窗体中放置一个按钮,在按钮的 Click
事件处理方法中编写如下代码。由于 DataContext
为空,所以会弹出一个 MessageBox
来显示异常堆栈。
private void CrashButton_OnClick(object sender, RoutedEventArgs e) {
try {
MessageBox.Show(new Window().DataContext.ToString()); } catch (Exception ex) {
MessageBox.Show(ex.StackTrace, "Exception"); } }
如果将生成的 CrashMe.exe
和 CrashMe.pdb
放一起,弹出的 MessageBox
内容如下左图所示;如果将 CrashMe.pdb
文件删除,内容如下右图所示。
对比两张图可以发现,带 CrashMe.pdb
的多了 文件位置
和 代码行号
,说明这些信息是记录在 pdb
文件中的。
PDB
文件中都包含哪些内容
通过上一小节的例子,大家对 PDB
文件有了大概的了解,知道其中存储了 代码行号
等信息。对于 托管程序
和 非托管程序
,其 PDB
文件中存储的信息不尽相同,由于 托管程序
的 Metadata
已经存储了 类型定义
、函数签名
等信息,所以其 PDB
中的内容相对较少。
Native C PDB
包含的信息public
、private
和static
函数地址- 全局变量的名称和地址
- 参数和局部变量的名称以及它们在栈中的偏移量
class
、structure
和数据的类型定义Frame Pointer Omission
数据,用来在x86
上的native
堆栈的遍历- 源代码文件的名称和行号
.NET PDB
包含的信息- 源代码文件名称和行数
- 局部变量的名称和行数
PDB
是非公开的文件格式,我们不能直接获取其中的内容,只能通过微软提供的 Debug Interface Access SDK
来访问其中的信息。
PDB
的唯一性和重要性
每个程序集(PE
文件,EXE
或 DLL
)都会有一个与之对应的 PDB
文件,并且每次编译生成的 PEPDB
文件都不同。编译器会生成一个 GUID
存储在 PEPDB
文件中,以此来映射 PE
文件和 PDB
文件。由于 PDB
文件具有唯一性,因此 PDB
文件和 PE
文件同等重要,一旦丢失就不能通过重新编译来获取。注意:即使是同一份代码,在同一台计算机上编译,每次的生成的 PDB
都是不同的,一定要保存好发布版本的 PDB
文件。
我们可以使用 DumpBin.exe
来从 PE
文件中获取 GUID
信息,在控制台中启动该程序,并传入 PDB文件
和 /headers参数
即可。如下 部分控制台输出
所示,其中的 BBF232AA-7586-4659-B391-E19B0150E69F
即为此 PE
文件的 GUID
信息,另外还输出了与其对应的 PDB
文件的位置。
D:CrashMebinDebug>dumpbin.exe CrashMe.exe /headers
.....
Debug Directories
Time Type Size RVA Pointer
-------- ------- -------- -------- --------
5AC1F73B cv 11C 00003838 1A38 Format: RSDS, {BBF232AA-7586-4659-B391-E19B0150E69F}, 1, C:UsersIronDesktopCrashMeobjDebugCrashMe.pdb
......
接下来找到对应的 PDB
文件,检查其中 GUID
信息是否与 PE
一致,推荐使用 PdbInspector
来查看 PDB
文件的内部信息。
调试工具会通过路径和名字来查找 PDB
文件, 还会通过上面的 GUID
来确定 PDB文件
和 PE文件
是否真正匹配。
调试工具加载 PDB
文件的顺序:
PE
文件所在的路径PE
中hardcode
记录的build
目录,例如objdebug*.pdb
- 根据
symbol server
的设置,在本地的symbol server
的cache
中查找 - 远程的
symbol server
中查找
参考资料
- PDB文件详解 – CSDN
- PDB Files: What Every Developer Must Know
- DUMPBIN Reference – MS
- How to Inspect the Content of a Program Database (PDB) File – CodeProject
- Symbols File Locator – CodeProject
- Converting a managed PDB into a XML file – MSDN
- Microsoft/microsoft-pdb – GitHub
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/137008.html原文链接:https://javaforall.cn