【问题标题】:Should I compile release builds with debug info as "full" or "pdb-only"?我应该将调试信息编译为“full”还是“pdb-only”?
【发布时间】:2011-12-04 12:55:29
【问题描述】:

在 C# 项目的 Visual Studio 中,如果您转到项目属性 > 构建 > 高级 > 调试信息,您有三个选项:none、full 或 pdb-only。

哪种设置最适合发布版本?


那么,full 和 pdb-only 有什么区别?

如果我使用full 会有性能影响吗?如果我使用pdb-only 会更难调试生产问题吗?

【问题讨论】:

  • 仅 pdb 或无 pdb,始终用于发布版本。
  • @leppie 谢谢,但我正在寻找该职位的一些理由。
  • 如果没有性能影响,那就太好了。记忆影响呢?如果我创建一个 StackTrace 实例并请求文件信息,它必须来自 pdb 符号数据。应用程序启动时是否所有符号都加载到内存中?这个大概的内存使用是多少? (例如相对于代码大小的百分比开销。)

标签: c# visual-studio debugging build debug-symbols


【解决方案1】:

我会使用pdb-only 构建。您将无法将调试器附加到已发布的产品,但如果您收到故障转储,您可以使用 Visual Studio 或 WinDBG 检查崩溃时的堆栈跟踪和内存转储。

如果您使用full 而不是pdb-only,您将获得相同的好处,除了可执行文件可以直接附加到调试器。您需要根据您的产品和客户确定这是否合理。

确保将 PDB 文件保存在某处,以便在收到崩溃报告时可以引用它们。如果您可以设置 symbol server 来存储这些调试符号,那就更好了。

如果您选择使用none 进行构建,那么当现场发生崩溃时您将无法追索。您将无法对事故进行任何形式的事后检查,这可能会严重影响您追查问题的能力。

关于性能的说明:

John Robbins 和 Eric Lippert 都写过关于 /debug 标志的博客文章,他们都表示此设置对性能的影响零。有一个单独的/optimize 标志指示编译器是否应该执行优化。

【讨论】:

  • @Matt,MSDN article on the /debug switch 明确警告使用“完整”设置会影响性能: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.
  • @Matt:如果'full'与'pdb-only'相比没有缺点,但只有优点,为什么'pdb-only'甚至存在?有什么理由使用它而不是“完整”吗?此外,您应该在“社区内容”部分中添加对 MSDN 文章的更正。
  • @AllonGuralnek 引用链接的 John Robbins 文章:真正的原因:历史。在 .NET 1.0 中存在差异,但在 .NET 2.0 中则没有。看起来 .NET 4.0 将遵循相同的模式。与 CLR 调试团队再次核对后,完全没有区别。
  • 这不是真的。您可以仅使用 pdb 构建,但仍附加调试器。我只是为了确定。
  • "我将使用 pdb-only 构建。您将无法将调试器附加到已发布的产品" 您的信息来源是什么?正如@Mark 和我所指出的,这似乎不正确。
【解决方案2】:

警告 /debug 开关的 MSDN documentation(在 Visual Studio 中是调试信息)似乎已过时!这就是它所具有的不正确

如果您使用 /debug:full,请注意对 JIT 优化代码的速度和大小以及对代码的影响很小 /debug:full 的质量。我们建议 /debug:pdbonly 或不使用 PDB 生成发布代码。

/debug:pdbonly 和 /debug:full 之间的一个区别是 /debug:full 编译器发出一个DebuggableAttribute,用于 告诉 JIT 编译器有可用的调试信息。

那么,现在是真的吗?

  1. 仅限 Pdb – 在 .NET 2.0 之前,它有助于调查已发布产品(客户机器)的故障转储。但它并没有让附加调试器。这不是 .NET 2.0 的情况。 完全与Full相同。
  2. 完整 - 这有助于我们调查故障转储,还允许我们将调试器附加到发布版本。但与 MSDN 提到的不同,它不会影响性能(从 .NET 2.0 开始)。它与 Pdb-only 完全相同。

如果它们完全相同,为什么我们有这些选项? John Robbins(windows 调试大神)found out 这些都是出于历史原因。

在 .NET 1.0 中存在差异,但在 .NET 2.0 中则没有。 看起来 .NET 4.0 将遵循相同的模式。后 与 CLR 调试团队仔细检查,没有区别 全部。

控制 JITter 是否进行调试构建的是 /optimize 转变。

最重要的是,您想要构建您的发布版本 /optimize+ 和任何 /debug 开关,以便您可以使用源代码进行调试 代码。

然后他继续证明这一点。

现在优化是单独开关 /optimize 的一部分(在 Visual Studio 中称为 Optimize code)。

简而言之,无论 DebugInfo 设置 pdb-only 还是 full,我们都会得到相同的结果。建议避免使用 None,因为它会剥夺您分析已发布产品或附加调试器的故障转储的能力。

【讨论】:

  • 绝妙的答案!我自己的调查(比较生成的文件)显示了相同的结果。
  • @rpattabi 你能指定pdbonly和full相同的引用吗?现在是 2019 年,文档仍然表明它们是不同的,并且完整会导致性能下降。并且 VS2019 使用 Release 配置的调试类型默认设置为 pdbonly 创建项目。
  • @joe MSDN 文档底部有一个讨论 msdn.microsoft.com/en-us/library/8cw0bt21.aspx 。看看它。一位贡献者指向github.com/dotnet/roslyn/blob/master/docs/compilers/CSharp/… 以获取最新信息,其中 pdbonly 和 full 被提及为相同。 (仅供参考。我不再使用 Windows 或 VS。所以我没有关注那里发生的事情。但正如我所审查的,我的答案中的信息仍然相关,MSDN 文档仍然不正确。)
【解决方案3】:

您只需要 PDB,但不希望将 PDB 文件提供给用户。但是,将它们与您的二进制文件一起为自己提供,使您能够将故障转储加载到 WinDbg 之类的调试器中,并查看您的程序实际失败的地方。当您的代码在您无权访问的机器上崩溃时,这会非常有用。

完全调试将 [Debuggable] 属性添加到您的代码中。这对速度有很大的影响。例如,可能会禁用某些循环优化以使单步执行更容易。此外,它对 JIT 流程的影响很小,因为它开启了跟踪。

【讨论】:

  • 有道理。无论如何,我并没有真正将 DLL 分发给用户——它是一个 ASP.NET 应用程序。但是您能否增强您的答案并证明为什么您应该使用“pdb-only”与“full”?是性能问题吗?
  • @jkohlhepp:我想补充一点,尽管调试发布版本有点棘手,因为您会丢失一些信息(由于 JIT)。几乎总是,您将无法看到方法参数的值。要解决此问题,您可以使用 this 暂时禁用 JIT 优化。
  • 感谢吹镖,感谢 Ilian Pinzon 提供的额外信息。我知道您无法使用发布代码进行完美调试,但拥有 PDB 总比没有好。
  • 使用“完整”设置不会对性能产生影响。它只是允许将调试器附加到正在运行的进程。
  • MSDN 上的好问题 Matt,msdn.microsoft.com/en-us/library/8cw0bt21,正在等待自己的答案。
【解决方案4】:

我正在编写一个未处理的异常处理程序,当使用 pdb-only 时堆栈跟踪包括行号,否则当我选择无时我只会得到子/函数的名称。

如果我不分发 .pdb,即使只有 pdb 构建,我也不会在堆栈跟踪中获得行号。

所以,我正在分发(XCOPY 部署在 LAN 上)pdb 以及我的 VB 应用程序中的 exe。

【讨论】:

    猜你喜欢
    • 2010-10-19
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多