Bloaty: A super handy linux binary analysis
bloaty is a great tool from Google for binary size analysis. We were just wondering why the binary size became so large for our code in production and bloaty is great at that.
For example, if you run it against a release build of bloaty itself, just for fun:
./bloaty -d sections ./bloaty
FILE SIZE VM SIZE
-------------- --------------
35.8% 16.2Mi 0.0% 0 .debug_info
25.3% 11.4Mi 0.0% 0 .debug_loc
11.6% 5.26Mi 0.0% 0 .debug_str
6.5% 2.93Mi 0.0% 0 .debug_ranges
6.3% 2.83Mi 42.5% 2.83Mi .rodata
5.7% 2.60Mi 0.0% 0 .debug_line
4.4% 2.00Mi 29.9% 2.00Mi .text
0.0% 0 15.1% 1.01Mi .bss
1.3% 585Ki 0.0% 0 .strtab
1.0% 441Ki 6.5% 441Ki .data
0.7% 316Ki 0.0% 0 .debug_abbrev
0.6% 279Ki 4.1% 279Ki .eh_frame
0.5% 235Ki 0.0% 0 .symtab
0.1% 50.3Ki 0.7% 50.3Ki .eh_frame_hdr
0.1% 46.9Ki 0.7% 46.8Ki .gcc_except_table
0.1% 38.3Ki 0.0% 0 .debug_aranges
0.0% 14.2Ki 0.1% 7.80Ki [24 Others]
0.0% 7.78Ki 0.1% 7.72Ki .dynstr
0.0% 6.20Ki 0.1% 6.14Ki .dynsym
0.0% 4.89Ki 0.1% 4.83Ki .rela.plt
0.0% 3.30Ki 0.0% 3.23Ki .plt
100.0% 45.2Mi 100.0% 6.66Mi TOTAL
You can easily tell most of the size is actually debug information - 79.2% (35.8+25.3+11.6+6.5)! This is actually a pretty common pattern for C++ binarie and most of the size is debug info. These debug symbols can be offloaded to a symbol package and installed on-demand for coredumps and debugging if needed, if size is becoming an issue.
Another interesting analysis you can do is to look at how much each file is contributing to your different sections (text, string, etc). Again, using bloaty itself as an example:
./bloaty -d sections,compileunits ./bloaty
...
4.4% 2.00Mi 29.9% 2.00Mi .text
33.7% 688Ki 33.7% 688Ki [117 Others]
9.4% 193Ki 9.4% 193Ki /home/yzha/local/github/bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc
6.2% 125Ki 6.2% 125Ki /home/yzha/local/github/bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc
5.6% 115Ki 5.6% 115Ki /home/yzha/local/github/bloaty/third_party/capstone/arch/AArch64/AArch64InstPrinter.c
4.6% 94.6Ki 4.6% 94.6Ki /home/yzha/local/github/bloaty/third_party/capstone/arch/Sparc/SparcInstPrinter.c
4.6% 93.3Ki 4.6% 93.3Ki /home/yzha/local/github/bloaty/third_party/capstone/arch/ARM/ARMDisassembler.c
4.1% 83.3Ki 4.1% 83.3Ki /home/yzha/local/github/bloaty/src/bloaty.cc
3.9% 79.3Ki 3.9% 79.3Ki /home/yzha/local/github/bloaty/third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp
3.8% 78.7Ki 3.8% 78.7Ki /home/yzha/local/github/bloaty/third_party/capstone/arch/PowerPC/PPCInstPrinter.c
3.0% 62.1Ki 3.0% 62.1Ki /home/yzha/local/github/bloaty/third_party/protobuf/src/google/protobuf/text_format.cc
2.8% 56.9Ki 2.8% 56.9Ki /home/yzha/local/github/bloaty/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc
2.5% 50.1Ki 2.5% 50.1Ki /home/yzha/local/github/bloaty/third_party/protobuf/src/google/protobuf/extension_set.cc
2.3% 46.0Ki 2.3% 46.0Ki /home/yzha/local/github/bloaty/third_party/capstone/arch/ARM/ARMInstPrinter.c
2.1% 42.2Ki 2.1% 42.2Ki /home/yzha/local/github/bloaty/third_party/protobuf/src/google/protobuf/map_field.cc
2.1% 42.1Ki 2.1% 42.1Ki /home/yzha/local/github/bloaty/third_party/protobuf/src/google/protobuf/wire_format.cc
2.0% 40.6Ki 2.0% 40.6Ki /home/yzha/local/github/bloaty/third_party/capstone/arch/SystemZ/SystemZDisassembler.c
1.7% 34.0Ki 1.7% 34.0Ki /home/yzha/local/github/bloaty/src/dwarf.cc
1.5% 30.9Ki 1.5% 30.9Ki /home/yzha/local/github/bloaty/src/elf.cc
1.5% 30.2Ki 1.5% 30.2Ki /home/yzha/local/github/bloaty/third_party/protobuf/src/google/protobuf/repeated_field.cc
1.5% 30.1Ki 1.5% 30.1Ki /home/yzha/local/github/bloaty/third_party/capstone/arch/AArch64/AArch64Disassembler.c
1.3% 27.0Ki 1.3% 27.0Ki /home/yzha/local/github/bloaty/third_party/re2/re2/re2.cc
...
It looks like protobuf is a big contributor. Now we can add source filter to see how much:
./bloaty -d sections,compileunits --source-filter=protobuf ./bloaty
...
100.0% 24.1Mi 100.0% 1013Ki TOTAL
Filtering enabled (source_filter); omitted file = 21.1Mi, vm = 5.67Mi of entries
There are a lot of output here, but you can see protobuf contributs to 24.1/45.2=53% of size of bloaty itself. If you want you can also dive into different sections to see how much each individual files contributes to as well.