Go to main content
Oracle® Solaris 11.3 リンカーとライブラリガイド

印刷ビューの終了

更新: 2015 年 10 月
 
 

シンボル結合の確認

デフォルトのシンボル検索モデルを理解して、このモデルを直接結合と比較するために、次のコンポーネントを使用してプロセスを構築します。

$ cat main.c
extern int W(), X();

int main() { return (W() + X()); }
$ cat W.c
extern int b();

int a() { return (1); }
int W() { return (a() - b()); }
$ cat w.c
int b() { return (2); }
$ cat X.c
extern int b();

int a() { return (3); }
int X() { return (a() - b()); }
$ cat x.c
int b() { return (4); }
$ cc -o w.so.1 -G -Kpic w.c
$ cc -o W.so.1 -G -Kpic W.c -R. w.so.1
$ cc -o x.so.1 -G -Kpic x.c
$ cc -o X.so.1 -G -Kpic X.c -R. x.so.1
$ cc -o prog1 -R. main.c W.so.1 X.so.1

アプリケーションのコンポーネントは次の順番で読み込まれます。

$ ldd prog1
        W.so.1 =>        ./W.so.1
        X.so.1 =>        ./X.so.1
        w.so.1 =>        ./w.so.1
        x.so.1 =>        ./x.so.1

W.so.1X.so.1 の両方のファイルで、a() という名前の関数を定義します。w.so.1x.so.1 の両方のファイルで、b() という名前の関数を定義します。さらに、W.so.1X.so.1 の両方のファイルで、関数 a() および b() を参照します。

実行時のシンボル検索 (デフォルトの検索モデルを使用) と最終的な結合は、LD_DEBUG 環境変数を設定することで確認できます。実行時リンカーの診断によって、関数 a() および b() への結合が確認できます。

$ LD_DEBUG=symbols,bindings prog1
....
17375: symbol=a;  lookup in file=prog1  [ ELF ]
17375: symbol=a;  lookup in file=./W.so.1  [ ELF ]
17375: binding file=./W.so.1 to file=./W.so.1: symbol 'a'
....
17375: symbol=b;  lookup in file=prog1  [ ELF ]
17375: symbol=b;  lookup in file=./W.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./X.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./w.so.1  [ ELF ]
17375: binding file=./W.so.1 to file=./w.so.1: symbol 'b'
....
17375: symbol=a;  lookup in file=prog1  [ ELF ]
17375: symbol=a;  lookup in file=./W.so.1  [ ELF ]
17375: binding file=./X.so.1 to file=./W.so.1: symbol 'a'
....
17375: symbol=b;  lookup in file=prog1  [ ELF ]
17375: symbol=b;  lookup in file=./W.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./X.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./w.so.1  [ ELF ]
17375: binding file=./X.so.1 to file=./w.so.1: symbol 'b'

関数 a() または b() のいずれかを参照するたびに、アプリケーション prog1 で始まる関連シンボルを検索することになります。a() への各参照は、W.so.1 で検出されたシンボルの最初のインスタンスに結合します。b() への各参照は、w.so.1 で検出されたシンボルの最初のインスタンスに結合します。この例では、W.so.1 および w.so.1 の関数定義が、X.so.1 および x.so.1 の関数定義にどのように割り込むかを示します。割り込みの存在は、直接結合の使用を検討するときに重要な要素となります。割り込みについては、次のセクションで詳細に説明します。

この例は簡潔であり、関連する診断は容易に理解できます。しかし、ほとんどのアプリケーションでは、多数の動的コンポーネントから構成されているため、この例よりかなり複雑です。これらのコンポーネントは多くの場合、異なるソースベースから構築され、別々に配布されます。

複雑なプロセスの診断を解析することは、非常に困難な場合があります。動的オブジェクトのインタフェースを解析するには、ほかに lari(1) ユーティリティーを使用する方法があります。lari は、プロセスの結合情報と、各オブジェクトが提供するインタフェース定義を組み合わせて解析します。この情報によって、lari はプロセスのシンボル依存関係に関する興味深い情報を簡潔に伝えることができます。この情報は、直接結合に関連する割り込みを解析するときに、非常に有用です。

デフォルトでは、lari興味深いと見なされた情報を伝えます。この情報はシンボル定義の複数のインスタンスから生じます。lariprog1 に関する次の情報を表示します。

$ lari prog1
[2:2ES]: a(): ./W.so.1
[2:0]: a(): ./X.so.1
[2:2E]: b(): ./w.so.1
[2:0]: b(): ./x.so.1

この例では、prog1 から確立されたプロセスに、多重定義された a()b() の 2 つのシンボルが含まれています。出力診断の最初の要素 (角括弧で囲まれた要素) は関連するシンボルを示しています。

最初の 10 進値は関連するシンボルのインスタンスの数を示しています。a()b() の 2 つのインスタンスが存在します。2 番目の 10 進値は、このシンボルに対して解決された結合の数を示しています。W.so.1 のシンボル定義 a() は、この依存関係に対して 2 つの結合が確立されたことを表しています。同様に、w.so.1() のシンボル定義 b は、この依存関係に対して 2 つの結合が確立されたことを表しています。結合数に続く文字は結合を修飾します。文字「E」は、結合が外部オブジェクトから確立されたことを示しています。文字「S」は、結合が同じオブジェクトから確立されたことを示しています。

これらのコンポーネントから作成された LD_DEBUGlari、およびプロセスの例は、次のセクションで直接結合についてさらに説明するために使用されます。