There's now gdb
and binutils
support for separating debug info from the binaries to be debugged. Docs describing this can be found in:
- gdb: separate debug files
- objcopy --add-gnu-debuglink, --only-keep-debug
- ld --build-id
After a bit of experimenting, I'm able to get gdb
(7.6) to find the debug info using either the build-id and debug-link methods. Here's two gdb
fragments that show the debugger finding the debug info in the non-standard locations, using the build-id and debug-link methods respectively:
(gdb) set debug-file-directory .
(gdb) file uWithBuildId
Reading symbols from /home/peeterj/build-id/uWithBuildId...Reading symbols from /home/peeterj/build-id/.build-id/2d/41caac1bcbeb65255abc3f35624cf9ed37791a.debug...done.
Reading symbols from /home/peeterj/build-id/uWithDebugLink...Reading symbols from /home/peeterj/build-id/uWithDebugLink.debug...done.
To create the debug info files I've used objcopy
and strip
. I've included details of such commands below for reference.
However, the reason I'm looking at this at all is with the hope of being able to build all of our product code with -g
. Currently this breaks the debugger if we try since our shared-lib is too big with relocation truncated to fit messages like:
/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o:(.debug_aranges+0x6): relocation truncated to fit: R_X86_64_32 against `.debug_info'
(and subsequent link failure)
Does anybody know of a way to do one of:
- Generate a standalone file containing all the debug info from the sources that contribute to the binary (i.e all the .o's and .a's that end up in the
ld
command that generates the binary). - Or, instruct
ld
to link without including this debug info in the binary itself, and generate a standalone debug file that can be identified with a build-id or debug-link? I don't see anything in the docs for a single pass method to do this withld
, but theld
docs are big and perhaps I missed it. - Some way to deal with the truncation error above (such a method would allow either the build-id or debug-link methods to work).
sample commands to generate separate debug files for an executable
Here's a sample command line sequence using both the --build-id
and --add-gnu-debuglink
methods:
g++ -g -c -o u.o u.cpp
g++ -o uWithBuildId -Wl,--build-id u.o
g++ -o uWithDebugLink u.o
copyDebugAndStrip uWithBuildId
objcopy --only-keep-debug uWithDebugLink uWithDebugLink.debug
objcopy --add-gnu-debuglink=uWithDebugLink.debug uWithDebugLink
strip -g uWithDebugLink
where copyDebugAndStrip is the following perl code:
#!/usr/bin/perl
my $binary = $ARGV[0] ;
my @p = `objdump --section .note.gnu.build-id -s $binary | tail -2` ;
foreach (@p)
{
chomp ;
s/^ *[\da-f]+ *// ;
s/ .*// ;
s/ //g ;
}
my $buildid = "$p[0]$p[1]" ;
$buildid =~ /^(..)(.*)/ ;
my ($d, $r) = ($1, $2) ;
print "build-id for '$binary': $buildid\n" ;
my $cmd =
"mkdir -p .build-id/$d
rm -f .build-id/$d/$r.debug
objcopy --only-keep-debug $binary .build-id/$d/$r.debug
strip -g $binary
" ;
print $cmd ;
system $cmd ;