共有ライブラリシンボルの競合を見つけるためのツールはありますか?

共有ライブラリシンボルの競合を見つけるためのツールはありますか?

私が書いているソフトウェアのいくつかがクラッシュを起こしていますが、2つの異なる共有ライブラリ間のシンボリッククラッシュが原因であると思われます(共有ライブラリの1つを無効にするともう1つが機能し始めます)。

プログラムによってロードされたライブラリを表示し、複数のライブラリに定義されたシンボルがあるかどうかを知るために使用できるツールはありますか?

答え1

問題を解決するためにシェルスクリプトに使用できるいくつかの一般的なユーティリティがあります(問題を解決するためにそれらを組み合わせたスクリプトを見たことはありませんが)。これnmオブジェクトファイルまたは実行可能ファイルからシンボルを検索するユーティリティです。ほとんどのシステムではlddotoolmacOSの場合)実行可能ファイルで使用されている共有ライブラリを表示します。たとえば、前者のスクリプト(listused.sh)は、ncursesがライブラリ内のすべてのシンボルとそのライブラリを使用するプログラムでこれらのシンボルをテストできるかどうかを示します(参照)レポート存在するtest/README)。

この-Cオプションは便利ですが(C ++ライブラリに興味がある場合)、これらのライブラリは剥がれた(デバッグ情報がありません。)しかし、-Dオプション(「最新」システム、つまり過去10〜15年間に更新されたほとんどすべてのシステムで利用可能)は、次の記号を提供します。動的図書館:

一般記号の代わりに動的記号を表示します。これは、特定の種類の共有ライブラリなどの動的オブジェクトにのみ適しています。

動的記号のみが表示されます。このオプションは共有ライブラリにのみ適しています。

シンボル情報を表示しますSHT_DYNSYM。これはld.so.1で使用されるシンボルテーブルであり、削除された動的実行可能ファイルにも存在します。もし–D指定しない場合、デフォルトの動作はSHT_SYMTABシンボル情報を表示することです。

少なくともその文書によると、これは最新システムの機能ではありません。

(誰かがこの機能の導入スケジュールをすぐに知ることができます。)

私はいくつかのスクリプトでこの機能を使用しました。analyze-curses-symbols

追加資料:

-quickstart_infoオプションを使用すると、競合が発生したときにldが通知します。また、競合を見つけるには、-Dcオプションを指定してelfdumpを実行するように求められます。 elfdumpから生成された出力を読み取る方法の詳細については、elfdump(1)のマニュアルページを参照してください。

  • しかし、elfdumpは標準化されていません(でもnm例)そして-Dc他の実装では見つかりません。これ、Solarisの場合。 (持っている関連Solaris用プログラム)。

答え2

nm -C library.so | grep -i symbol

あなたが探しているものかもしれません。ただし、削除されたライブラリでは機能しない可能性があります。

答え3

Linux動的リンカーは、これらの問題をデバッグするためのいくつかの方法も提供します。たとえば、export LD_DEBUG=bindingsすべてのシンボルバインディングに関する多くの情報を取得できます。これらすべての出力を1つのファイルに収集し、さまざまなシナリオの出力を比較すると、いくつかのシンボルが別のファイルにリンクされていることがわかります。よりld.so ドキュメントより多くの選択のために。

たとえば、TensorFlowをバイナリに接続し、一部の組み込みPythonを使用した場合の競合を追跡しています。事故をimport hashlib。 TensorFlowを接続しなくても競合は発生しません。 (これも報告されたことを発見しました。ここそしてここ.)

TFを接続すると、次のような出力が得られます。

2306643:     binding file /u/zeyer/.linuxbrew/Cellar/[email protected]/3.11.2_1/lib/python3.11/lib-dynload/_hashlib.cpython-311-x86_64-linux-gnu.so [0] to /u/zeyer/.local/lib/python3.11/site-packages/tensorflow/libtensorflow_framework.so.2 [0]: normal symbol `EVP_MD_size' [OPENSSL_1_1_0]

ただ実行すると、python -c "import hashlib"次のような結果が表示されます。

   2307740:     binding file /u/zeyer/.linuxbrew/Cellar/[email protected]/3.11.2_1/lib/python3.11/lib-dynload/_hashlib.cpython-311-x86_64-linux-gnu.so [0] to /work/tools/users/zeyer/linuxbrew/lib/libcrypto.so.1.1 [0]: normal symbol `EVP_MD_size' [OPENSSL_1_1_0]

ご覧のとおり、TFを使用している場合はOpenSSL関連のシンボルを検索し、他の場合は(必要に応じて)libtensorflow_framework.so.2でそのシンボルを見つけます。libcrypto.so.1.1

私たちの解決策は、-L/work/tools/users/zeyer/linuxbrew/lib -Wl,-rpath,/work/tools/users/zeyer/linuxbrew/lib -Wl,-no-as-needed -lcryptoTFライブラリをリンクする前にリンカフラグを追加することでした。だからlibcrypto.so.1.1まず強制的にロードします。これで問題が解決します。バラよりここ私のコンパイルスクリプトのため。

関連情報