通常、ライブラリ/アプリケーションを開発するとき、ldd
プログラムを使用して外部依存関係 (動的ライブラリにリンクされている) と未定義のシンボルをチェックできます。
$ ldd -r libfoo.so
linux-vdso.so.1 (0x00007fff6b9fe000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa55fe31000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55fa85000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa560386000)
libbar.so.0 => /usr/local/lib/libbar.so.0
undefined symbol: bar_nullfn (libfoo.so)
そのため、この例には互換性のないバージョンのlibbar.soがインストールされているようで、bar_nullfn
. libfoo.so
これは、ビルド フェーズ中にリンカがシンボルの欠落について既に不平を言うため、ビルドに使用されたマシンではめったに発生しません。
これは、実行時リンカーが次の情報に基づいてシンボルを解決できる (または解決できない) 限り、うまく機能します。libfoo.so
残念ながら、ホスト アプリケーションによって dlopen() される動的ライブラリであるpluginsを使用しています。これらのプラグインは、ホスト アプリケーションの関数 (ヘッダーを介して公開) を使用しますが、ホストのコンテキスト外では解決できません。当然のことながら、実行ldd -r
すると大量の誤検出が発生します。
$ ldd -r ./foo.so
linux-vdso.so.1 (0x00007fff6b9fe000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa55fe31000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55fa85000)
undefined symbol: post (./foo.so)
undefined symbol: startpost (./foo.so)
undefined symbol: clock_free (./foo.so)
undefined symbol: clock_new (./foo.so)
undefined symbol: logpost (./foo.so)
undefined symbol: clock_set (./foo.so)
ホストがこれらのシンボル ( post
、...) を提供するため、未定義のシンボルが非常に多いように見えても、プラグインを dlopen() することができます。
そのようなプラグインを構築できるようにするために、リンカは不足しているシンボルを無視するように明示的に指示されています。
今私の問題は、そのようなプラグインには実際に未定義のシンボルがあり、実行時に解決できない場合があることです。リンカはビルド中に不足しているシンボルを無視するように求められたため、警告は発行されません。しかし、プラグインがロードされると、dlopen()
次のようなエラーで失敗します
undefined symbol: psot
ldd は私に与えます:
$ ldd -r ./foo.so
linux-vdso.so.1 (0x00007fff6b9fe000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa55fe31000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55fa85000)
undefined symbol: post (./foo.so)
undefined symbol: startpost (./foo.so)
undefined symbol: logpsot (./foo.so)
undefined symbol: clock_free (./foo.so)
undefined symbol: clock_new (./foo.so)
undefined symbol: psot (./foo.so)
undefined symbol: logpost (./foo.so)
undefined symbol: clock_set (./foo.so)
現在、それを修正する方法を知っている唯一の方法は、不足している各シンボルを繰り返し修正することです。たとえば、(存在しない) 関数psot()
とを使用してプラグインで 2 つのタイプミスをした場合logpsot()
、ホストを起動し、プラグインをロードし、シンボルを使用していることを発見しpsot
、問題を修正し、再コンパイルし、ホスト/プラグインを再起動します。とも書いlogpsot
た。
ldd
(または同様の)シンボルを解決するために使用できる追加のバイナリオブジェクトを指定する方法があるかどうか疑問に思っていました。例えば
ldd --addlib /path/to/host -r ./foo.so
$ ldd -r ./foo.so
linux-vdso.so.1 (0x00007fff6b9fe000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa55fe31000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55fa85000)
undefined symbol: logpsot (./foo.so)
undefined symbol: psot (./foo.so)