リンカーとライブラリ

デバッグ支援

Solaris OS リンカーには、デバッギングライブラリが付いています。このライブラリを使用すると、リンク編集プロセスをより詳細に監視できます。このライブラリは、ユーザーのアプリケーションおよびライブラリのリンク編集を理解およびデバッグする場合に役立ちます。このライブラリを使用して表示される情報のタイプは、定数のままであると予期されます。ただし、この情報の正確な形式は、リリースごとに若干変更される場合があります。

ELF フォーマットを熟知していないと、デバッギング出力の中には見慣れないものがあるかもしれません。しかし、多くのものが一般的な関心を惹くものでしょう。

デバッグは、-D オプションを使用して実行できます。作成されるすべての出力は、標準エラーに送られます。このオプションは、1 つまたは複数のトークンで増強し、必要なデバッギングのタイプを指示する必要があります。使用できるトークンは、コマンド行で -D help を入力すれば表示できます。


$ ld -Dhelp
............
debug: files      display input file processing (files and libraries)
............

ほとんどのコンパイラドライバは、前処理フェーズ中に -D オプションを解釈します。このため、リンカーにこのオプションを渡すためには、LD_OPTIONS 環境変数のメカニズムが適しています。

次の例では、入力ファイルの監視方法を示しています。この構文は、リンクを編集するときにどのライブラリが使用されているかを判別するときに利用できます。アーカイブから抽出されたオブジェクトもこの構文で表示されます。


$ LD_OPTIONS=-Dfiles cc -o prog main.o -L. -lfoo
............
debug: file=main.o  [ ET_REL ]
debug: file=./libfoo.a  [ archive ]
debug: file=./libfoo.a(foo.o)  [ ET_REL ]
debug: file=./libfoo.a  [ archive ] (again)
............

ここでは、prog のリンク編集を満たすために、メンバー foo.o がアーカイブライブラリ libfoo.a から抽出されています。foo.o の抽出が、その他の再配置可能オブジェクトの抽出を認めていないことを検証するために、このアーカイブが 2 回検索されていることに注意してください。診断内に「(again)」が複数個含まれていることから、このアーカイブが lorder(1)tsort(1) による並べ替えの候補であることがわかります。

symbols トークンを使用することにより、どのシンボルによってアーカイブメンバーが抽出されたか、また、最初のシンボル参照を実行したオブジェクトを判別できます。


$ LD_OPTIONS=-Dsymbols cc -o prog main.o -L. -lfoo
............
debug: symbol table processing; input file=main.o  [ ET_REL ]
............
debug: symbol[7]=foo  (global); adding
debug:
debug: symbol table processing; input file=./libfoo.a  [ archive ]
debug: archive[0]=bar
debug: archive[1]=foo  (foo.o) resolves undefined or tentative symbol
debug:
debug: symbol table processing; input file=./libfoo(foo.o)  [ ET_REL ]
.............

シンボル foo は、main.o によって参照されます。このシンボルは、リンカーの内部シンボルテーブルに追加されます。このシンボル参照によって、再配置可能オブジェクト foo.o が、アーカイブ libfoo.a から抽出されます。


注 –

この出力は、このマニュアル用に簡素化したものです。


detail トークンを、symbols トークンとともに使用すると、入力ファイル処理中のシンボル解決を監視できます。


$ LD_OPTIONS=-Dsymbols,detail cc -o prog main.o -L. -lfoo
............
debug: symbol table processing; input file=main.o  [ ET_REL ]
............
debug: symbol[7]=foo  (global); adding
debug:   entered  0x000000 0x000000 NOTY GLOB  UNDEF REF_REL_NEED
debug:
debug: symbol table processing; input file=./libfoo.a  [ archive ]
debug: archive[0]=bar
debug: archive[1]=foo  (foo.o) resolves undefined or tentative symbol
debug:
debug: symbol table processing; input file=./libfoo.a(foo.o)  [ ET_REL ]
debug: symbol[1]=foo.c
.............
debug: symbol[7]=bar  (global); adding
debug:   entered  0x000000 0x000004 OBJT GLOB  3     REF_REL_NEED
debug: symbol[8]=foo  (global); resolving [7][0]
debug:       old  0x000000 0x000000 NOTY GLOB  UNDEF main.o
debug:       new  0x000000 0x000024 FUNC GLOB  2     ./libfoo.a(foo.o)
debug:  resolved  0x000000 0x000024 FUNC GLOB  2     REF_REL_NEED
............

main.o からの、オリジナルの未定義シンボル foo が、アーカイブメンバー foo.o から抽出されたシンボル定義で上書きされます。このシンボルの詳細情報は、各シンボルの属性に反映されます。

上記の例からわかるように、デバッギングトークンのいくつかを使用すると、豊富な出力が作成されます。入力ファイルのサブセットに関するアクティビティーを監視するには、リンク編集コマンド行に直接 -D オプションを配置します。このオプションはオンとオフを切り替えることができます。次の例では、シンボル処理の表示がオンになるのは、ライブラリlibbar の処理中だけです。


$ ld .... -o prog main.o -L. -Dsymbols -lbar -D!symbols ....

注 –

リンク編集コマンド行を入手するには、使用しているドライバからコンパイル行を拡張する必要があります。「コンパイラドライバを使用する」を参照してください。