I am currently trying to use the --gsplit-dwarf
gcc
flag in order to automatically create and separate debug symbols from build libraries/executables. More info on DWARF Obj files. However, what I have observed is that split-dwarf
still leaves a lot of unnecessary information in the remaining .o
file. What I would like to do is use strip
to remove that info but still have it be compatible for debugging using the .dwo
/.dwp
files; however, it seems that this does not work. I want to strip the release executables for space savings and for further obfuscation, and was hoping split-dwarf
would allow me to do so.
Example app app.cpp
int main()
{
int a = 1;
std::cout << "Split DWARF test" << std::endl;
return 0;
}
Compiling:
g -c -gsplit-dwarf app.cpp -o app_dwarf.o
Linking:
g app_dwarf.o -o app_dwarf -fuse-ld=gold -Wl,--gdb-index
Examine the build artifact:
readelf -wi app_dwarf
Contents of the .debug_info section:
Compilation Unit @ offset 0x0:
Length: 0x30 (32-bit)
Version: 4
Abbrev Offset: 0x0
Pointer Size: 8
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_low_pc : 0x8da
<14> DW_AT_high_pc : 0x9c
<1c> DW_AT_stmt_list : 0x0
<20> DW_AT_GNU_dwo_name: (indirect string, offset: 0x0): app_dwarf.dwo
<24> DW_AT_comp_dir : (indirect string, offset: 0xe): /home/ross/Desktop/dwarf_test
<28> DW_AT_GNU_pubnames: 1
<28> DW_AT_GNU_addr_base: 0x0
<2c> DW_AT_GNU_dwo_id : 0xdf705add23e14a0b
Can see it references the dwo
... this also works in GDB and does not work when I remove the dwo
file. However, if I look at the symbol table for the build artifact (the executable), the full symbol table is still there.
If I strip the executable, the table is removed and the size is reduced, but it also strips away the debug_info
that references the dwo
file.
Also separately, shouldn't the symbol table be included in the dwo
file?
Hoping some direction can be provided here that will allow me to capture all of the debug info outside of the artifact itself to be kept for debugging at a later time.
The alternate way to do this would be a multi stage approach where we do something like:
g -g -o app_dwarf app.cpp
objcopy --only-keep-debug app_dwarf app_dwarf.debug
objcopy --add-gnu-debuglink=app_dwarf.debug app_dwarf
strip --strip-unneeded app_dwarf
But would need to divide that up into compile and link steps so that build times and resources are affected less. I thought that was the whole point of the single gsplit-dwarf
flag, though.
CodePudding user response:
If I strip the executable, the table is removed and the size is reduced, but it also strips away the debug_info that references the dwo file.
Correct.
The right way is to keep the unstripped copy of the executable and the .dwp
file, while distributing the stripped copy to end-users.
I thought that was the whole point of the single gsplit-dwarf flag, though.
No.
The motivation is explained here. To quote: "By splitting the debug information into two parts at compile time -- one part that remains in the .o file and another part that is written to a parallel .dwo ("DWARF object") file -- we can reduce the total size of the object files processed by the linker."
If the total size of object files processed by the linker isn't a problem for you (it rarely is for binaries under 1 GiB), then you don't really need fission (though it may still speed up your link a bit).