I've just stumbled to the very same question.
Previously I just separated my built ELF-binaries with the objcopy's --only-keep-debug
, --strip-debug
, --add-gnu-debuglink
flags.
Now I need to save even more space and so I'm considering using --strip-unneeded
instead of --strip-debug
.
But like you I'm afraid that this may affect my debugging experience.
So, I've made several tests and come to the following conclusions:
--strip-unneeded
strips what is stripped by --strip-debug
and even more. I.e. 'debug' info is considered as a part of 'unneeded' info.
- Debug binaries created with the
--only-keep-debug
flag, not only store info stripped by the --strip-debug
, but also info stripped by the --strip-unneeded
.
- I've not noticed any difference in debugging against
--strip-debug
vs --strip-unneeded
, provided the debug binaries created with the --only-keep-debug
.
Details below:
I've created a very simple C++ project, which contains an executable and a shared library.
The library contains a globally exported function, which is called by the application.
Also the library contains several local functions (i.e. static or in the anonymous namespace), being called by the globally exported function. The code in the local functions just created a crash by just throwing an unhandled exception.
First, I've compiled both binaries with the -g -O0
flags.
Second, I've extracted the debug information from them in a separate binaries and linked these debug files to the original binaries. I.e., for both files:
objcopy --only-keep-debug $FILE $FILE.debug
objcopy --add-gnu-debuglink=$FILE.debug $FILE
After this point I had unstripped binaries also having separate correspondent linked debug binaries.
Then I've copied these files into two additional directories. In the first one I've done --strip-debug
against the original binaries and in another I've done --strip-unneeded
.
Considering file sizes, the original files where obviously the biggest, the files in strip-unneeded dir where the smallest, and the files in the strip-debug dir were in the middle.
Also, additionally running --strip-debug
against the files in the strip-unneeded dir has not changed the file sizes, meaning that --strip-debug
strips just some subset of what is stripped by --strip-unneeded
.
I've then compared section listing of all the three variants by running readelf -S
against all of them.
Looking at them, it could be seen that --strip-debug
strips the following sections: .debug_arranges
, .debug_info
, .debug_abbrev
, .debug_line
and .debug_str
, and also somewhat reduced the .symtab
and .strtab
sections.
--strip-unneeded
also additionally completely removes .symtab
and .strtab
sections.
I've then run readelf -S
against the debug binaries, which I'd got with the --only-keep-debug
flag. The sections there had all the sections removed by --strip-unneeded
. So, it not only contained .debug_arranges
, .debug_info
, .debug_abbrev
, .debug_line
and .debug_str
, but also .symtab
and .strtab
. And the sizes of the sections were almost identical to their original sizes.
I've then tried to step-by-step debug all the three variants and haven't noticed any difference between them. Also I've produced crashes and core dumps with all of them and then tried to debug against the core dumps - also no difference.
Versions used:
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
GNU objcopy (GNU Binutils for Ubuntu) 2.26.1
GNU strip (GNU Binutils for Ubuntu) 2.26.1