デバッグ対象のバイナリからデバッグ情報を分離する機能がサポートされるようになりましたgdb
。binutils
これについて説明しているドキュメントは次の場所にあります。
少し実験した後、gdb
(7.6) で build-id メソッドと debug-link メソッドのいずれかを使用してデバッグ情報を見つけることができました。以下gdb
は、それぞれ build-id メソッドと debug-link メソッドを使用して、非標準の場所でデバッグ情報を見つけるデバッガーを示す 2 つのフラグメントです。
(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 ;