There's now gdb and binutils support for separating debug info from the binaries to be debugged. Docs describing this can be found in:
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
ldcommand that generates the binary). - Or, instruct
ldto 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 thelddocs 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 ;