gnu ld/gdb:单独的调试文件.如果有太多的调试信息需要链接,如何生成调试文件?

Pee*_*oot 4 debugging gdb binutils

现在有gdbbinutils要调试从二进制分离调试信息的支持.可以在以下位置找到描述此内容的文档:

经过一些实验,我能够gdb使用build-id和debug-link方法获得(7.6)查找调试信息.这里有两个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.
Run Code Online (Sandbox Code Playgroud)

要创建我用的调试信息的文件objcopystrip.我在下面列出了这些命令的详细信息以供参考.

但是,我正在考虑这个问题的原因是希望能够构建我们所有的产品代码-g.目前,如果我们尝试,这会破坏调试器,因为我们的shared-lib太大而且重定位被截断以适合以下消息:

/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'
Run Code Online (Sandbox Code Playgroud)

(以及随后的链接失败)

有没有人知道如何做到以下之一:

  1. 生成一个独立文件,其中包含有助于二进制文件的所有调试信息(即ld生成二进制文件的命令中最终的.o和.a ).
  2. 或者,指示ld链接而不在二进制本身中包含此调试信息,并生成可以使用build-id或debug-link标识的独立调试文件?我没有在文档中看到任何单一传递方法来执行此操作ld,但ld文档很大,也许我错过了它.
  3. 处理上面的截断错误的一些方法(这样的方法将允许build-id或debug-link方法工作).

sample命令为可执行文件生成单独的调试文件

这是使用--build-id--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
Run Code Online (Sandbox Code Playgroud)

其中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 ;
Run Code Online (Sandbox Code Playgroud)

Pee*_*oot 6

最初似乎binutils黄金链接器能够构建大型-g共享库,为上面的(3)提供了解决方案,然而,事实证明这是因为缺少错误检查.

另一方面,如果使用了尖端工具链,则可以使用(1)和(2)上的工作,这里描述了裂变矮化/ binutils/gcc工作的一部分:

在关于此重定位截断错误的bugzilla报告的讨论中提到了这种裂变工作:

http://sourceware.org/bugzilla/show_bug.cgi?id=15444

使用此拆分调试文件的示例如下:

g++ -gsplit-dwarf -gdwarf-4   -c -o main.o main.cpp
gcc -gsplit-dwarf -gdwarf-4   -c -o d1/t1.o d1/t1.c
g++ -gsplit-dwarf -gdwarf-4   -c -o d2/t2.o d2/t2.cpp
gcc -Wl,--index-gdb main.o d1/t1.o d2/t2.o   -o main
Run Code Online (Sandbox Code Playgroud)

其中gcc/ g++是版本4.8,binutilstrunk(cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils)已配置使用--enable-gold=default,最后使用gdb版本7.6,它可以读取拆分调试信息.

在聚会中加入gcc,intel(版本16)编译器支持-gsplit-dwarf.intel编译器记录了binutils-2.24 +,gdb-7.6.1 +是必需的.clang编译器代码库有一些分离矮人支持,但我不知道支持的状态.