2011-03-28 135 views
217

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

+14

为什么要在释放中生成pdb?所以当一个崩溃报告来自野外时,你有信息来调试它。另一个价值是客户可以在原作者不会的时候进行调试。 – 2012-02-12 18:14:15

+0

@IanBoyd:该评论的第二句暗示你部署了PDB。绝大多数情况下这是不可取的。 – IInspectable 2017-06-09 11:52:09

+2

@IInspectable或[可取的](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/microsoft-public-symbols) – 2017-06-09 21:03:34

回答

361

因为没有PDB文件,不可能通过除地址级调试之外的其他任何东西来调试“发布”版本。优化确实会在您的代码中执行一些操作,如果发生错误(例如引发异常),很难找到罪魁祸首。即使设置断点也是非常困难的,因为源代码行不能与生成的汇编代码一一对应(或者甚至以相同的顺序)。 PDB文件可以帮助您和调试器解决问题,从而使验尸调试更加容易。

您指出,如果您的软件已准备好发布,那么您应该已经完成​​了您的所有调试。虽然这是事实,但也有几个重要的点要牢记:

  1. 你应该测试和调试应用程序(你释放它之前)使用“释放”的构建。这是因为打开优化(它们在“调试”配置下被默认禁用)有时会导致出现细微的错误,否则您将无法捕获。当你正在做这个调试时,你会需要PDB符号。

  2. 客户经常报告边缘情况和只在“理想”条件下出现的错误。这些都是在实验室中几乎不可能复制的东西,因为它们依赖于该用户机器的某些令人毛骨悚然的配置。如果他们是特别有用的客户,他们会报告抛出的异常并为您提供堆栈跟踪。或者他们甚至会让你借用他们的机器来远程调试你的软件。无论哪种情况,您都需要PDB文件来帮助您。

  3. 性能分析应该总是在启用优化的“发布”版本上完成。而且,PDB文件再次派上用场,因为它们允许将被汇编的汇编指令映射回您实际编写的源代码。

你不能回去生成PDB文件编译后*如果您在构建过程中没有创建它们,那么您就失去了机会。它不会伤害任何东西来创建它们。如果你不想分发它们,你可以简单地从你的二进制文件中省略它们。但是如果你以后决定你想要他们,那你的运气不好。更好的是始终生成并存档副本,以防万一您需要它们。

如果你真的想关闭它们,那永远是一种选择。在您的项目的“属性”窗口中,将“调试信息”选项设置为“无”,以进行要更改的任何配置。

但是,请注意,默认情况下,“调试”和“释放”配置使用不同的设置来发出调试信息。你会想保持这个设置。调试版本的“调试信息”选项设置为“完整”,这意味着除了PDB文件之外,调试符号信息也会嵌入到程序集中。您还可以获得支持诸如编辑和继续等很酷功能的符号。在发布模式中,选择“仅限pdb”选项,就像它听起来一样,它只包含PDB文件,而不会影响程序集的内容。所以它不像/bin目录中存在或不存在PDB文件那么简单。但假设您使用“仅限pdb”选项,则PDB文件的存在不会影响代码的运行时性能。

*作为Marc Sherman points out in a comment,只要你的源代码并没有改变(或者你可以从一个版本控制系统原码),可以重建,并生成匹配的PDB文件。至少,通常。这在大多数情况下运作良好,但the compiler is not guaranteed to generate identical binaries each time you compile the same code,所以可能会有细微的差异。更糟糕的是,如果您在此期间对工具链进行了升级(比如为Visual Studio应用Service Pack),则PDB更不可能匹配。为了保证可靠地生成PDB文件,您不仅需要存档版本控制系统中的源代码,还需要存档整个构建工具链的二进制文件,以确保您可以精确地重新创建您的配置建立环境。不用说,简单地创建和存档PDB文件就容易多了。

+18

“编译后无法生成PDB文件。” - 如果你的源代码没有改变,那么你可以在事实之后重新生成一个可用的PDB。默认情况下,windbg不会加载这个PDB,但你可以通过指定/ i选项像''reload/i foo.dll'来加载它。即使在释放foo.dll后创建了foo.pdb,也会加载foo.pdb。 – 2012-11-29 14:20:06

+0

我注意到每个新的编译都有不同的哈希摘要,因此即使在相同的环境中,每个编译也会有轻微的差异。 PDB的地址能否不随方差而改变,因此需要保持PDB的构建?只是把它看作一个想法,因为我不太了解PDB是如何工作的或者为什么在构建之间哈希会发生变化。 – thebunnyrules 2017-01-31 23:27:24

+1

@在脚注中,我链接到[一篇文章](https://ericlippert.com/2012/05/31/past-performance-is-no-guarantee-of-future-results/),解释*“设计的C#编译器从不会生成相同的二进制文件,C#编译器每次运行它时,都会在每个程序集中嵌入一个新生成的GUID,从而确保没有两个程序集的位对位相同。“*这就解释了为什么它具有不同的散列,因此具有不同的PDB文件。这可以用十六进制编辑器修复,但不方便用户使用。并且也在这个答案的范围之外。 – 2017-02-01 05:19:15

71

PDB可以为Release以及Debug生成。这是设置为(在VS2010但在VS2005必须是相似的):

ProjectPropertiesBuildAdvancedDebug Info

它只是更改为None

+1

但是,你为什么要这样做?如果您的软件已准备好发布,那么您应该已经完成​​了您的所有调试 – 2011-03-28 09:40:36

+4

因为您可以调试生产问题。一旦我们必须这样做。 – Aliostad 2011-03-28 09:44:35

+1

你如何做到这一点?是否有某种工具可以让您远程调试? – 2011-03-28 09:45:54

7

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

+5

@ m.edmondson使用RDP,Webex等访问远程机器,并在那里安装windbg。设置你的符号路径和巴姆,你是金! – 2012-11-29 14:14:06

+0

指向更详细指南的链接会更有帮助。这种单线的方法可能会导致人们(比如我)走错路。例如,大多数.NET开发人员对Windbg一无所知。 – Nuzzolilo 2014-09-12 18:54:52

+1

@ m.edmondson - 某些版本的Visual Studio有能力执行远程调试。从远程机器上的“附加处理”调试菜单。 – Matt 2014-11-08 16:01:07

8

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

2

.PDB文件是“程序数据库”的简称。它包含调试器的调试点信息以及使用或引用的资源。它在我们构建为调试模式时生成。它允许应用程序在运行时进行调试。

调试模式下,.PDB文件大小增加。它在我们测试我们的应用程序时使用。

发布或部署时不需要此文件。 pdb文件的好文章。

http://www.codeproject.com/Articles/37456/How-To-Inspect-the-Content-of-a-Program-Database-P

+1

“没有需要此文件时发布或部署“,除非有人在发布的版本中遇到崩溃,并且从它们获得的崩溃报告不包含可用的堆栈跟踪......那么您希望您将它包含在内。 – Nyerguds 2017-01-02 10:44:01

4

此外,您还可以使用崩溃转储来调试软件。客户将其发送给您,然后您可以使用它来确定源代码的确切版本 - 并且Visual Studio甚至会使用故障转储来提供正确的调试符号集(以及源代码,如果您设置正确的话)。请参阅微软的documentation on Symbol Stores

1

在多项目解决方案中,您通常希望拥有一个根本不生成PDB或XML文件的配置。我不认为将每个项目的Debug Info属性更改为none,而是认为添加仅适用于特定配置的构建后事件会更方便。

不幸的是,Visual Studio不允许您为不同的配置指定不同的构建后事件。所以,我决定手动做到这一点,通过编辑csproj文件的启动项目并添加以下(而不是任何现有PostBuildEvent标签):

<PropertyGroup Condition="'$(Configuration)' == 'Publish'"> 
    <PostBuildEvent> 
     del *.pdb 
     del *.xml 
    </PostBuildEvent> 
    </PropertyGroup> 

不幸的是,这会让后生成事件文本框为空,并把其中的任何内容都可能产生不可预知的结果。

+2

这将删除所有'* .xml'文件,请注意。 – 2017-04-03 07:17:10

0

调试符号(.pdb)和XML文档( .xml)文件占总大小的很大比例,不应该是常规部署软件包的一部分。 但应该可以在需要时访问它们。

一种可能的方法:在TFS构建过程结束时,将它们移动到单独的工件上。

相关问题