15

我有一个项目,在 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部分。回到项目设置并仅从-fltoCFLAGS 中删除即可解决问题。objdump -g在没有 LTO 的 ELF 文件上现在显示一个.debug_info部分,其中填充了对我项目中函数的正确引用,并且调试再次正常工作。

如何让 LTO 和调试符号一起玩得很好?

编辑:忘记包含我的 gcc 信息。我使用的是GNU ARM Embedded Toolchain,测试是在 5.4-2016q2 和 5.4-2016q3 版本上进行的。

4

3 回答 3

7

这是因为 gcc 不支持 combine -fltowith -g

您可以找到详细信息GCC Online Docs - Optimize Options

“结合-flto目前-g是实验性的,预计会产生意想不到的结果。”

当您使用-flto时,-g将被忽略。

于 2017-07-28T02:12:21.393 回答
5

现在情况应该已经好转了。GCC 8 终于得到了早期的调试信息改进: http ://hubicka.blogspot.com/2018/06/gcc-8-link-time-and-interprocedural.html

虽然可以使用 LTO 和 -g 构建并调试生成的二进制文件,但调试信息有点混乱 C,而不是对应于最初编写的语言程序的调试信息。这终于解决了。[...] 主要思想是在编译早期生成 DWARF,将其存储到目标文件中,在链接时只需将必要的片段复制到最终目标文件,而无需编译器对其进行解析和更新。

但请注意,这-gsplit-dwarf不适用于 LTO。

于 2019-02-04T00:17:22.097 回答
0

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

于 2018-08-19T07:41:30.943 回答