Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc LTO appears to strip debugging symbols

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.

like image 442
swineone Avatar asked Nov 22 '16 13:11

swineone


People also ask

How do I get rid of debug symbols?

To remove debugging symbols from a binary (which must be an a. out or ELF binary), run strip --strip-debug filename. Wildcards can be used to treat multiple files (use something like strip --strip-debug $LFS/tools/bin/*).

What is the meaning of debug symbols?

A debug symbol is a special kind of symbol that attaches additional information to the symbol table of an object file, such as a shared library or an executable.

How do you know if a debug symbol is present?

To check if there's debug info inside the kernel object, you can add the following at the end of the objdump command: | grep debug . If this string is found, you know the kernel object contains debug information. If not, then it's a "clean" kernel object.

Do debug symbols affect performance?

Load time will be increased when the debug symbols are present over when not present. The on-disk footprint will be larger. If you compiled with zero optimization then you really lose nothing. If you set optimization, then the optimized code will be less optimized because of the debug symbols.


2 Answers

It's because gcc does not support combine -flto with -g.

You can find the details GCC Online Docs - Optimize Options

"Combining -flto with -g is currently experimental and expected to produce unexpected results."

When you use -flto, the -g will be ignored.

like image 178
alpha Avatar answered Oct 19 '22 05:10

alpha


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.

like image 5
Trass3r Avatar answered Oct 19 '22 05:10

Trass3r