Debugging GNULD/gdb:单独的调试文件。当存在';调试信息太多,无法链接?

Debugging GNULD/gdb:单独的调试文件。当存在';调试信息太多,无法链接?,debugging,gdb,binutils,Debugging,Gdb,Binutils,现在,gdb和binutils支持将调试信息从要调试的二进制文件中分离出来。描述这一点的文档可在以下位置找到: 经过一点实验,我能够使用buildid和debug link方法获得gdb(7.6)来查找调试信息。这里有两个gdb片段,显示调试器分别使用build id和debug link方法在非标准位置查找调试信息: (gdb) set debug-file-directory . (gdb) file uWithBuildId Reading symbols from /home

现在,
gdb
binutils
支持将调试信息从要调试的二进制文件中分离出来。描述这一点的文档可在以下位置找到:

经过一点实验,我能够使用buildid和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
构建我们所有的产品代码。目前,如果我们尝试,这会中断调试器,因为我们的共享库太大,重定位被截断,无法容纳以下消息:

/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
    链接而不将此调试信息包含在二进制文件本身中,并生成一个可以用生成id或调试链接标识的独立调试文件?我在文档中没有看到任何关于使用
    ld
    的单次传递方法的内容,但是
    ld
    文档很大,可能我错过了它
  • 处理上述截断错误的某种方法(这种方法将允许build id或debug link方法工作)
  • 用于为可执行文件生成单独调试文件的示例命令 下面是一个使用
    --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 ;
    

    最初看来,
    binutils
    gold链接器能够构建大型g共享lib,为上述(3)提供了一个解决方案,然而,事实证明这是因为缺少错误检查

    另一方面,如果使用前沿工具链,则(1)和(2)的工作似乎可用,这是裂变矮星/binutils/gcc工作的一部分,如下所述:

    在讨论bugzilla关于该重新定位截断错误的报告时提到了该裂变工作:

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

    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版


    intel(版本16)编译器加入gcc,支持-gsplit-dwarf。需要包含binutils-2.24+、gdb-7.6.1+的英特尔编译器文档。clang编译器代码库有一些split dwarf支持,但我不知道该支持处于什么状态。

    在使用g++(v6.3.0)+gold linker(v2.27)+“-g”参数编译时,我遇到了类似的链接器问题

    staticlib.a(sharedlib.o):(.debug\u loc+0x1d38):根据“.debug\u info”截断重新定位以适应:R\u X86\u 64\u 32 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+149326 IO 0pf+0w

    添加参数“-fdebug类型部分”修复了此问题

    详情请浏览: