リンカーとライブラリ

デバッギングライブラリ

デバッギングライブラリは、アプリケーションの実行と依存関係を理解したり、デバッグする場合に役立ちます。このライブラリを使用して表示される情報のタイプは、定数のままであると予期されます。ただし、この情報の正確な形式は、リリースごとに若干変更される場合があります。

実行時リンカーをよく理解していないと、デバッギング出力のなかには理解できないものがある可能性があります。しかし、多くのものが一般的な関心を惹くものでしょう。

デバッグを有効にするには、環境変数 LD_DEBUG を使用します。すべてのデバッギングの出力は、接頭辞としてプロセス識別子を持っていて、デフォルトでは、標準エラーに対して送信されます。この環境変数は、1 つまたは複数のトークンを使用して、必要なデバッギングタイプを示す必要があります。

LD_DEBUG で使用可能なトークンを表示するには、LD_DEBUG=help を使用します。どのような動的実行可能プログラムを使用しても、この情報を要求することができます。これは、情報が表示されたあとでプロセスが終了するためです。


$ LD_DEBUG=help prog
......
11693: files     display input file processing (files and libraries)
......

環境変数 LD_DEBUG_OUTPUT を使用すれば、標準エラーの代わりに使用する出力ファイルを指定できます。出力ファイルの名前には、接尾辞としてプロセス ID が付きます。

セキュリティー保護されたアプリケーションのデバッギングは実行できません。

実行時に発生するシンボル結合の表示機能は、もっとも有効なデバッギングオプションの 1 つです。次の例では、2 つのローカル共有オブジェクト上に依存関係を持つ、非常に単純な動的実行可能プログラムを取り上げてみます。


$ cat bar.c
int bar = 10;
$ cc -o bar.so.1 -K pic -G bar.c
 
$ cat foo.c
int foo(int data)
{
        return (data);
}
$ cc -o foo.so.1 -K pic -G foo.c
 
$ cat main.c
extern  int     foo();
extern  int     bar;
 
int main()
{
        return (foo(bar));
}
$ cc -o prog main.c -R/tmp:. foo.so.1 bar.so.1

実行時シンボル結合は、LD_DEBUG=bindings を設定することによって表示されます。


$ LD_DEBUG=bindings prog
11753: .......
11753: binding file=prog to file=./bar.so.1: symbol bar
11753: .......
11753: transferring control: prog
11753: .......
11753: binding file=prog to file=./foo.so.1: symbol foo
11753: .......

即時再配置で必要とされるシンボル bar は、アプリケーションが制御を取得する「前」に結合されます。これに対して、遅延再配置で要求されたシンボル foo は、アプリケーションが制御を受け取った後、関数が最初に呼び出されたときに結合されます。この再配置は、遅延結合のデフォルトモードを示しています。環境変数 LD_BIND_NOW が設定されている場合、シンボル結合はすべて、アプリケーションが制御を受け取る前に実行されます。

LD_DEBUG=bindings,detail と設定すると、実際の結合位置の実アドレスと相対アドレスに関する追加情報が表示されます。

LD_DEBUG を使用すれば、検索パスの使用状況を表示できます。たとえば、依存関係の配置に使用される検索パスのメカニズムは、次のように LD_DEBUG=libs を設定して表示できます。


$ LD_DEBUG=libs prog
11775:
11775: find object=foo.so.1; searching
11775:  search path=/tmp:.  (RUNPATH/RPATH from file prog)
11775:  trying path=/tmp/foo.so.1
11775:  trying path=./foo.so.1
11775:
11775: find object=bar.so.1; searching
11775:  search path=/tmp:.  (RUNPATH/RPATH from file prog)
11775:  trying path=/tmp/bar.so.1
11775:  trying path=./bar.so.1
11775: .......

アプリケーション prog 内に記録された「実行パス」は、2 つの依存関係 foo.so.1bar.so.1 の検索に影響を与えます。

これと同様の方法で、各シンボルを検索する検索パスは、LD_DEBUG=symbols を設定して表示できます。symbolsbindings を組み合わせれば、シンボル再配置処理の全容を把握できます。


$ LD_DEBUG=bindings,symbols prog
11782: .......
11782: symbol=bar;  lookup in file=./foo.so.1  [ ELF ]
11782: symbol=bar;  lookup in file=./bar.so.1  [ ELF ]
11782: binding file=prog to file=./bar.so.1: symbol bar
11782: .......
11782: transferring control: prog
11782: .......
11782: symbol=foo;  lookup in file=prog  [ ELF ]
11782: symbol=foo;  lookup in file=./foo.so.1  [ ELF ]
11782: binding file=prog to file=./foo.so.1: symbol foo
11782: .......

上記の例では、シンボル bar は、アプリケーション prog 内では検索されません。このようにデータ参照検索が省略される原因は、コピーの再配置時に使用される最適化にあります。この再配置タイプの詳細については、「コピー再配置」を参照してください。