ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
マニュアルページセクション 1: ユーザーコマンド Oracle Solaris 11 Information Library (日本語) |
- アプリケーションレベルの製品検査による Solaris インタフェースの不安定な使用の確認
appcert [-h] [-n] [-f infile] [-w working_dir] [-B] [-L] [-S] {obj | dir}...
appcert ユーティリティーは、Solaris アプリケーションバイナリインタフェース (ABI) へのアプリケーションの準拠を検査します。Solaris ABI は、アプリケーションが安全かつ安定して使用できる Solaris の実行時ライブラリインタフェースを定義します。具体的には、appcert は不安定な実行時インタフェースへの依存、および Solaris の将来のリリースで製品の動作に障害を発生させる可能性があるそのほかの危険を特定します。
appcert は次の内容をチェックします。
Solaris ライブラリ内での非公開シンボルの使用。これらは、開発者による使用が意図されていない非公開シンボル (つまり、関数またはデータ) で、Solaris ライブラリが相互の呼び出しに使用するインタフェースです。これらのシンボルにより、セマンティック動作が変更されるだけでなく、完全に削除されてしまう可能性もあるため (いわゆる降格シンボル)、アプリケーションがこれらのいずれにも依存していないことを確認することをお勧めします。
静的リンク。具体的には、対応する共有オブジェクト .so の動的なリンクではなく、アーカイブ libc.a、libsocket.a、および libnsl.a の静的リンクを指します。ある Solaris ライブラリから別のライブラリへの非公開シンボルによる呼び出しのセマンティクスはリリースによって変わる可能性があるため、ライブラリコードをバイナリオブジェクトに組み込むことはお勧めしません。
非結合シンボル。これらは、appcert の実行時に動的リンカーが解決できなかったライブラリシンボル (つまり、関数またはデータ) です。この問題は、環境の問題 (LD_LIBRARY_PATH など) または構築の問題 (コンパイル時に -llib や -z defs を指定しないなど) である可能性があります。このような問題を指摘したり、より深刻な問題を示したりする場合に、これらのシンボルにフラグが付けられます。
appcert によって、製品全体を簡単に検査できます (製品が多数のプログラムの集合体で、共有オブジェクトをサポートしている場合)。具体的には、appcert で製品のインストール先ディレクトリを調べます。
このタスクを実行するため、appcert は、製品内部のオブジェクトファイル (実行可能オブジェクトまたは共有オブジェクト) ごとにインタフェースの依存関係のプロファイルを作成し、依存関係にあるすべての Solaris システムインタフェースを特定します。(appcert は、この特定のために Solaris 実行時リンカーを使用します。)次に、これらの依存関係プロファイルを Solaris ABI の定義と比較して、非公開の (アプリケーションレベルで使用する場合に安全でなく不安定な) インタフェースを識別します。
appcert は単純なロールアップレポートを生成し、製品のコンポーネントに問題があった場合は、そのコンポーネントと問題の内容を示します。開発者は、このレポートを使用することで、製品の安定性を複数のリリースにわたって検査できます。
appcert は、公開 (安全かつ安定した) Solaris インタフェースと非公開 (非 ABI) インタフェースの両方について、完全なインタフェース依存関係情報を生成します。必要に応じて、この情報を製品コンポーネントごとに確認することもできます。
重要: appcert は、チェック対象のアプリケーションを実行する環境と同じ環境で実行する必要があります。「注意事項」を参照してください。
次のオプションがサポートされています。
appcert をバッチモードで実行すると、出力レポートはバイナリごとに 1 行ずつ表示されます。行の先頭の PASS はバイナリに問題が見つからなかったこと、FAIL は何らかの問題が見つかったこと、INC はバイナリを完全にはチェックできなかったことを意味します。ただし、これらのラベルを単純に文字どおりに解釈することは避けてください。たとえば、PASS は appcert で警告が発せられなかったことを意味しているにすぎません。これらの文字列は左寄せされるため、grep ^FAIL ... などを使用して選択できます。
確認するファイルの一覧 (各行に 1 ファイル) を含む infile ファイルを指定します。この一覧は、コマンド行オペランドで処理された一覧に追加されます (下記の「オペランド」の項を参照)。
使用法についての情報を出力します。
appcert は、製品を検査して共有オブジェクトの存在を確認します。共有オブジェクトが見つかった場合、そのオブジェクトが存在するディレクトリを LD_LIBRARY_PATH に追加します。このフラグを使用すると、appcert によるこの動作は無効になります。
このオプションを指定すると、ディレクトリを検索してチェックするバイナリを探すときに、シンボリックリンクをたどらなくなります。find(1) を参照してください。
Solaris ライブラリディレクトリ (/usr/openwin/lib:/usr/dt/lib) を LD_LIBRARY_PATH に追加します。
ライブラリコンポーネントを実行するディレクトリを特定して、一時ファイルを作成します (デフォルトは /tmp)。
次のオペランドがサポートされています。
チェック対象の製品を構成するオブジェクトや、そのオブジェクトを含むディレクトリの完全な一覧。appcert はディレクトリを再帰的に検索して、オブジェクトファイルを探します。オブジェクトでないファイルは無視されます。
次の終了値が返されます。
appcert の実行に成功し、バイナリ安定性問題は見つかりませんでした。
appcert の実行に失敗しました。
確認した一部のオブジェクトに、バイナリ安定性問題が見つかりました。
チェック可能なバイナリオブジェクトが見つかりませんでした。
検査対象のオブジェクトファイルがライブラリに依存している場合、その依存関係を (コンパイラの -l スイッチを使用して) 内部に記録する必要があります。
検査対象のオブジェクトファイルがほかの共有ライブラリに依存している場合、appcert の実行時に、LD_LIBRARY_PATH または RUNPATH を使用してそれらのライブラリへのアクセスが可能になっている必要があります。
64 ビットアプリケーションをチェックするには、64 ビット Solaris カーネルがマシンで実行されている必要があります。isalist(1) を参照してください。また、現在、64 ビットアプリケーションでは静的リンクのチェックは実行されません。
appcert は、次を検査できません。
完全または部分的に静的にリンクされているオブジェクトファイル。
|
実行権が設定されていない実行可能ファイル。
|
setuid root であるオブジェクトファイル。
|
ELF でない実行可能ファイル (シェルスクリプトなど)。
C 言語以外の Solaris インタフェース (C++、Java など)。
|
appcert は、検索結果を作業ディレクトリ内の次のファイルに記録します (デフォルトの作業ディレクトリは /tmp/appcert.?????)。
チェック済みバイナリと、そのバイナリに固有の出力が存在する作業ディレクトリ内のサブディレクトリ間のマッピング。
appcert の実行時に標準出力に表示されたロールアップレポートのコピー。
appcert がチェックを求められたがスキップせざるをえなかったバイナリの一覧、および各バイナリをスキップした簡単な理由。
また、appcert.?????/objects/ のサブディレクトリ内にある次のファイルには、オブジェクトごとの情報が含まれます。
降格された Solaris シンボルと思われるシンボルの一覧
オブジェクトにより直接結合が行われる非公開の Solaris シンボルの一覧。
オブジェクトにより直接結合が行われる公開 Solaris シンボルの一覧。
ldd -r を実行したときに、動的リンカーによりバインドされなかったシンボルの一覧。利便性を高めるため、file not found という記載のある ldd 出力行も含まれます。
プリンタ形式で書き込まれた、検査済みオブジェクトの動的バインドの要約 (各 Solaris ライブラリから使用される公開シンボルと非公開シンボルのテーブルも含まれる)。
ほかのファイルは、appcert によって内部的に使用される一時ファイルです。
非公開シンボルは、開発者や外部での使用が意図されていない Solaris ライブラリの関数またはデータ変数です。これらのシンボルは、Solaris ライブラリが相互の呼び出しや通信に使用するインタフェースです。これらのシンボルには、pvs(1) の出力内でシンボルのバージョン名 SUNWprivate が付けられます。
非公開シンボルにより、セマンティック動作が変更されるだけでなく、完全に削除されてしまう可能性もあるため (「降格」または「非推奨」のシンボル)、アプリケーションがどの非公開シンボルにも依存しないようにしてください。
降格シンボルとは、Solaris ライブラリの関数またはデータ変数のうち、かつてはそのライブラリに対して非公開で、その後の Solaris リリースで削除された (または、適用範囲がそのライブラリに対してローカルになった可能性のある) 関数またはデータ変数です。アプリケーションがこれらの降格シンボルのいずれかへの呼び出しを直接行なった場合、シンボルが削除されたリリースまたはそれ以降のリリースでは呼び出しに失敗します (再配置エラー)。
まれに、降格シンボルが以降のリリースで復帰することがありますが、それでもなお、アプリケーションが動作しないリリースが存在することに変わりはありません。
Sun Microsystems Inc. では、バイナリの安定性を高めるため、ライブラリの適用範囲設定の大半は Solaris 2.5.1 から 2.6 への移行時に実施しました。これらの内部インタフェースを完全に見えなくする (つまり、動的にリンクできなくする) ことで、開発者が不注意または故意にこれらのインタフェースを呼び出すことがなくなります。詳細は、『リンカーとライブラリ』のバージョン管理の章を参照してください。
非結合シンボルとは、アプリケーションにより参照され、appcert の実行時に動的リンカーが解決できなかったライブラリシンボル (つまり関数またはデータ) のことです。注: appcert はアプリケーションを実際に実行するわけではないため、動的リンクに影響を及ぼす一部の環境特性が適切に設定されない場合があります。
非結合シンボルは、バイナリ安定性問題があることを必ずしも示すわけではありません。appcert の実行時に、実行時動的リンカーがそれらのシンボルを解決できなかったことを示すだけです。
非結合シンボルが生成される原因として、LD_LIBRARY_PATH が正しく設定されていない場合があります。これが正しく設定されていることを確認し、すべてのバイナリオブジェクトが依存関係にあるすべてのライブラリ (製品固有のライブラリ、Solaris ライブラリ、または他社製のライブラリ) を検索できるようにしてください。その後、appcert を再度実行します。
シェルスクリプトを記述して環境を正しく設定してから、チェックするバイナリ上で appcert を実行する際に役立つ場合があります。
非結合シンボルが生成される別のよくある原因として、構築時にコンパイラおよび ld(1) に -l スイッチが指定されなかったために、テスト対象の共有オブジェクトで動的依存関係が記録されなかった場合があります。このため、共有オブジェクトでは、リンク対象の実行可能ファイルに適切な依存関係が記録されている必要があります。
このような共有オブジェクトでは、標準的な方法でリンクを設定する (実行可能ファイルの構築時に指定する) か、または動的に開く (実行可能ファイルが、実行中のある時点で共有オブジェクトに対して dlopen(3C) を呼び出すなど) ことができます。どちらの場合でも、appcert の実行時に非結合シンボルが生成される可能性があります。前者の場合は、通常、appcert の実行前に LD_LIBRARY_PATH を適切に設定することによって解決できます。後者の場合 (dlopen) は、解決が困難になるのが普通です。状況によっては、LD_PRELOAD を適切に設定して必要なライブラリを事前に読み込むことができますが、この方法が常にうまくいくとは限りません。
環境が正しく設定され、非結合シンボルが生成されないようになっていることを確認するにはどうすればよいでしょうか。バイナリ上で ldd -r を実行しても、「file not found」エラーや「symbol not found」エラーが出力されないように設定する必要があります。動的リンクの詳細については、ld.so.1(1) および ldd(1) を参照してください。
いずれの場合でも、appcert は、非結合シンボルがより深刻な問題を示していると考えられる場合に警告フラグを設定します。非結合シンボルは、降格シンボル (ライブラリから削除されたか、適用範囲がローカルに設定されたシンボル) への依存関係を示す場合があります。降格シンボルへの依存関係は、深刻なバイナリ安定性問題につながります。
ただし、環境を適切に設定すれば、ほとんどの非結合シンボルは取り除かれます。通常、可能な場合には常に、構築時にライブラリの依存関係を記録しておくことをお勧めします。これは、バイナリオブジェクトがより明確に定義され、自己完結されるようにするためです。また、共有オブジェクトを構築する際に -z defs フラグを使用して、コンパイル時にすべてのシンボル解決を強制することをお勧めします。詳細については、ld(1) を参照してください。
appcert は、テスト対象のバイナリオブジェクトごとに /bin/ldd -r を実行します。これにより、環境変数 LD_DEBUG=“files,bindings” が設定されます。(詳細については、ldd(1) および ld.so.1(1) を参照してください)。何らかの理由でこのコマンドが失敗すると、appcert は動的シンボル結合情報を保持せず、「no bindings」が検出されます。
次のいずれかが真の場合、appcert の実行に失敗する可能性があります。
バイナリオブジェクトに読み取り権がありません。
バイナリオブジェクトが SUID または SGID で、かつユーザーが十分な特権を備えていません。
バイナリオブジェクトが、実行権ビットの設定されていない実行可能ファイルです。
バイナリオブジェクトが完全に静的にリンクされています。
バイナリオブジェクトにライブラリ依存関係の情報が記録されていません。
そのほかにも理由は考えられます (メモリー不足など)。一般に、このフラグは、アクセス権または環境のために appcert がオブジェクトを完全には検査できなかったことを意味します。動的結合が記録可できるようにするため、アクセス権または環境の変更を試みてください。
廃止ライブラリとは、使用が推奨されておらず、将来のリリースで Solaris から完全に削除される可能性のあるライブラリのことです。これらに依存するアプリケーションは将来の Solaris リリースで動作しなくなる可能性があるため、appcert はこれらにフラグを設定します。廃止ライブラリのインタフェース (非公開インタフェースを含む) はすべて凍結されており、変更されることはありません。
sys_errlist シンボルまたは sys_nerr シンボルを直接使用すると、参照が sys_errlist 配列の末尾を越えてしまう危険があります。これらのシンボルは、32 ビットバージョンの Solaris では非推奨であり、64 ビットバージョンにはまったく存在しません。代わりに strerror(3C) を使用してください。
「弱い」シンボル (socket など) に関連付けられている「強い」シンボル (_socket など) は、非公開 (将来動作が変更される可能性のあるもの) として予約されています。アプリケーションから直接参照するシンボルは、弱いシンボルだけにしてください (通常、強いシンボルは「_」で始まります)。
注: 特定の構築環境では、ソースコードが非公開シンボルを参照していないように思える場合でも、弱い (公開) シンボルの依存関係ではなく、強い (非公開) シンボルの依存関係がバイナリ内に記録されます。その場合でも、この発生原因を突き止めて、依存関係を修正するようにしてください。
appcert は、チェック対象のアプリケーションを実行するのと同じ環境で実行する必要があります。そうでない場合は、Solaris ライブラリ内のインタフェースへの参照を正しく解決できない場合があります。次の手順を実行します。
LD_LIBRARY_PATH およびその他のすべての環境特性が、アプリケーション実行時の設定になっていることを確認します。また、製品の一部である非 Solaris 共有オブジェクトの存在するディレクトリが含まれていて、参照時に検出できるようになっていることを確認します。
チェック対象のすべてのバイナリが、次のようになっていることを確認します。
動的にリンクされた ELF オブジェクトである
実行可能ファイルに実行権が設定されている (共有オブジェクトの場合は不要)
SUID root ではない (それ以外の場合、チェックを行うには自分が root である必要があるため、必要に応じて SUID ではないコピーを作成してチェックする必要があります)。
シェルスクリプトを記述して環境を正しく設定してから appcert を実行する際に役立つ場合があります。
発生する可能性のある問題は、次のとおりです。
appcert が、Solaris ライブラリの一部であると思われる非結合シンボルを報告します。
これは、Solaris 依存関係が記録されていない共有オブジェクトにアクセスするためにアプリケーションが dlopen(3C) を使用することが原因と思われます。動的リンカーが共有オブジェクト上呼び出されることはなく、Solaris シンボル結合の解決に使用できる依存関係情報がほかに存在しないため、この場合には appcert はシンボルの使用を解決できません。これは、Solaris 以外のシンボルでも発生することがあります。
この問題を回避するには、共有オブジェクトの構築時に、コンパイル行で -llib オプションを使用して Solaris ライブラリへの依存関係が明示的に記録されていることを確認します (cc(1) および ld(1) を参照)。
appcert が、アプリケーションのソースコード内で参照されていない Solaris 非公開シンボルがアプリケーションで使用されていることを報告します。
ほとんどの場合、この問題は、そのシンボルを参照する Solaris ライブラリの静的リンクが原因です。appcert は動的リンカーを使用してシンボルを解決するため、appcert は、静的にリンクされたライブラリをアプリケーションコードの一部とみなします (ある意味では事実ですが)。これは、Solaris ヘッダーファイルでマクロ置換を実行した結果として発生することもあります。
この問題を回避するには、可能なかぎり、Solaris ライブラリアーカイブをアプリケーション内に静的にリンクしないようにします。
appcert がライブラリを Solaris の一部として認識しません。
廃止された Solaris ライブラリの中には、シンボルのバージョン管理前に廃止された非常に古いライブラリがあります。このため、appcert はそのようなライブラリを Solaris の一部として認識できません。
「公開」および「非公開」という用語を「安定」および「不安定」と同等の意味で使用することは、混乱を招く可能性があります。特に、実験的なインタフェースや開発中のインタフェースは、ドキュメント化され、使用が推奨されているという意味では公開されていると言えます。ただし、そのようなインタフェースを使用して構築されたアプリケーションは、以降のリリースでは動作しない可能性があるという意味で不安定です。したがって、appcert の目的から、これらのインタフェースは開発が終了するまで非公開と分類されます。逆に、廃止されたインタフェースは、過去に公開されて安定しており、appcert では引き続き公開として扱われている場合でも、最終的には消滅するという意味で不安定です。さいわいなことに、このどちらかの状況が存在することはめったにありません。
属性についての詳細は、attributes(5) を参照してください。
|
cc(1), find(1), isalist(1), ld(1), ldd(1), ld.so.1(1), pvs(1), dlopen(3C), strerror(3C), Intro(4), attributes(5)