PDB 在调试时给我带来什么以及我如何知道它正在工作?
我必须使用没有源代码的第三方组件。 我有发布DLL和发布PDB文件。 我们将其称为“CorporateComponent.dll”。 我自己的代码从这个 DLL 创建对象并调用这些对象的方法。
CorpObject o = new CorpObject();
Int32 result = o.DoSomethingLousy();
调试时,方法“DoSomethingLousy”抛出异常。 PDB 文件对我有什么作用? 如果它有好处,我如何确定我正在利用它?
I have to use a third-party component without source code. I have the release DLL and release PDB file. Let's call it 'CorporateComponent.dll'. My own code creates objects from this DLL and calls methods on these objects.
CorpObject o = new CorpObject();
Int32 result = o.DoSomethingLousy();
While debugging, the method 'DoSomethingLousy' throws an exception. What does the PDB file do for me? If it does something nice, how can I be sure I'm making use of it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
pdb 包含调试器正确读取堆栈所需的信息。 您的堆栈跟踪将包含您拥有 pdb 的模块内部堆栈帧的行号和符号名称。
我将给出两个用法示例。 第一个是显而易见的答案。 第二个解释了源索引的 pdb。
第一个使用示例...
根据调用约定以及编译器使用的优化,调试器可能无法通过没有 pdb 的模块手动展开堆栈。 某些第三方库甚至操作系统的某些部分可能会发生这种情况。
考虑这样一个场景:您在 Windows 操作系统内部遇到访问冲突。 堆栈跟踪不会展开到您自己的应用程序中,因为该操作系统组件使用特殊的调用约定,这会使调试器感到困惑。 如果您配置符号路径来下载公共操作系统 pdb,那么堆栈跟踪很有可能会展开到您的应用程序中。 这使您能够准确地看到您自己的代码传递到操作系统系统调用中的参数。 (以及第三方库内部甚至您自己的代码内部的 AV 的类似示例)
第二个使用示例...
Pdb 有另一个非常有用的属性 - 它们可以使用微软称为“源索引”的功能与一些源代码控制系统集成”。 源索引 pdb 包含源控制命令,这些命令指定如何从源控制获取用于构建组件的确切文件版本。 Microsoft 的调试器了解如何执行命令以在调试会话期间自动获取文件。 这是一个强大的功能,可以让调试工程师不必手动将源树同步到给定构建的正确标签。 它对于远程调试会话和事后分析故障转储特别有用。
“Windows 调试工具”安装 (windbg) 包含一个名为 srcsrv.doc 的文档,该文档提供了一个示例,演示如何使用 srctool.exe 确定给定 pdb 中哪些源文件已建立源索引。
为了回答您的问题“我怎么知道”,调试器中的“模块”功能可以告诉您哪些模块有相应的 pdb。 在windbg中使用“lml”命令。 在 Visual Studio 中,从调试菜单中的某个位置选择模块。 (抱歉,我手头没有当前版本的 Visual Studio)
The pdb contains information the debugger needs in order to correctly read the stack. Your stack traces will contain line numbers and symbol names of the stack frames inside of the modules for which you have the pdb.
I'll give two usages examples. The first is the obvious answer. The second explains source-indexed pdb's.
1st usage example...
Depending on calling convention and which optimizations the compiler used, it might not be possible for the debugger to manually unwind the stack through a module for which you do not have a pdb. This can happen with certain third party libraries and even for some parts of the OS.
Consider a scenario in which you encounter an access violation inside of the windows OS. The stack trace does not unwind into your own application because that OS component uses a special calling convention that confuses the debugger. If you configure your symbol path to download the public OS pdb's, then there is a good chance that the stack trace will unwind into your application. That enables you to see exactly what arguments your own code passed into the OS system call. (and similar example for AV inside of a 3rd party library or even inside of your own code)
2nd usage example...
Pdb's have another very useful property - they can integrate with some source control systems using a feature that microsoft calls "source indexing". A source-indexed pdb contains source control commands that specify how to fetch from source control the exact file versions that were used to build the component. Microsoft's debuggers understand how to execute the commands to automatically fetch the files during a debug session. This is a powerful feature that saves the debug egineer from having to manually sync a source tree to the correct label for a given build. It's especially useful for remote debugging sessions and for analyzing crash dumps post-mortem.
The "debugging tools for windows" installation (windbg) contains a document named srcsrv.doc which provides an example demonstrating how to use srctool.exe to determine which source files are source-indexed in a given pdb.
To answer your question "how do I know", the "modules" feature in the debugger can tell you which modules have a corresponding pdb. In windbg use the "lml" command. In visual studio select modules from somewhere in the debug menus. (sorry, I don't have a current version of visual studio handy)
PDB 是一个数据库文件,它将指令映射到原始代码中的行号,因此当您获得堆栈跟踪时,您将获得代码的行号。 如果它是非托管 DLL,则 PDB 文件还会为您提供堆栈跟踪中的函数名称,而该信息通常仅适用于没有 PDB 的托管 DLL。
The PDB is a database file that maps the instructions to their line numbers in the original code so when you get a stack trace you'll get the line numbers for the code. If it's an unmanaged DLL then the PDB file will also give you the names of the functions in the stack trace, whereas that information is usually only available for managed DLLs without PDBs.
我从 pdb 获得的主要信息是堆栈跟踪的行号和实际方法名称。
The main I get from the pdb is line numbers and real method names for stack traces.
要确认您是否正在使用提供的 PDB CorporateComponent.pdb,请在 Visual Studio IDE 中进行调试期间查看输出窗口并找到指示 CorporateComponent.dll 已加载且后跟字符串
Symbols returned
Symbols returned 的行。代码>.以我的一个项目为例:
这表示 IDE 调试器已找到并加载 PDB。
正如其他人所指出的,在检查应用程序中的堆栈帧时,您应该能够看到 CorporateComponent.pdb 中的符号。 如果您不这样做,那么第三方可能没有在发布的 PDB 版本中包含符号信息。
To confirm if you're using the provided PDB, CorporateComponent.pdb, during debugging within the Visual Studio IDE review the output window and locate the line indicating that the CorporateComponent.dll is loaded and followed by the string
Symbols loaded
.To illustrate from a project of mine:
This indicates that the PDB was found and loaded by the IDE debugger.
As indicated by others When examining stack frames within your application you should be able to see the symbols from the CorporateComponent.pdb. If you don't then perhaps the third-party did not include symbol information in the release PDB build.