发布生成.pdb文件,为什么?

m.e*_*son 251 .net debugging debug-symbols visual-studio pdb-files

为什么Visual Studio 2005 .pdb在发布时编译时会生成文件?我不会调试发布版本,为什么它们会生成?

Cod*_*ray 404

因为没有PDB文件,除了地址级调试之外的其他任何东西都不可能调试"Release"构建.优化确实在你的代码上做了一个数字,如果出现问题就很难找到罪魁祸首(例如,抛出异常).即使设置断点也非常困难,因为源代码行不能与生成的汇编代码一对一匹配(或者甚至以相同的顺序).PDB文件可以帮助您和调试器,使得事后调试变得更加容易.

您要指出,如果您的软件已准备好发布,那么您应该在那时完成所有调试.虽然这确实如此,但要记住以下几点:

  1. 应该使用"发布"版本测试和调试应用程序(在发布之前).这是因为开启优化(默认情况下,它们在"调试"配置下被禁用)有时会导致出现您无法捕获的细微错误.当您进行此调试时,您将需要PDB符号.

  2. 客户经常报告仅在"理想"条件下出现的边缘情况和错误.这些是在实验室中几乎不可能再现的东西,因为它们依赖于该用户机器的一些破坏性配置.如果他们是特别有用的客户,他们将报告抛出的异常并为您提供堆栈跟踪.或者他们甚至会让你借用他们的机器来远程调试你的软件.在任何一种情况下,您都希望PDB文件能够为您提供帮助.

  3. 始终在启用了优化的"发布"版本上进行性能分析.再一次,PDB文件派上用场,因为它们允许将被分析的汇编指令映射回您实际编写的源代码.

编译,您无法返回并生成PDB文件.*如果你在构建过程中没有创建它们,那么你就失去了机会.创造它们并没有伤害任何东西.如果您不想分发它们,可以从二进制文件中省略它们.但如果你以后决定要他们,那你就不走运了.最好始终生成它们并归档副本,以防万一你需要它们.

如果你真的想关掉它们,那总是一个选择.在项目的"属性"窗口中,对于要更改的任何配置,将"调试信息"选项设置为"无".

不过请注意,即"调试"和"释放"的配置发射调试信息在默认情况下使用不同的设置.您需要保留此设置.对于Debug构建,"Debug Info"选项设置为"full",这意味着除了PDB文件之外,调试符号信息也嵌入到程序集中.您还可以获得支持编辑和继续等酷炫功能的符号.在发布模式下,选择"仅pdb"选项,它听起来只包含PDB文件,而不会影响程序集的内容.因此,它不像您/bin目录中是否存在PDB文件那么简单.但假设您使用"仅pdb"选项,PDB文件的存在绝不会影响代码的运行时性能.

*正如Marc Sherman在评论中指出的那样,只要您的源代码没有改变(或者您可以从版本控制系统中检索原始代码),您就可以重建它并生成匹配的PDB文件.至少,通常.这在大多数情况下运行良好,但是每次编译相同的代码时都不保证编译器生成相同的二进制文件,因此可能存在细微差别.更糟糕的是,如果您在此期间对工具链进行了任何升级(例如应用Visual Studio的Service Pack),则PDB更不可能匹配.为了保证事后生成的PDB文件的可靠生成,您不仅需要存档版本控制系统中的源代码,还需要存档整个构建工具链的二进制文件,以确保您可以精确地重新构建构建环境的配置. .毫无疑问,简单地创建和存档PDB文件要容易得多.

  • "编译后无法生成PDB文件." - 如果您的源代码没有更改,那么您可以重建以在事后生成可用的PDB.默认情况下,windbg不会加载此PDB,但您可以通过指定/ i选项来强制它加载,例如`.reload/i foo.dll`.即使在释放foo.dll后创建了foo.pdb,也会加载foo.pdb. (19认同)
  • @在脚注中,我链接到[一篇文章](https://ericlippert.com/2012/05/31/past-performance-is-no-guarantee-of-future-results/)解释说*“ C# 编译器的设计绝不会两次生成相同的二进制文件。每次运行 C# 编译器时,C# 编译器都会在每个程序集中嵌入一个新生成的 GUID,从而确保没有两个程序集是逐位相同的。”* 这解释了为什么它有不同的哈希值,因此有不同的 PDB 文件。这可以使用十六进制编辑器修复,但不方便用户使用。而且也超出了这个答案的范围。 (3认同)
  • Roslyn中有一个称为确定性构建的新功能。“ / deterministic标志使编译器在给出相同的输入时发出完全相同的EXE / DLL(逐字节)。” 这意味着最初使用此标志编译的项目,只要您要编译的代码相同,就可以重新编译为完全相同的二进制文件。可以在[Roslyn中的确定性构建](http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html)中找到更长的解释。 (2认同)

Ali*_*tad 83

PDB可以被生成Release,以及用于Debug.设置为(在VS2010中但在VS2005中必须类似):

None→交通Release→交通Debug→交通None→交通Release

只需将其更改为Debug.

  • 将PDB标记为生产代码的优点是.NET在抛出异常时将使用这些文件.它生成带有文件名和行号的堆栈跟踪,这通常非常方便! (19认同)
  • @ m.edmondson:是的,这是对的.您仍然会被告知抛出的异常*是什么*(如`FileNotFoundException`),但您将无法看到堆栈跟踪.这使得很难确切地确定哪个*行*代码导致抛出异常. (5认同)
  • 因为您可以调试生产问题.一旦我们必须这样做. (4认同)
  • 但你为什么要这样做?如果您的软件已准备好发布,那么您应该在那时完成所有调试 (2认同)
  • @ m.edmondson如果您正在寻找一个工具来远程调试生产盒中的一个问题,那么Windows SDK附带了一个非常着名的工具WinDbg,它支持远程调试.请看下面提到的链接.希望这可以帮助!http://msdn.microsoft.com/en-in/library/windows/hardware/hh451173(v=vs.85).aspx (2认同)
  • @史蒂文:非常感谢你。我已经纠结了好几天了,为什么我的测试服务器在堆栈跟踪中不包含行号,而开发中的相同代码会产生异常,堆栈跟踪具有行号和文件名!这就解释了! (2认同)

小智 8

没有.pdb文件,逐步完成生产代码几乎是不可能的; 你必须依赖其他昂贵且耗时的工具.我知道你可以使用跟踪或windbg,但这实际上取决于你想要实现的目标.在某些情况下,您只需要使用生产数据单步执行远程代码(没有错误或异常)来观察特定行为,这就是.pdb文件派上用场的地方.没有它们就不能在该代码上运行调试器.


jde*_*aan 7

为什么你这么肯定你不会调试发布版本?有时(希望很少但很少发生)您可能会收到客户的缺陷报告,由于某种原因(不同的时间,小的不同行为或其他)在调试版本中无法重现.如果该问题在发布版本中似乎是可重现的,那么您将很乐意拥有匹配的pdb.

  • @ m.edmondson使用RDP,Webex等访问远程机器并在那里安装windbg.设置你的符号路径和bam,你是金色的! (5认同)