-Og
。这个开关可以在提供合理运行时性能的同时,解决快速编译和卓越调试体验的问题。总体来说,使用该开关进行开发应该比默认的优化级别 -O0
更好。那么这个开关是否意味着-g
,还是我需要手动添加到我的CXXFLAGS
中?-Og
。这个开关可以在提供合理运行时性能的同时,解决快速编译和卓越调试体验的问题。总体来说,使用该开关进行开发应该比默认的优化级别 -O0
更好。那么这个开关是否意味着-g
,还是我需要手动添加到我的CXXFLAGS
中?查看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
。当使用-Og
时,带有OPT_LEVELS_1_PLUS_NOT_DEBUG
、OPT_LEVELS_1_PLUS_SPEED_ONLY
和OPT_LEVELS_2_PLUS_SPEED_ONLY
标记的选项将不会被启用。-Og
介于-O0
和-O1
之间。这不影响通过-g
选项启用的调试信息的包含。您可能还对不同的-g
选项感兴趣:
-ggdb
覆盖-g
。也就是说,如果在-g
之后设置了-ggdb
,则实际上会忽略-g
选项。-g
等同于-g2
,省略-g
相当于-g0
。-g3
产生比-g2
更大的调试部分,-ggdb3
也是如此。-O0
< -O1
< -Og
< -O2
< -O3
)。strip --strip-debug
的对象大小与-g
级别无关。这符合只有-O
级别对实际代码产生影响的预期,其中-g
确定调试部分。strip --keep-debug
导致对象的大小由-g
级别主导,其次是-O
级别。(因此-g0 -O3
比-g3 -O0
小)。注意:我没有考虑编译时间。随着更积极的优化级别,编译时间可能会增加。我希望调试级别对时间的影响很小(与优化相比),因为这只意味着需要在处理过程中跟踪额外的细节。
下面是我用来测试实际行为的命令(也将-gX
与-ggdbX
进行比较):
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
简短回答: 不,您仍需要手动添加-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
。
gcc手册 --version gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)
在fedora 29 workstation x86_64上。
版本不同,但我认为这很有帮助。
Options for Debugging Your Program
... 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. ...
Options That Control Optimization
... -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
是优化选项之一。如果您没有使用其他优化选项,请考虑在-g与-Og一起使用。
示例:
#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)
然后您会得到文件 sample.Og
的 (未找到调试符号)
。
4.8.x