现在gdb
和binutils
支持将调试信息与要调试的二进制文件分开。描述这个的文档可以在:
经过一些实验,我可以使用build-id和debug-link方法获得gdb
(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.
要创建调试信息文件,我使用了objcopy
和strip
。我在下面列出了这些命令的详细信息以供参考。
但是,我正在考虑这个问题的原因是希望能够使用-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'
(以及随后的链接失败)
有没有人知道如何做到以下之一:
ld
命令中的所有.o和.a)。ld
链接而不在二进制本身中包含此调试信息,并生成可以使用build-id或debug-link标识的独立调试文件?我没有在文档中看到使用ld
执行此操作的单一传递方法,但ld
文档很大,也许我错过了。以下是使用--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
其中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 ;
答案 0 :(得分:6)
最初似乎binutils
黄金链接器能够构建大型-g共享库,为上面的(3)提供了解决方案,但事实证明这是因为缺少错误检查。 / p>
另一方面,如果使用了尖端工具链,那么看起来(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
其中gcc
/ g++
是版本4.8,binutils
中继(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编译器代码库有一些拆分矮人支持,但我不知道支持的状态是什么。
答案 1 :(得分:1)
使用g ++(v6.3.0)+ gold链接器(v2.27)+“-g”参数进行编译时,我遇到了与链接器类似的问题。
staticlib.a(sharedlib.o):(。debug_loc + 0x1d38):重定位被截断以适合:R_X86_64_32针对`.debug_info' staticlib.a(sharedlib.o):(。debug_loc + 0x6c8c):从输出中省略了额外的重定位溢出 collect2:错误:ld返回1退出状态 gmake:*** [exec_file]错误1 287.760u 35.837s 7:30.37 71.8%0 + 0k 17217048 + 14932696io 0pf + 0w
添加参数“-fdebug-types-section”解决了这个问题。
更多详情请见:https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html