我必须使用没有源代码的第三方组件.我有发布DLL和发布PDB文件.我们称之为'CorporateComponent.dll'.我自己的代码从这个DLL创建对象并调用这些对象上的方法.
CorpObject o = new CorpObject(); Int32 result = o.DoSomethingLousy();
在调试时,方法'DoSomethingLousy'会抛出异常.PDB文件对我有什么作用?如果它做得好,我怎么能确定我正在使用它?
要确认您是否正在使用提供的PDB,CorporateComponent.pdb,在Visual Studio IDE中进行调试期间,请检查输出窗口并找到指示已加载CorporateComponent.dll并后跟字符串的行Symbols loaded
.
从我的项目来说明:
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版本中包含符号信息.
pdb包含调试器为正确读取堆栈所需的信息.堆栈跟踪将包含您拥有pdb的模块内的堆栈帧的行号和符号名称.
我将举两个例子.第一个是明显的答案.第二个解释了源索引的pdb.
第一个用法例子......
根据调用约定和编译器使用的优化,调试器可能无法通过您没有pdb的模块手动展开堆栈.某些第三方库甚至是操作系统的某些部分都可能发生这种情况.
考虑一种在Windows操作系统中遇到访问冲突的情况.堆栈跟踪不会展开到您自己的应用程序中,因为该OS组件使用特殊的调用约定来混淆调试器.如果您配置符号路径以下载公共OS pdb,那么堆栈跟踪很可能会展开到您的应用程序中.这使您可以准确地查看自己的代码传递给OS系统调用的参数.(以及第三方库内部甚至是您自己代码内部的AV的类似示例)
第二个用法示例......
Pdb有另一个非常有用的属性 - 它们可以使用微软称之为"源索引"的功能与某些源控制系统集成.源索引的pdb包含源控制命令,这些命令指定如何从源代码控制中获取用于构建组件的确切文件版本.Microsoft的调试器了解如何执行命令以在调试会话期间自动获取文件.这是一个强大的功能,可以使调试工程师不必手动将源树同步到给定构建的正确标签.它对于远程调试会话和分析崩溃后的故障转储特别有用.
"用于Windows的调试工具"安装(windbg)包含一个名为srcsrv.doc的文档,该文档提供了一个示例,演示如何使用srctool.exe确定在给定的pdb中源索引的源文件.
要回答"我怎么知道"的问题,调试器中的"模块"功能可以告诉您哪些模块具有相应的pdb.在windbg中使用"lml"命令.在visual studio中,从调试菜单中的某个位置选择模块.(对不起,我没有当前版本的visual studio方便)