gnu ld / gdb:单独的调试文件。当调试信息太多时,如何生成调试文件? [英] gnu ld/gdb: separate debug files. How to produce the debug file when there's too much debug info to link?

查看:395
本文介绍了gnu ld / gdb:单独的调试文件。当调试信息太多时,如何生成调试文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在有$ / code> gdb 和 binutils 支持将调试信息与要调试的二进制文件分开。描述这一点的文档可以在以下网址找到:





经过一番实验,我可以获得 gdb (7.6)来查找调试信息,使用build-id和debug-link方法。这里有两个 gdb 碎片,显示调试器在非标准位置查找调试信息,分别使用build-id和debug-link方法:

 (gdb)设置debug-file-directory。 
(gdb)文件uWithBuildId
从/home/peeterj/build-id/uWithBuildId...读取符号。从/home/peeterj/build-id/.build-id/2d/41caac1bcbeb65255abc3f35624cf9ed37791a读取符号。调试...完成


从/home/peeterj/build-id/uWithDebugLink...读取符号。从/home/peeterj/build-id/uWithDebugLink.debug...done中读取符号。

要创建调试信息文件,我使用过 objcopy strip 。我已经列出了这些命令的详细信息,以供参考。



但是,我正在看这个的原因是希望能够构建>所有的产品代码与 -g 。目前,如果我们尝试使用共享库,那么这个破坏调试器,因为我们的共享库太大,并且重定位被截断以适应以下消息:

  / usr /lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o:(.debug_aranges+0x6):重定位截断以适合:R_X86_64_32对`.debug_info '

(和后续链接失败)



有没有人知道如何执行以下操作之一:


  1. 生成一个独立文件,其中包含来源有助于所有调试信息的所有调试信息二进制(即所有的.o和.a的最终都在生成二进制的 ld 命令中。)

  2. 或者,指示 ld 链接而不在二进制本身中包含此调试信息,并生成可以使用build-id或debug-link标识的独立调试文件?文档中没有看到任何一个单一的方法来执行此操作与 ld ,但 ld 文档很大,也许我错过了。

  3. 有些方法来处理上面的截断错误(这样的方法可以允许build-id或debug-link方法工作)



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



这是一个示例命令使用 - build-id - add-gnu-debuglink 方法的行序列:

  g ++ -g -c -o uo u.cpp 
g ++ -o uWithBuildId -Wl, - build-id uo
g ++ -o uWithDebugLink uo
copyDebugAndStrip uWithBuildId
objcopy --only-keep-debug uWithDebugLink uWithDebugLink.debug
objcopy --add-gnu-debuglink = uWithDebugLink.debug uWithDebugLink
strip -g uWithDebugLink

其中copyDebugAndStrip是以下Perl代码:

 #!/ usr / bin / perl 

我的$ binary = $ ARGV [0];
我的@p =`objdump --section .note.gnu.build-id -s $ binary |尾巴-2
foreach(@p)
{
chomp;
s / ^ * [\da-f] + * //;
s /。* //;
s / // g;
}

我的$ buildid =$ p [0] $ p [1];
$ buildid =〜/^(..)(.*)/;

我的($ d,$ r)=($ 1,$ 2);

打印$ binary的build-id:$ buildid\\\
;

我的$ 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;


解决方案

最初,似乎 binutils 金链接器能够构建大的共享库,为(3)提供一个解决方案,但是,原因是缺少错误检查。



另一方面,如果使用了出色的工具链,(1)和(2)中的工作就可以使用,这里描述的部分分裂矮星/ binutils / gcc工作: / p>



这个裂变作品在讨论关于这个重定位截断错误的bugzilla报告时被提及:



http://sourceware.org/bugzilla/sh ow_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 trunk( cvs -z 9 -d:pserver:anoncvs@sourceware.org:/ cvs / src co binutils )已使用配置为 - enable-gold = default ,最后使用gdb版本7.6,它可以读取拆分调试信息。



在聚会中加入gcc,intel(版本16)编译器支持-gplpl -矮人。 intel编译器要求binutils-2.24 +,gdb-7.6.1 +是必需的。 clang编译器代码库有一些分裂的矮人支持,但我不知道支持的是什么状态。


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:

  1. 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 ld command that generates the binary).
  2. Or, instruct ld 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 ld, but the ld docs are big and perhaps I missed it.
  3. 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 ;

解决方案

Initially it appeared that the binutils gold linker was capable of building large -g shared libs, providing a solution for (3) above, however, it turns out that is because of a lack of error checking.

On the other hand it looks like work on (1) and (2) is in available if a bleeding edge toolchain is used, part of the fission dwarf/binutils/gcc work described here:

This fission work was mentioned in discussion of a bugzilla report on this relocation truncation error:

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

An example of the use of this split debug files is:

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

where gcc/g++ are version 4.8, the binutils trunk (cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils) has been used configured with --enable-gold=default, and finally using gdb version 7.6 which can read the split debug info.

Joining gcc in the party, the intel (version 16) compiler supports -gsplit-dwarf. The intel compiler documents that binutils-2.24+,gdb-7.6.1+ are required. The clang compiler codebase has some split dwarf support, but I don't know what state that support is in.

这篇关于gnu ld / gdb:单独的调试文件。当调试信息太多时,如何生成调试文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆