我有项目,在ARM Cortex-M4处理器上运行,我试图包含gcc链接时优化(LTO)功能。
目前我的编译和链接标志是:
CFLAGS = -ggdb -ffunction-sections -Og
LDFLAGS = -Wl,-gc-sections
这些标志一切正常,我能够正确调试项目。
然后我尝试将-flto
添加到CFLAGS。虽然该程序运行正常,但我无法再调试项目,gdb抱怨缺少调试符号。在ELF文件上运行objdump -g
(启用LTO)会提供以下输出:
xxx.elf: file format elf32-littlearm
Contents of the .debug_frame section:
00000000 0000000c ffffffff CIE
Version: 1
Augmentation: ""
Code alignment factor: 2
Data alignment factor: -4
Return address column: 14
DW_CFA_def_cfa: r13 ofs 0
00000010 00000018 00000000 FDE cie=00000000 pc=08002a3c..08002a88
DW_CFA_advance_loc: 2 to 08002a3e
DW_CFA_def_cfa_offset: 16
DW_CFA_offset: r4 at cfa-16
DW_CFA_offset: r5 at cfa-12
DW_CFA_offset: r6 at cfa-8
DW_CFA_offset: r14 at cfa-4
DW_CFA_nop
0000002c 0000000c ffffffff CIE
Version: 1
Augmentation: ""
Code alignment factor: 2
Data alignment factor: -4
Return address column: 14
DW_CFA_def_cfa: r13 ofs 0
0000003c 0000000c 0000002c FDE cie=0000002c pc=08002a88..08002a98
请注意丢失的.debug_info
部分。回到项目设置,只从CFLAGS中删除-flto
解决了问题。现在,没有LTO的ELF文件上的objdump -g
会显示.debug_info
部分,其中包含对项目中函数的正确引用,并且调试再次正常工作。
如何让LTO和调试符号一起很好地发挥作用?
修改:忘记包含我的gcc信息。我使用的是GNU ARM Embedded Toolchain,测试是在版本5.4-2016q2和5.4-2016q3上进行的。
答案 0 :(得分:5)
这是因为gcc不支持将-flto
与-g
结合使用。
您可以找到详细信息GCC Online Docs - Optimize Options
“将
-flto
与-g
结合使用目前是实验性的,并且可以预期 产生意想不到的结果。“
使用-flto
时,-g
将被忽略。
答案 1 :(得分:1)
现在情况应该已经有所改善。 GCC 8终于有了早期调试信息的改进: http://hubicka.blogspot.com/2018/06/gcc-8-link-time-and-interprocedural.html
虽然可以使用LTO和-g进行构建并调试生成的结果 二进制文件,调试信息有点像C,而不是 与语言程序相对应的调试信息最初是 写出来。这终于解决了。 [...]主要思想是生产 DWARF在编译的早期,将其存储到目标文件中 链接时只需将必要的片段复制到最终目标文件中,而无需 需要编译器解析并更新它。
答案 2 :(得分:0)
一个人可以尝试使用属性((使用)),或者一个人可以尝试以不更改其值的方式使用调试符号。