Debugging 同时使用-g3和-O3编译

Debugging 同时使用-g3和-O3编译,debugging,optimization,gcc,compiler-construction,build,Debugging,Optimization,Gcc,Compiler Construction,Build,我见过的大多数构建环境至少有两种策略:调试构建与最终/优化/发布构建。对于gcc,这通常意味着-g与-O的某些版本。现在我看到了这样一种情况:优化构建是使用-O3构建的,而调试版本是使用-g3和-O3构建的mangcc确实表明这是可能的,但对于真正的调试目的来说,这似乎是违反直觉的 回顾让我想起了-Og,它允许不干扰调试的优化。这对我来说是有道理的,但是有什么令人信服的理由可以用-O3-g3进行调试,除非您基本上是在调试gcc自己的优化功能?有时人们编写错误的代码-例如,可能是导致未定义行为的代

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


回顾让我想起了
-Og
,它允许不干扰调试的优化。这对我来说是有道理的,但是有什么令人信服的理由可以用
-O3-g3
进行调试,除非您基本上是在调试gcc自己的优化功能?

有时人们编写错误的代码-例如,可能是导致未定义行为的代码。现在让我们假设,在低优化或无优化的情况下,未定义的行为似乎“正确”工作,但它会在
-O3
处导致灾难性的崩溃。您将要在
-O3
处调试此问题,对吗?因此,您别无选择,只能添加一个
-g
标志,然后继续前进,即使优化可能会在某种程度上影响调试体验

将“调试/发布”轴与“优化/未优化”轴合并在一起的构建系统通常存在一个大问题。实际上,它们应该是正交的——例如,通常希望有一个带有日志记录的“调试”构建,但在启用优化的情况下仍然可以快速运行。类似地,如果优化的构建中没有可用的调试符号,跟踪与优化器相关的bug可能非常困难

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

.. 或者,如果您试图调试优化的代码(可能与未优化的代码有不同的bug)。问题到底是什么?问题是为什么我所关注的环境是使用
-O3-g3
编译调试版本。我正在试图找出哪些信息是一个人可以学习的,而仅仅用
-g3
是无法学习的。我模模糊糊地知道答案,您也提供了答案,但我正在寻找示例或进一步的澄清。我基本上不同意客户发布版本一般应关闭调试符号的建议。事实上,MSVC中的Microsoft有默认策略为调试/发布版本生成符号,XCode也是如此。只有非常有限的代码集(如热路径代码或需要极端优化的数学代码)才应该关闭调试符号。外部符号也可以,您可能只是不想向客户提供内部秘密。我想,除非是开源或是你的商业模式的一部分。确切地说,但部署调试符号不会泄露源代码,通常是作为提供更好调试体验的手段分发的(例如,Microsoft公共符号服务器),我将编辑图表以匹配我在回答中所说的内容;该轴应该包括其他调试细节,如日志记录等。