gcc LTO似乎剥离调试符号

时间:2016-11-22 13:40:44

标签: debugging gcc optimization lto

我有项目,在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上进行的。

3 个答案:

答案 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)

一个人可以尝试使用属性((使用)),或者一个人可以尝试以不更改其值的方式使用调试符号。