基本的に、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 ...
このペアが見つかりませんでした。迷惑な選択肢もあります。 Newsを使用して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にそのようなツールがありますか?
答え1
ライブラリを探すパスは、ファイル/etc/ld.so.conf
、環境変数LD_LIBRARY_PATH
、およびELFバイナリでエンコードされたすべてのRPATHに一覧表示されます。このプログラムは、ldd
特定のアプリケーションがどのライブラリをロードするかを示します。
興味のあるシンボルがある場合は、プログラムを使用してシンボルをダンプしてファイルし、1つまたは任意のelf実行可能ファイルからnm
シンボルをダンプできます。.o
.a
readelf
.so
例:
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
検索する-s
シンボルを指定します。
答え2
GNUシステムで(GNU libcダイナミックリンカーを使用している場合)、次のようにプログラムを実行できます。
LD_DEBUG=bindings kst2
シンボルが解決される場所を探します。
答え3
あるLinuxシステムから別のLinuxシステムにコードを移植しようとしたときに、このような状況が何度も発生しました。通常、私はすべての標準ディレクトリをgrepingします。 Google には何も見つかりません。以下はクイックスクリプトです。