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

时间:2013-05-06 23:30:11

标签: debugging gdb binutils

现在gdbbinutils支持将调试信息与要调试的二进制文件分开。描述这个的文档可以在:

中找到

经过一些实验,我可以使用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.

要创建调试信息文件,我使用了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'

(以及随后的链接失败)

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

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

    以下是使用--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 ;
    

2 个答案:

答案 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