title: gnu ld/gdb: separate debug files. How to produce the debug file when there's too much debug info to link?
body: <p>There's now <code>gdb</code> and <code>binutils</code> support for separating debug info from the binaries to be debugged.  Docs describing this can be found in:</p>
  
  <ul>
  <li><a href="http://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html" rel="noreferrer">gdb: separate debug files</a> </li>
  <li><a href="http://sourceware.org/binutils/docs-2.23.1/binutils/objcopy.html#objcopy" rel="noreferrer">objcopy --add-gnu-debuglink, --only-keep-debug</a> </li>
  <li><a href="http://sourceware.org/binutils/docs/ld/Options.html#Options" rel="noreferrer">ld --build-id</a></li>
  </ul>
  
  <p>After a bit of experimenting, I'm able to get <code>gdb</code> (7.6) to find the debug info using either the build-id and debug-link methods.  Here's two <code>gdb</code> fragments that show the debugger finding the debug info in the non-standard locations, using the build-id and debug-link methods respectively:</p>
  
  <pre><code>(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.
  </code></pre>
  
  <p>To create the debug info files I've used <code>objcopy</code> and <code>strip</code>.  I've included details of such commands below for reference.</p>
  
  <p>However, the reason I'm looking at this at all is with the hope of being able to build <em>all</em> of our product code with <code>-g</code>.  Currently this breaks the debugger if we try since our shared-lib is too big with relocation truncated to fit messages like:</p>
  
  <pre><code>/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'
  </code></pre>
  
  <p>(and subsequent link failure)</p>
  
  <p>Does anybody know of a way to do one of:</p>
  
  <ol>
  <li>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 <code>ld</code> command that generates the binary).</li>
  <li>Or, instruct <code>ld</code> 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 with <code>ld</code>, but the <code>ld</code> docs are big and perhaps I missed it.</li>
  <li>Some way to deal with the truncation error above (such a method would allow either the build-id or debug-link methods to work).</li>
  </ol>
  
  <h2> sample commands to generate separate debug files for an executable </h2>
  
  <p>Here's a sample command line sequence using both the <code>--build-id</code> and <code>--add-gnu-debuglink</code> methods:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>where copyDebugAndStrip is the following perl code:</p>
  
  <pre><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 ;
  </code></pre>