本文主要是介绍【C++】了解PDB,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Introduction
本文帮助那些处于初级或中级水平,对PDBs格式文件的重要性和为什么需要PDBs格式文件了解不多的开发人员。What is PDB
Why PDB as a Separate File?
这些符号可以很好地嵌入二进制中,但这又会导致文件大小显著增加(有时是几兆字节)。为了避免这种额外的大小,现代编译器和早期的大型机调试系统将符号信息输出到一个单独的文件中;对于微软编译器来说,这个文件被称为PDB文件。What Does the PDB File Contain
以下是PDB文件存储的一些重要信息:
-
- Local variable name - 局部变量名-为了证明PDB包含本地变量名,我们将使用反射器来反汇编程序集,其PDB存在于与程序集相同的文件夹中。反射器有一个选项,称为“显示PDB符号”,如截图所示,当选中时,也为该程序集加载相应的PDB。当您检查选项时,您可以看到反编译代码具有与实际代码相同的变量名,但是在没有PDB的情况下,或者当该选项未选中时,您的反编译代码中的本地变量将被替换为字符串变量的“STR”和“Num”。十进制等。
- 源文件名
- 信源的行号
- 源索引(稍后说明)
namespace UnderstandingPDBs
{class Program{static void Main(string[] args){try{int sum = Add(5, 10);decimal value = Divide(10, 0);}catch{}}private static int Add(int i, int j){return i + j;}private static decimal Divide(int i, int j){try{return i / j;}catch (Exception ex){LogError(ex);throw ex;}}private static void LogError(Exception ex){using (var txtWriter = new StreamWriter(@"dump.txt",true)){string error = "Exception:" + ex.Message + Environment.NewLine + "StackTrace:" + ex.StackTraceif(ex.InnerException!=null)error=error+"INNER EXCEPTION:"+ex.InnerException;txtWriter.WriteLine(error);}}}
}
With PDB, this is the exception thrown by the application:
Exception:Attempted to divide by zero.
StackTrace: at UnderstandingPDBs.Program.Divide(Int32 i, Int32 j) in
C:\Users\Rishi\Documents\Visual Studio 2010\Projects\UnderstandingPDBs\Program.cs:line 33
Without PDB, exception shows the following message:
Exception:Attempted to divide by zero.
StackTrace: at UnderstandingPDBs.Program.Divide(Int32 i, Int32 j)
---------
Clearly, the one with PDB shows line number and file name of the class where exception is thrown.
How PDB is Loaded by Debugger?
Different Build Settings in Visual Studio
Visual Studio has 3 different Build Options which control the debug symbols generation:
- none: PDB files will not be generated.PDB文件将不会生成。
- pdb-only: The debug symbols will be only in PDB files and not in Binary仅PDB:调试符号只在PDB文件中,而不是二进制文件。
- Full: Along with symbols in PDB binary will also contain some debug symbols完整的:连同PDB二进制中的符号也将包含一些调试符号。
Full is the default option set in Visual Studio.
According to MSDN:
"If you use /debug:full, be aware that there is some impact on the speed and size of JIT optimized code and a small impact on code quality with /debug:full. We recommend /debug:pdbonly or no PDB for generating release code."“如果您使用/Debug:FULL,请注意,JIT优化代码的速度和大小会有一些影响,对代码质量的影响也会很小。我们建议/调试:PDBUN或无PDB生成发布代码。
Should We Deploy PDBs Along with Binaries?
并不是必须部署PDB和二进制部署来获得关于异常的额外信息。同样可以使用符号服务器和源索引来实现,我将在下面的主题中进行讨论。
Security Risk with PDB?
如果部署了PDB并且用户不能访问二进制文件,那么向他们展示堆栈跟踪信息并让他们知道应用程序的内部结构不是一个好主意。
Symbol Server
符号服务器用于存储调试器已知的PDB文件,并可用于查找更多描述性的调用堆栈信息。
我们可以使用SyStur.EXE设置自己的符号服务器,它允许调试器找到与所讨论的二进制相关联的实际PDB。SytSuff.EXE包含在Window包的调试工具中。微软还维护符号服务器,我们可以通过从微软的符号服务器加载PDB来使用。
How and Why to load Microsoft Symbol Store
当您在调试点和打开模块窗口停止执行时(如下所示),您将发现所有的DLL(外部或内部)加载到该断点为止,但是默认情况下的符号状态将显示“除了PDB之外无法找到或打开PDB文件”。这些是微软BCL二进制文件,因为我们的调试器找不到相关的PDB,所以这些二进制二进制文件没有加载。
由于这些二进制文件在您的应用程序之外,还需要在“调试”>“常规”菜单中取消“启用仅我的代码”。
那么这怎么可能有用呢?
可以在代码中放置断点,并在加载和不加载符号的情况下查看调用堆栈。
下图显示了没有加载符号的调用堆栈,它只显示了我的方法和BCL的方法(只是外部代码)。
在下面的屏幕截图中,你可以看到我已经加载了符号,现在符号的状态显示了“符号加载”。
Points of Interest
这篇关于【C++】了解PDB的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!