现在有gdb
and binutils
支持将调试信息与要调试的二进制文件分开。描述这一点的文档可以在以下位置找到:
-
gdb:单独的调试文件 http://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
-
objcopy --add-gnu-debuglink, --only-keep-debug http://sourceware.org/binutils/docs-2.23.1/binutils/objcopy.html#objcopy
- ld --构建 ID http://sourceware.org/binutils/docs/ld/Options.html#Options
经过一番实验后,我能够得到gdb
(7.6) 使用 build-id 和 debug-link 方法查找调试信息。这里有两个gdb
显示调试器分别使用 build-id 和 debug-link 方法在非标准位置查找调试信息的片段:
(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.
创建我使用过的调试信息文件objcopy
and strip
。我在下面提供了此类命令的详细信息以供参考。
然而,我之所以关注这个,是希望能够构建all我们的产品代码-g
。目前,如果我们尝试的话,这会破坏调试器,因为我们的共享库太大,重定位被截断以适应如下消息:
/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'
(以及随后的链接失败)
有谁知道一种方法可以做到以下之一:
- 生成一个独立文件,其中包含来自对二进制文件有贡献的源的所有调试信息(即最终出现在
ld
生成二进制文件的命令)。
- 或者,指示
ld
链接而不在二进制文件本身中包含此调试信息,并生成可以使用 build-id 或调试链接标识的独立调试文件?我在文档中没有看到任何用于执行此操作的单遍方法的内容ld
,但是ld
文档很大,也许我错过了。
- 处理上面截断错误的某种方法(这样的方法将允许 build-id 或 debug-link 方法工作)。
为可执行文件生成单独的调试文件的示例命令
这是使用以下命令的示例命令行序列--build-id
and --add-gnu-debuglink
方法:
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
其中 copyDebugAndStrip 是以下 Perl 代码:
#!/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 ;