I have project, running on an ARM Cortex-M4 processor, where I'm trying to include the gcc link-time optimization (LTO) feature.
Currently my compilation and linking flags are:
CFLAGS = -ggdb -ffunction-sections -Og
LDFLAGS = -Wl,-gc-sections
Everything works fine with these flags and I'm able to correctly debug the project.
Then I tried adding -flto
to CFLAGS. Although the program works fine, I'm no longer able to debug the project, with gdb complaining of missing debugging symbols. Running objdump -g
on the ELF file (with LTO enabled) gives the following output:
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
Note the missing .debug_info
section. Going back to the project settings and only removing -flto
from CFLAGS solves the problem. objdump -g
on the ELF file without LTO now shows a .debug_info
section, filled with the proper references to the functions in my project, and debugging works fine again.
How to get LTO and debug symbols to play well together?
Edit: forgot to include my gcc information. I'm using the GNU ARM Embedded Toolchain, and the test was performed on versions 5.4-2016q2 and 5.4-2016q3.
The situation should have improved by now. GCC 8 finally got the early debug info improvements: http://hubicka.blogspot.com/2018/06/gcc-8-link-time-and-interprocedural.html
While it was possible to build with LTO and -g and debug the resulting binary, the debug information was kind of messed up C, instead of debug info corresponding to the language program was originally written in. This is finally solved. [...] The main idea is to produce DWARF early during compilation, store it into object files and during link-time just copy necessary fragments to final object files without need for compiler to parse it and update it.
But note that -gsplit-dwarf
won't work with LTO.