基本的に、これは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用にこのようなツールはありますか?
ライブラリを探すパスは、ファイル/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
は検索するシンボルを指定します。
GNUシステム(GNU libc動的リンカーを使用している場合)では、次のようにプログラムを実行できます。
LD_DEBUG=bindings kst2
シンボルが解決される場所を見つける。
私は何度かこれに遭遇し、コードを1つのLinuxシステムから別のLinuxシステムに移植しようとしました。通常、私はすべての標準ディレクトリをgrepするだけです。私はグーグルを見つけることができませんでした。だからここに簡単なスクリプトがあります: