5

There are a number of flags around debug info compression in gcc and binutils. Here, I'm interested in the interplay between the following four flags in a standard sort of C++ project that creates a number of object files with the compiler and then uses the compiler to drive a link step that combines the object files into various final binaries:

  • -Wa,--compress-debug-sections=zlib-gabi
  • -Wa,--nocompress-debug-sections
  • -Wl,--compress-debug-sections=zlib-gabi
  • -Wl,--compress-debug-sections=none

So, we can imagine four possibilities. We have compiled our object files with either no compression in the assembler or with -Wa,--compress-debug-sections=zlib-gabi, and we have linked our object files into binaries with either no compression in the linker or with -Wl,--compress-debug-sections=zlib-gabi enabled.

The combination -Wa,--nocompress-debug-sections for compile and -Wl,--compress-debug-sections=none is uninteresting. Presumably no compression at all takes place.

The next two combinations are somewhat more interesting:

  • With -Wa,--compress-debug-sections=zlib-gabi for the assembler and -Wl,--compress-debug-sections=none for the linker, it seems like the linker would need to spend time to uncompress the debug information from each object file before merging it and emitting new uncompressed debug info sections for the final binaries.

  • With -Wa,--nocompress-debug-sections for the assembler and -Wl,--compress-debug-sections=zlib-gabi for the linker, it seems clear that the assembler won't spend time compressing the debug info for the object files, and the linker will spend time compressing the final merged debug info sections.

Are my assumptions and understanding of these two cases mostly correct? If not, what have I misunderstood?

That leaves the most interesting case:

  • With -Wa,--compress-debug-sections=zlib-gabi to the assembler AND -Wl,--compress-debug-sections=zlib-gabi to the linker, what happens here? If my understanding for the above cases is correct, I'd expect that the assembler would do the work to compress debug information in each object file, and then the linker would need to spend time decompressing it, then do merging, and finally recompress the merged debug info sections. Is that correct? Or is the linker somehow able to magically directly merge the compressed debug info sections in the object files directly into the final compressed debug info sections for the link step, avoiding the uncompress/recompress cycle?

Overall, I'm just looking to understand what I should default these flags to in the build system for the best build performance. I'll of course do some benchmarking, but I'm interested to understand the theory of operation here as well, as it will help me understand any build benchmark results around these flags.

acm
  • 12,183
  • 5
  • 39
  • 68

1 Answers1

3

Sadly, I am not knowledgeable about this topic.
However, I stumbled across the following which might answer the first part of your question.

Recently, the -Wa,--compress-debug-sections option has been made available. This option reduces the total size of the object files sent to the linker by more than a third, so that the debug information now accounts for 70-80% of the total size of the object files. The output file is unaffected: the linker decompresses the debug information in order to link it, and outputs the uncompressed result (there is an option to recompress the debug information at link time, but this step would only reduce the size of the output file without improving link time or memory usage).

From: https://gcc.gnu.org/wiki/DebugFission (section: Problems with Size of the Debug Information)

So, looking at that quote it seems you are right with your assumption for these two cases:

  • -Wa,--compress-debug-sections=zlib-gabi and -Wl,--compress-debug-sections=none
  • -Wa,--nocompress-debug-sections and -Wl,--compress-debug-sections=zlib-gabi
Deniz Bahadir
  • 503
  • 1
  • 4
  • 16