PDB在调试时会给我什么,我如何知道它在工作?

时间:2020-03-05 18:50:15  来源:igfitidea点击:

我必须使用没有源代码的第三方组件。我有发布DLL和发布PDB文件。我们称之为" CorporateComponent.dll"。我自己的代码从此DLL创建对象,并在这些对象上调用方法。

CorpObject o = new CorpObject();
Int32 result = o.DoSomethingLousy();

调试时,方法'DoSomethingLousy'引发异常。 PDB文件对我有什么作用?如果它做的很好,我如何确定我正在使用它?

解决方案

回答

PDB是一个数据库文件,它将指令映射到原始代码中的行号,因此,当我们获得堆栈跟踪时,将获得代码的行号。如果它是非托管DLL,则PDB文件还将为我们提供堆栈跟踪中的函数名称,而该信息通常仅适用于不带PDB的托管DLL。

回答

我从pdb获得的主要内容是行号和堆栈跟踪的真实方法名称。

回答

pdb包含调试器正确读取堆栈所需的信息。堆栈跟踪将包含具有pdb的模块内部堆栈帧的行号和符号名称。

我将举两个用法示例。首先是显而易见的答案。第二部分解释了源索引的pdb。

第一种用法示例...

根据调用约定和编译器使用的优化,调试器可能无法通过我们没有pdb的模块手动展开堆栈。某些第三方库甚至操作系统的某些部分都可能发生这种情况。

考虑在Windows操作系统内部遇到访问冲突的情况。堆栈跟踪不会展开到我们自己的应用程序中,因为该OS组件使用特殊的调用约定,这会使调试器感到困惑。如果将符号路径配置为下载公共OS pdb的符号路径,则堆栈跟踪很有可能会展开到应用程序中。这样一来,我们就可以准确查看自己的代码将哪些参数传递给OS系统调用。 (以及第3方库内甚至我们自己的代码内的AV的类似示例)

第二用法示例...

Pdb具有另一个非常有用的属性,它们可以使用Microsoft称为"源索引"的功能与某些源控制系统集成。源索引的pdb包含源控制命令,这些命令指定如何从源控制中获取用于构建组件的确切文件版本。 Microsoft的调试器了解如何执行命令以在调试会话期间自动获取文件。这是一项功能强大的功能,可以使调试egineer免于必须手动将源树同步到给定构建的正确标签的麻烦。它对于远程调试会话和事后分析崩溃转储特别有用。

"用于Windows的调试工具"安装(windbg)包含一个名为srcsrv.doc的文档,该文档提供了一个示例,演示了如何使用srctool.exe确定在给定的pdb中哪些源文件在源索引中。

为了回答问题"我怎么知道",调试器中的"模块"功能可以告诉我们哪些模块具有相应的pdb。在windbg中,使用" lml"命令。在Visual Studio中,从调试菜单中的某个位置选择模块。 (抱歉,我没有Visual Studio的当前版本)

回答

为了在Visual Studio IDE中进行调试期间确认是否正在使用提供的PDB CorporateComponent.pdb,请查看输出窗口,并找到指示已加载CorporateComponent.dll的行,后跟字符串" Symbols loading"。

为了说明我的一个项目:

The thread 0x6a0 has exited with code 0 (0x0).
The thread 0x1f78 has exited with code 0 (0x0).
'AvayaConfigurationService.vshost.exe' (Managed): Loaded 'C:\Development\Src\trunk\ntity\AvayaConfigurationService\AvayaConfigurationService\bin\Debug  \AvayaConfigurationService.exe', Symbols loaded.
'AvayaConfigurationService.vshost.exe' (Managed): Loaded 'C:\Development\Src\trunk\ntity\AvayaConfigurationService\AvayaConfigurationService\bin\Debug\IPOConfigService.dll', No symbols loaded.
Loaded 'C:\Development\src...\bin\Debug\AvayaConfigurationService.exe', Symbols loaded.

这表明IDE调试器已找到并加载了PDB。

正如其他人指出的那样,在检查应用程序中的堆栈框架时,我们应该能够从CorporateComponent.pdb中看到符号。如果我们不这样做,那么也许第三方在发行版PDB构建中未包含符号信息。