【问题标题】:Compiling with both -g3 and -O3同时使用 -g3 和 -O3 进行编译
【发布时间】:2013-08-02 17:44:59
【问题描述】:

我见过的大多数构建环境至少有两种策略:调试构建与最终/优化/发布构建。对于 gcc,这通常意味着 -g-O 的某个版本。现在我看到优化版本是用-O3 构建的,而调试版本是用-g3 -O3 构建的。 man gcc 确实表明这是可能的,但对于真正的调试目的,这对我来说似乎违反直觉。

查看http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html 让我想起了-Og,它允许在不干扰调试的情况下进行优化。这对我来说是有道理的,但是除非您基本上是在尝试调试 gcc 自己的优化能力,否则有什么令人信服的理由使用 -O3 -g3 进行调试?

【问题讨论】:

  • .. 或者如果您正在尝试调试优化的代码(可能与未优化的代码有不同的错误)。究竟是什么问题?
  • 问题是为什么我正在查看的环境使用-O3 -g3 编译调试版本。我试图弄清楚一个人可以学到哪些信息,而只用-g3 是无法学到的。我隐约知道您也提供了答案,但我正在寻找示例或进一步澄清。

标签: debugging optimization gcc compiler-construction build


【解决方案1】:

有时人们会编写糟糕的代码——例如,可能会导致未定义行为的代码。现在假设在低优化或没有优化的情况下,未定义的行为似乎“正常”工作,但它会导致-O3 的灾难性崩溃。你会想在-O3 调试这个问题,对吧?因此,您别无选择,只能添加 -g 标志并前往城镇,即使调试体验可能会因优化而受到一定程度的影响。

将“调试/发布”轴与“优化/未优化”轴混为一谈的构建系统通常存在一个大问题。确实,它们应该是正交的——例如,通常希望有一个带有日志记录的“调试”构建,但在启用优化的情况下仍然可以快速运行。同样,如果您的优化构建中没有可用的调试符号,则可能很难追踪与优化器相关的错误。

                   +--------------------------------+
                   |           Optimizations        |
                   +-----------------+--------------+
                   |        On       |     Off      |
 +----------+------+-----------------+--------------+
 |          |  On  | Debug optimized |  Best debug  |
 |  Debug   |      |    code         |  experience  |
 | Logging/ +------+-----------------+--------------+
 | Symbols  |  Off |   Release build | Probably not |
 |          |      |  for customers  |    useful    |
 +----------+------+-----------------+--------------+

【讨论】:

  • 我非常不同意客户的发布版本通常应关闭调试符号的建议。事实上,微软在 MSVC 中的默认策略是为调试/发布版本生成符号,XCode 也是如此。只有非常受限的代码集(如热路径代码或需要极端优化的数学代码)才应该关闭调试符号。
  • 外部符号很好,只是您可能不想将内部秘密调味料提供给您的客户。除非开源或其他业务模式的一部分,我猜。
  • 明确地说,但部署调试符号并不会泄露源代码,并且通常作为提供更好调试体验的一种方式分发(例如,Microsoft 公共符号服务器)
  • 我将编辑图表以匹配我在答案中所说的内容;该轴应该包括其他调试细节,如日志/等。
  • "可能没用" = "对 Valgrind 有好处,可以在极其烦人的 UB 错误上运行"
猜你喜欢
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 2012-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 2018-04-08
相关资源
最近更新 更多