【问题标题】:Visual Studio: debug information in release buildVisual Studio:发布版本中的调试信息
【发布时间】:2023-04-02 13:41:01
【问题描述】:

我很想在发布给客户的发布版本中包含调试信息。据我所知,唯一的缺点是二进制文件大小增加了 25%。优点是我可以获得立即可用的故障转储,更容易分析。 我愿意忍受 25% 的增长。我还有其他缺点吗?

这是一个 C 项目,我想做的只是链接/调试/生成调试信息

【问题讨论】:

    标签: visual-studio debugging build debug-symbols


    【解决方案1】:

    可执行文件的大小应该增加不到 25%。

    实际上我有点惊讶它增加了很多,但一些快速测试表明,至少一个大型示例项目 (ScummVM) 仅通过添加 /DEBUG 选项将 .exe 从 10,205,184 字节增加到 10,996,224 字节到链接步骤(大约增加 8%)。 /DEBUG 是使用 IDE 中的 "Linker | Debugging | Generate Debug Info" 选项指定的。请注意,此设置应该对编译器生成的优化没有影响。

    我知道一个指向 .pdb 文件的指针被放入了可执行文件中,但并没有太多。我做了一些实验,发现启用 /OPT:REF 链接器选项将大小差异更改为 10,205,184 与 10,205,696。所以非 /DEBUG 构建保持相同的大小,但 /DEBUG 构建下降到仅大 512 字节(这可能由指向 .pdb 的指针解释 - 可能链接器舍入到 512 的某个倍数或其他东西)。增幅远低于 1%。显然,添加/DEBUG 会导致链接器保留未引用的对象,除非您还指定/OPT:REF。 (IDE 中的"Linker | Optimization | References" 选项)。

    程序在没有 .pdb 文件的情况下也能正常运行 - 如果您想在客户站点提供更好的调试体验,您可以选择将其发送给客户。如果您只是希望能够获得体面的堆栈跟踪,则不需要在客户机器上拥有 .pdb 文件 - 他们(或您提供的某些工具/功能)可以发送可以加载到调试器在您的站点上使用可用的 .pdb 文件并获取相同的堆栈跟踪信息端口分析。

    当然,需要注意的一件事是您需要将 .pdb 文件与您的版本一起存档。 “Windows 调试工具”包(现在在 Windows SDK 中分发)提供了一个符号服务器工具,因此您可以存档 .pdb 文件并轻松检索它们以进行调试。

    我能想到的分发 .pdb 文件的唯一缺点是,如果您担心的话,它可以使您的应用程序的逆向工程变得更容易。请注意,Microsoft 为 Windows 分发符号(使用公共符号服务器 - 以及某些特定版本的完整符号集的包)。但是,他们分发的符号确实经过了一个消毒步骤,该步骤删除了他们认为敏感的某些项目。您可以使用链接器的/PDBSTRIPPED 选项(IDE 中的"Linker | Debugging | Strip Private Symbols")执行相同(或类似)操作。有关该选项删除内容的详细信息,请参阅the MSDN documentation。如果您要分发符号,则使用该选项可能是合适的。

    【讨论】:

    • 显然,SCUMVM 几乎没有未引用的代码 :) 在我启用剥离未引用的符号后,可执行文件大小恢复正常。非常感谢!
    • 看起来应该指定 /OPT:REF 来删除未引用的对象,而不是 /OPT:NOREF。 msdn.microsoft.com/en-us/library/bxwfs976.aspx 这对我来说很不直观......
    【解决方案2】:

    根据 Visual Studio 2005 Retired documentation 上的 Visual Studio 2005 文档:

    /DEBUG 将 /OPT 选项的默认值从 REF 更改为 NOREF 和 从 ICF 到 NOICF(因此,您需要明确指定 /OPT:REF 或 /OPT:ICF)。

    在我的情况下,当我启用两者时它会有所帮助:

    /O2 /DEBUG /OPT:REF /OPT:ICF
    

    【讨论】:

      【解决方案3】:

      您没有提及您使用的语言,C++ 与 C# 可能会有不同的答案。

      我不能 100% 确定您正在考虑做出什么改变。您是要告诉 Visual Studio 使其标准 Debug 编译并发布,还是要在 Release 编译中编辑几个设置?对 Release 版本中的几个设置进行仔细修改是最好的方法。

      无论您最终得到什么,我都会确保启用优化,因为这会对编译代码的性能产生显着影响。

      【讨论】:

      • 但其他问题是......我如何确保优化仍然存在?我的意思是,它们已启用,但如果“生成调试信息”覆盖设置并禁用它们怎么办?
      • 如果您使用的是平面 C,则此设置位于项目的属性页中,位于 Configuration Properties::C/C++::Optimization 下。我相信调试版本的默认设置是禁用优化 (/Od),发布版本的默认设置是最大化速度 (/O2)。
      • 如果要验证编译器设置是否生效,选择一个方法,查看反汇编器中的Debug和ModifiedRelease编译。在 Debug 中,C 代码和程序集之间会有很强的相关性,在优化的构建中,事情会被重新安排,并且更难遵循。理论上,您可以将 ModifiedRelease 程序集与真正的 Release 程序集进行比较,它应该是相同的,或者至少比 Debug 程序集更接近。
      【解决方案4】:

      我总是发送调试版本,而不是发布版本。我想不出有什么缺点,优点就是你说的。

      【讨论】:

      • 优化是有用的东西
      • @SLAks 是的,同意。我不是在制作调试版本,而是在发布带有调试信息的版本......我的理解是它仍然具有所有优化,只是还包括一些调试符号。嗯,这就是我想用这个问题来澄清的。
      • 想象一个汽车经销商说“我总是卖实验室原型,而不是工厂的真车”......哦,你可能不允许将调试运行时分发给客户(IANAL,但是查看您的编译器的许可证)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多