web-dev-qa-db-ja.com

ライブシステムで定義されている共有ライブラリシンボルの場所を見つける/システムでエクスポートされたすべてのシンボルを一覧表示する

基本的に、これは2つの質問を1つにまとめたものです。システム内でエクスポートされたすべてのシンボルと共有ライブラリパスを一覧表示できれば、単純にその出力をgrepできるからです。

カーネルシンボルの場合、いつでもcat /proc/kallsymsそして、メモリにロードされたモジュールのすべてのシンボルのリストを取得します。次にSudo cat /proc/modulesは、ロードされたモジュールとそのア​​ドレスのリストを提供しますが、モジュールがロードされたパスは提供しません(それらが独立した、ツリー外の.koオブジェクトとして構築されている場合)。

たとえば、kstを使用してプログラムltraceをトレースしようとします。

$ ltrace kst2
...
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0, 0xbfe631a8, 0x823652b, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298)     = 0xa1ce800
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298)     = 0xa1ce800
...

...そして、これを知りたい_ZNK13QGraphicsItem10parentItemEvが存在します。

では、共有ライブラリシンボルについてはどうすればよいでしょうか。読む [gcc-help] Re:シンボルが定義されているライブラリを見つける。 ;私はこのようなものを試しました:

$ find /usr/lib -name '*.so*' -exec nm --print-file-name --defined-only --dynamic {} \; | grep "QGraphicsItem"
...
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
/usr/lib/libQtGui.so.4.7.2:00766aa0 T _Zls6QDebugN13QGraphicsItem18GraphicsItemChangeE
/usr/lib/libQtGui.so.4.7.2:00767e80 T _Zls6QDebugP13QGraphicsItem
...

...しかし、それによって追加の問題が発生します。システム上の共有ライブラリをスキャンするすべてのパスが本当にわからないので、最初にfind /lib ...何も見つかりませんでした。私はこのディレクトリの推測が厄介であるだけでなく、代替手段も使用しています。ルートファイルシステム全体をfindでスキャンします。また、nm(多分それらはシンボリックリンクなのでしょうか?)、かなりのエラーメッセージを出力します(私も好きではありません)。

問題は-ldd(またはld?)はおそらくシンボルのこの検索の一部を実行しますが、それぞれのマンページを試しましたが、シンボルを「見つける」方法がわかりません引数として実行ファイルのようなものを提供せずにコマンドライン。副題-そのためにこれらのツールを使用する方法はありますか?

だから、私が探しているコマンドラインツールは、(擬似コード)のように動作します:

$ ./findsymbol '_Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE'
symbol found in:
    /usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
...

...ここでは、検索するディレクトリを指定していませんが、これも処理します。 LD_PRELOADまたはLD_LIBRARY_PATH;私がそうするなら:

$ LD_PRELOAD="/path/to/mylib.so" ./findsymbol '*mylib_print*'

...その後、/path/to/mylib.so指定されたシンボルが定義された場所(そのようなシンボルが標準ライブラリに存在しない場合)-それ以外の場合は「見つかりません」を出力します。それ以外の場合は、./findsymbol --dumpallは、特定の環境(たとえば、特定のbashシェル)から見た使用可能なすべてのシンボルとその場所のリストを生成できます。

Linux用にこのようなツールはありますか?

22
sdaau

ライブラリを探すパスは、ファイル/etc/ld.so.conf、環境変数LD_LIBRARY_PATH、およびELFバイナリにエンコードされたRPATHにリストされます。プログラムlddは、特定のアプリケーションがロードするライブラリを通知します。

興味のあるシンボルを取得したら、プログラムnmを使用して.oおよび.aファイルのシンボルをダンプし、readelfを使用して.soまたは任意のelf実行可能ファイルからシンボルをダンプできます。

例:

nm -g /usr/lib/blah.a
readelf -Ws /usr/lib/blah.so

そして最後に、その背景を除いて、ここにあなたの聖杯があります:

記号_ZN6Kopete6Global10PropertiesC2Evが与えられた場合、これはどこにありますか?

scanelf -l -s _ZN6Kopete6Global10PropertiesC2Ev | grep _ZN6Kopete6Global10PropertiesC2Ev

これにより、

ET_DYN _ZN6Kopete6Global10PropertiesC2Ev /usr/lib64/libkopete.so.4.11.4

-lフラグは/etc/ld.so.confでdirsを検索することを示し、-sは検索するシンボルを指定します。

17
casey

GNUシステム(GNU libc動的リンカーを使用している場合)では、次のようにプログラムを実行できます。

LD_DEBUG=bindings kst2

シンボルが解決される場所を見つける。

7

私は何度かこれに遭遇し、コードを1つのLinuxシステムから別のLinuxシステムに移植しようとしました。通常、私はすべての標準ディレクトリをgrepするだけです。私はグーグルを見つけることができませんでした。だからここに簡単なスクリプトがあります:

edt11x/findinsharedlibs

0
edt11x