web-dev-qa-db-ja.com

Mac OS XでDYLD_LIBRARY_PATHを使用しても大丈夫ですか?そして、それを使用した動的ライブラリ検索アルゴリズムは何ですか?

-install_name、@ rpath、および@loader_pathを使用して動的ライブラリのパスを修正する必要があるため、DYLD_LIBRARY_PATHの使用を推奨しない記事をいくつか読みました。

LinuxとMac OS Xの両方で実行するプログラムを作成するという点では、Mac OS XのDYLD_LIBRARY_PATHはLinuxのLD_LIBRARY_PATHとまったく同じです。また、-install_nameと@rpathを持たない(ほぼ)同じmakeファイルを共有できます。

  • Mac OS XでDYLD_LIBRARY_PATHを使用しても大丈夫ですか?
  • バイナリが動的ライブラリを見つけられない場合のMac OS Xでの動的ライブラリ検索アルゴリズムは何ですか?現在のディレクトリ-> DYLD_LIBRARY_PATHディレクトリ...?
48
prosseek

既に述べたように、DYLD_LIBRARY_PATHは他の* nix上のLD_LIBRARY_PATHのように動作します。ただし、DYLD_FALLBACK_LIBRARY_PATHという別の環境変数を確認する必要があります。

一般に、これらは(osxとlinuxの両方で)開発用にのみ推奨されます。同じシンボルテーブルを持たないライブラリでオーバーライドすると、シンボル検索エラーが発生する可能性があるためです。これの良い例は、カスタムインストールでVecLibのデフォルトのインストール(例:blas lapack)をオーバーライドしようとした場合です。これにより、DYLD_LIBRARY_PATHが設定されている場合はシステムVecLibにリンクされているアプリケーションでシンボルが見つからないエラーが、設定されていない場合は逆(カスタムアプリケーションでのシンボル検索エラー)が発生します。これは、システムblas/lapackがATLASライブラリの完全な実装ではないためです。

DYLD_FALLBACK_LIBRARY_PATHはこれらの問題を引き起こしません。

ライブラリを非標準の場所にインストールする場合、DYLD_FALLBACK_LIBRARY_PATHの方がずっと健全です。これにより、デフォルトパスで提供されるライブラリ内のシンボルが検索され、そこでシンボルが見つからない場合は、指定されたパスにフォールバックします。

利点は、このプロセスにより、デフォルトライブラリに対してコンパイルされたアプリケーションでシンボルルックアップエラーが発生しないことです。

一般に、ライブラリを非標準の場所にインストールする場合、動的ルックアップのあいまいさを解消する絶対パスを指定する必要があります。

67
jkyle

DYLD_LIBRARY_PATHLD_LIBRARY_PATHのようには動作しません。 OS X dlopenドキュメント( https://developer.Apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/dlopen.3.html )は、絶対パスを指定すると、最初にDYLD_LIBRARY_PATHで指定された場所が検索されます。

パスにスラッシュが含まれているがフレームワークパス(つまり、dylibへのフルパスまたは部分パス)ではない場合、dlopen()は互換性のあるMach-Oファイルが見つかるまで次を検索します。$ DYLD_LIBRARY_PATH(パス名の葉) 、提供されたパス(相対パスに現在の作業ディレクトリを使用)、$ DYLD_FALLBACK_LIBRARY_PATH(pathからのリーフ名を使用)。

つまり、DYLD_LIBRARY_PATH/Helloに設定すると、次の2つのdlopenが呼び出されます。

dlopen("/Hello/libfoo.so", RTLD_NOW);
dlopen("/World/libfoo.so", RTLD_NOW);

両方とも/Hello/libfoo.soに解決されます。これは非常に直感に反し、セキュリティの脆弱性を表しています。 dlopenを使用するソフトウェアには、正しいライブラリをロードすることを保証する方法がありません(おそらく、独自の環境でDYLD_LIBRARY_PATHをオーバーライドしますか?)

6
Sander Mertens

ダイナミックリンクエディタの環境変数とそれらがダイナミックライブラリの検索に与える影響に関するドキュメントについては、man dyld

DYLD_LIBRARY_PATH

これは、ライブラリを含むディレクトリのコロン区切りのリストです。動的リンカーは、これらのディレクトリを検索してから、ライブラリのデフォルトの場所を検索します。既存のライブラリの新しいバージョンをテストできます。

プログラムが使用するライブラリごとに、動的リンカーはDYLD_LIBRARY_PATHの各ディレクトリで順番に検索します。それでもライブラリが見つからない場合は、DYLD_FALLBACK_FRAMEWORK_PATHとDYLD_FALLBACK_LIBRARY_PATHを順番に検索します。

Otool(1)に-Lオプションを使用します。実行可能ファイルがリンクされているフレームワークと共有ライブラリを発見します。

DYLD_FALLBACK_LIBRARY_PATH

これは、ライブラリを含むディレクトリのコロン区切りのリストです。インストールパスにないライブラリのデフォルトの場所として使用されます。デフォルトでは、$(HOME)/ lib:/ usr/local/lib:/ lib:/ usr/libに設定されています。

DYLD_VERSIONED_LIBRARY_PATH

これは、潜在的なオーバーライドライブラリを含むディレクトリのコロン区切りリストです。動的リンカーは、これらのディレクトリで動的ライブラリを検索します。見つかったライブラリごとに、dyldはLC_ID_DYLIBを調べ、current_versionとインストール名を取得します。次に、Dyldはインストール名パスでライブラリを探します。そのインストール名のdylibが必要な場合は、より大きいcurrent_version値を持つ方がプロセスで使用されます。これはDYLD_LIBRARY_PATHに似ていますが、常にオーバーライドするのではなく、指定されたライブラリの方が新しいことをオーバーライドするだけです。

3
Doug Richardson