私が書いているソフトウェアのいくつかがクラッシュを起こしていますが、2つの異なる共有ライブラリ間のシンボリッククラッシュが原因であると思われます(共有ライブラリの1つを無効にするともう1つが機能し始めます)。
プログラムによってロードされたライブラリを表示し、複数のライブラリに定義されたシンボルがあるかどうかを知るために使用できるツールはありますか?
答え1
問題を解決するためにシェルスクリプトに使用できるいくつかの一般的なユーティリティがあります(問題を解決するためにそれらを組み合わせたスクリプトを見たことはありませんが)。これnm
オブジェクトファイルまたは実行可能ファイルからシンボルを検索するユーティリティです。ほとんどのシステムではldd
(otool
macOSの場合)実行可能ファイルで使用されている共有ライブラリを表示します。たとえば、前者のスクリプト(listused.sh
)は、ncursesがライブラリ内のすべてのシンボルとそのライブラリを使用するプログラムでこれらのシンボルをテストできるかどうかを示します(参照)レポート存在するtest/README
)。
この-C
オプションは便利ですが(C ++ライブラリに興味がある場合)、これらのライブラリは剥がれた(デバッグ情報がありません。)しかし、-D
オプション(「最新」システム、つまり過去10〜15年間に更新されたほとんどすべてのシステムで利用可能)は、次の記号を提供します。動的図書館:
- GNUバイナリチル、1999年から
一般記号の代わりに動的記号を表示します。これは、特定の種類の共有ライブラリなどの動的オブジェクトにのみ適しています。
- ELFツールチェーン、2008年から
動的記号のみが表示されます。このオプションは共有ライブラリにのみ適しています。
シンボル情報を表示します
SHT_DYNSYM
。これはld.so.1で使用されるシンボルテーブルであり、削除された動的実行可能ファイルにも存在します。もし–D
指定しない場合、デフォルトの動作はSHT_SYMTAB
シンボル情報を表示することです。
少なくともその文書によると、これは最新システムの機能ではありません。
(誰かがこの機能の導入スケジュールをすぐに知ることができます。)
私はいくつかのスクリプトでこの機能を使用しました。analyze-curses-symbols
。
追加資料:
- 共有ライブラリシンボルの競合(Linux)この目的でこれを使用する方法を示す例を提供してください
nm
。 - 第3章動的共有オブジェクトの使用以前のSGIマニュアルには
elfdump
関連オプションがあると言われています。
-quickstart_infoオプションを使用すると、競合が発生したときにldが通知します。また、競合を見つけるには、-Dcオプションを指定してelfdumpを実行するように求められます。 elfdumpから生成された出力を読み取る方法の詳細については、elfdump(1)のマニュアルページを参照してください。
答え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 -lcrypto
TFライブラリをリンクする前にリンカフラグを追加することでした。だからlibcrypto.so.1.1
まず強制的にロードします。これで問題が解決します。バラよりここ私のコンパイルスクリプトのため。