【问题标题】:CMake build mode RelWithDebInfoCMake 构建模式 RelWithDebInfo
【发布时间】:2010-11-17 09:53:37
【问题描述】:

我认为我了解发布和调试构建模式之间的区别。主要区别在于,在调试模式下,生成的可执行文件没有经过优化(因为这会使调试更加困难)并且包含调试符号。

在构建 PCRE(WinMerge 的外部依赖项之一)时,我注意到了一种我以前从未见过的构建模式:RelWithDebInfo。

这里提到了Debug和RelWithDebInfo的区别:http://www.cmake.org/pipermail/cmake/2001-October/002479.html。 摘录: “RelwithDebInfo 与 Release 模式非常相似。它生成完全优化的代码,但也构建程序数据库,并插入调试行信息,让调试器有机会随时猜测您在代码中的位置。”

这听起来确实是个好主意,但如何设置并不一定很明显。此链接描述了如何为 VC++ 启用此功能:http://www.cygnus-software.com/papers/release_debugging.html

我是否遗漏了什么,或者将所有发布代码编译为 RelWithDebInfo 没有意义?

【问题讨论】:

  • 默认情况下,CMake 在 Visual Studio 下的 RelWithDebInfo 下通过使用标志 /Ob1 而不是 Release 下的 /Ob2 来部分禁用内联。这会对性能产生很大影响。

标签: c++ visual-studio cmake


【解决方案1】:

就我而言,在没有内部存储相应调试符号的情况下向客户发送代码是在调试生产问题时导致脱发的秘诀。

使用调试符号调试 Release 构建与调试 Debug 构建几乎没有什么不同,因此我建议始终这样做。

也就是说,我不知道是否有任何缺点。如果是这样的话,会很有趣。

【讨论】:

  • gcc (4.8?) 正在为优化构建添加对更好调试信息的支持,因此该建议只会变得更加相关。请参阅the gcc documentation 中的 -fvar-tracking 和 -fvar-tracking-assignments。简而言之,调试信息现在可以跟踪内存和寄存器之间的数据运动,并且给定特定的指令指针,它可以知道在哪里寻找给定的变量。
【解决方案2】:

我错过了什么,还是没有 编译所有发布代码是有意义的 作为 RelWithDebInfo?

这取决于您对客户对调试信息的信任程度。

附加信息:

gcc 将调试信息编码到目标代码中。

这是 gcc 的 pdb 等价物:

How to generate gcc debug symbol outside the build target?

请注意,cmake 似乎不支持这种开箱即用的方法。

【讨论】:

  • 您不必将调试信息发送给您的客户(哦,除非,正如您所提到的,对于嵌入在二进制文件中的平台)
  • 编译器将调试信息放在可执行文件(如VC)中,这不是问题。
  • 我做跨平台开发。我希望 Visual C++ 的人了解目标在其他平台上的后果。我还建议 cmake 用户使用 cmake 邮件列表,因为我发现他们的书面文档不完整。
  • @Juan:在 Linux 平台上,stripobjcopy 都可以从二进制文件中剥离调试信息。使用objcopy,您还可以保留独立的调试信息。然后,您可以无缝调试您的发布版本,而无需将调试信息发送给客户(请参阅--only-keep-debug),耶!
【解决方案3】:

一旦您尝试调试优化的发布版本,您就会知道为什么只有在没有其他出路的情况下才会这样做。

基本上,我看到两种情况下你会需要这个:

  • 您有一个未出现在调试版本中的问题,因此您必须调试发布版本
  • 您遇到了客户崩溃,并使用本地存储的调试信息来了解崩溃。

我不了解你,但在过去十年中,我不得不调试发布代码两次或三次,并设法在客户崩溃不成问题的公司工作。

是的,为您的发布版本提供调试信息可能也是一个好主意,但是 VS 不会以这种方式进行设置,并且对于每个十年中需要此设置的两种情况,不值得设置此设置每次手动起来。既然 CMake 是免费提供的,那就去做吧。

【讨论】:

  • 我想这取决于你处理什么样的代码——我非常使用优化构建的调试符号。尤其是因为我们会在任何意外异常时生成一个小型转储,并且它与符号一起为每个线程提供了一个完整的、可读的调用堆栈。无论如何,这是一个开始调试的好地方。
  • Kim,我很少看到崩溃。我想这归结为编码风格。在我曾经工作了很长时间(几年)的一个大型项目中,有些部分的崩溃比其他部分更常见,有些部分在测试期间发现的崩溃是五年才发生一次的事情。崩溃的概率显然与手动资源管理的数量相关。
  • 虽然您的答案是在 2009 年编写的,但我目前在我的桌面上安装了 VS2008,它实际上在默认情况下(即使用向导创建项目)在 Release 中生成 PDB(Win32 和控制台应用程序) .
【解决方案4】:

生产代码不需要调试信息携带的大小膨胀。

【讨论】:

  • 调试信息是否还在可执行文件中留下足迹?我以为 PDB 携带了所有信息……
  • 在 Linux 上,信息包含在二进制库和共享库的目标代码中。
【解决方案5】:

即使为发布构建生成调试信息,它对于调试目的的用处也远不如调试构建有用。原因是许多变量和中间表达式被优化掉了,因此在调试器中不可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多