30

最近更新了 GCC 4.8 的文档,现在引入了一个新的优化开关,-Og. 这

[..] 满足快速编译和卓越调试体验的需求,同时提供合理水平的运行时性能。开发的整体体验应该优于默认优化级别-O0。

此开关是否暗示-g或我必须CXXFLAGS手动将其添加到我的?

4

3 回答 3

40

查看 GCC 4.9.2 源代码 (gcc/opts.c) 表明它-Og与 相同-O1,但禁用了一些可能导致更差调试体验的标志:

/* in function default_options_optimization: */
    case OPT_Og:
      /* -Og selects optimization level 1.  */
      opts->x_optimize_size = 0;
      opts->x_optimize = 1;
      opts->x_optimize_fast = 0;
      opts->x_optimize_debug = 1;
      break;

几步之后,函数maybe_default_option被调用,带有一组选项和x_optimize_debug标志。标有 的选项OPT_LEVELS_1_PLUS_NOT_DEBUG,使用OPT_LEVELS_1_PLUS_SPEED_ONLYOPT_LEVELS_2_PLUS_SPEED_ONLY不启用-Og

所以这就是“应该比-O0更好”的说法的来源。-Og介于-O0和之间-O1。这不会影响包含将通过-g选项启用的调试信息。您可能还会对不同的-g选项感兴趣:

  • 选项-ggdb覆盖-g。也就是说,如果您设置-ggdbafter -g,该-g选项实际上会被忽略。
  • 选项-g等于-g2,省略-g与 相同-g0
  • Option产生的-g3调试部分比-g2对.-ggdb3-ggdb2
  • 更高的优化级别都会导致代码和调试部分的增加。( -O0< -O1< -Og< -O2< -O3)。
  • strip --strip-debug导致与-g级别无关的相同对象大小。这符合预期,即只有级别对确定调试部分-O的实际代码有影响。-g
  • strip --keep-debug导致对象的大小由-g级别决定,其次是-O级别。(所以-g0 -O3小于-g3 -O0)。

注意:这里我没有考虑编译的时间。它可能会随着更积极的优化级别而增加。我希望调试级别只会对时间产生很小的影响(与优化相比),因为它只是意味着在传递过程中需要跟踪额外的细节。

这是我用来测试实际行为的命令(也比较-ggdbX而不是-gX):

for g in -g0 -g2 -g3;do
    for O in -O0 -O1 -O2 -O3 -Og; do
        flags="$g $O";
        gcc -fPIC -rdynamic -c -Wall -Wextra -Ilib ltunify.c -o obj/gL_"${flags// /_}_.o" $flags || break;
    done;
done
于 2014-11-22T10:25:36.270 回答
23

简短回答:不,您仍然必须-g手动添加。

长答案

我一直在努力从源代码中直接找到一个硬性答案,所以我决定使用这里描述的方法自己测试它:如何检查程序是否使用调试符号编译?

-O3我用标志构建了一个可执行文件,没有-g. objdump --syms <file> | grep debug正如预期的那样,使用没有产生任何结果。

-g然后我构建了一个带有和不带有任何优化标志的可执行文件。相同的objdump命令产生了六个结果,如下所示:

0000000000000000 l d .debug_info 0000000000000000 .debug_info

我终于用-Og标志构建了一个可执行文件,没有-g. 该objdump命令没有产生任何结果。这意味着在这种情况下不存在调试符号。

虽然我无法从 GCC 本身找到任何明确的文档,但Gentoo Wiki(如 Marco Scannadinari 之前提到的)证实了我的断言,-Og这并不意味着-g.

于 2014-03-03T17:38:21.693 回答
1

--version gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)fedora 29 工作站 x86_64 上的 gcc 手册。

不同的版本,但我认为它很有帮助。

调试程序的选项

...
  If you are not using some other optimization option, consider using -Og with -g.  With no -O option at
  all, some compiler passes that collect information useful for debugging do not run at all, so that -Og may
  result in a better debugging experience.
...

控制优化的选项

...
  -Og Optimize debugging experience.  -Og enables optimizations that do not interfere with debugging. It
      should be the optimization level of choice for the standard edit-compile-debug cycle, offering a
      reasonable level of optimization while maintaining fast compilation and a good debugging experience.
...

所以,我们可以看到-Og是优化选项之一。如果您没有使用其他优化选项,请考虑将 -Og 与 -g 一起使用。

样本:

#include <stdio.h>

int main(int argc, char *argv[]) {
    int n;

    for (n=0; n<10; n++) {
       printf("Print Number: %d\n", n);
    }
    return 0;
}

编译:

[user@localhost myctest]$ gcc sample.c -o sample
[user@localhost myctest]$ gcc sample.c -o sample.Og -Og
[user@localhost myctest]$ gcc sample.c -o sample.g -g
[user@localhost myctest]$ gcc sample.c -o sample.Og.g -Og -g

然后可以看到编译文件的大小:

[user@localhost myctest]$ ls -l --human-readable sample*
-rwxrwxr-x. 1 user user 18K Aug 10 19:43 sample
-rw-rw-r--. 1 user user 162 Aug 10 19:43 sample.c
-rwxrwxr-x. 1 user user 21K Aug 10 19:43 sample.g
-rwxrwxr-x. 1 user user 18K Aug 10 19:43 sample.Og
-rwxrwxr-x. 1 user user 21K Aug 10 19:44 sample.Og.g

然后您可以使用readelf(GNU readelf 版本 2.31.1-13.fc29)重新检查这些文件中的调试信息。

[user@localhost myctest]$ readelf --debug-dump=aranges sample
[user@localhost myctest]$ readelf --debug-dump=aranges sample.g
Contents of the .debug_aranges section:

  Length:                   44
  Version:                  2
  Offset into .debug_info:  0x0
  Pointer Size:             8
  Segment Size:             0

    Address            Length
    0000000000401126 000000000000003d 
    0000000000000000 0000000000000000 

[user@localhost myctest]$ readelf --debug-dump=aranges sample.Og
[user@localhost myctest]$ readelf --debug-dump=aranges sample.Og.g
Contents of the .debug_aranges section:

  Length:                   44
  Version:                  2
  Offset into .debug_info:  0x0
  Pointer Size:             8
  Segment Size:             0

    Address            Length
    0000000000401126 0000000000000028 
    0000000000000000 0000000000000000 
 

可以看到仅通过-Og选项编译的文件中没有调试信息。您还可以使用 的选项查看更多信息readelf --debug-dump=。例如readelf --debug-dump=aranges,info sample.g. 和readelf --headers sample.g | grep debug

man readelf

--debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info, =trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]

您可以使用 gdb 检查:

[user@localhost myctest]$ gdb sample.Og
GNU gdb (GDB) Fedora 8.2-3.fc29
Copyright (C) 2018 Free Software Foundation, Inc.
...

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from sample.Og...(no debugging symbols found)...done.
(gdb) 

然后你得到(no debugging symbols found)文件sample.Og。

4.8.x

对于 4.8.x 文档,在Debugging-Options-Og一节中没有提及,仅在Optimize-Options一节中介绍。

于 2021-08-10T12:02:01.623 回答