作業パッケージには、一部のライブラリに対してlddが「見つかりません」を返したファイルがいくつか含まれていることがたくさんありました。たとえば...
/usr/lib64/thunderbird/libprldap60.so
libldap60.so => not found
/usr/lib64/libreoffice/program/libofficebean.so
libjawt.so => not found
ThunderbirdとLibre Officeを使用している何百人ものユーザーがいますが、誰も問題を報告していません。次のファイルがシステムに存在します。
/usr/lib64/thunderbird/libldap60.so
/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.33.x86_64/jre/lib/amd64/libjawt.so
/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.71.x86_64/jre/lib/amd64/libjawt.so
この例では、/usr/bin/thunderbird と /usr/bin/libreoffice の両方が、そのプログラムの起動に使用されるラッパースクリプトです。このスクリプトは、これらのライブラリが表示されるように環境を設定すると予想していましたが、そうではありません。 。これは次のとおりです。これはスクリプトで発生します。
私たちのシステムには、このような例が何百ものあります。たとえば、この2つが選択します。何が起こっているのかを説明できる人はいますか?
答え1
単純でおそらく明らかな答えは、見ているライブラリの検索パスにldd
ライブラリ自体の依存関係があるディレクトリが含まれていないことです。通常、ライブラリーの依存関係がシステム全体の標準位置で見つからない限り、指定された実行パス(環境変数$LD_RUN_PATH
または適切なリンカーオプションを使用)を使用してライブラリーを構築する必要があります。それ以外の場合は、NETと同様に、後で実行時にこれらのライブラリを見つけることができませんldd
。
では、なぜThunderbirdはこれらの「問題」にもかかわらずまだ機能しますか?
実行パスが不足しているにもかかわらず、必要なライブラリを見つける方法はいくつかあります。
- 環境変数は
$LD_LIBRARY_PATH
実行時に設定され、検索する追加のディレクトリのリストを提供します。 - 必要なディレクトリは、現在ライブラリの前にロードされている他の関連ライブラリの実行パスにあり、検索パスにすでに含まれている可能性があります。ちなみに、これが標準に規定されている実装思考であるかどうかはわかりません。それにもかかわらず、ライブラリがロードされる正確な順序に大きく依存するため、脆弱です。
dlopen()
ライブラリは、フルパス名の関数を使用してアプリケーションによって手動でロードされた可能性があります。
Thunderbirdはこの最後の技術を使用しているようです。起動時に出力を見たstrace
結果、次のようになります。
- 独自のバイナリがあるディレクトリを探します。 Thunderbirdを起動するシェルスクリプトヘルパーはこれを行うためにフルパス名を使用するため、これは常に可能です。
dependentlibs.list
このディレクトリにあるテキストファイルを開きます。- このテキストファイルの各ファイル名のフルパス名を設定するために、同じディレクトリを先頭に追加します
dlopen()
。 - 今述べたすべての依存ライブラリ
libldap60.so
は「事前ロード」されており、それを必要とする他のライブラリはそのライブラリを再検索する必要はありません。
に記載されている順序やファイルがdependentlibs.list
重要であることに注意してください。
Thunderbirdがこれを行う理由は、そのディレクトリをアプリケーションまたは内部ライブラリの実行パスにハードコードする必要がないためです。
Javaが何をしているのかわかりませんが、似たようなものがあることは間違いありません。