web-dev-qa-db-ja.com

特定のプロセスの実行時にロードされる共有ライブラリを確認する方法は?

どのライブラリが実行中のプロセスであるかを確認する方法はありますか?

具体的には、プログラムが dlopen を使用していくつかの共有ライブラリをロードする場合、readelfまたはlddはそれを表示しません。実行中のプロセスからその情報を取得することはまったく可能ですか?はいの場合、どのように?

47
BЈовић

他の人々は正しい軌道に乗っています。いくつかの方法があります。

cat /proc/NNNN/maps | awk '{print $6}' | grep '\.so' | sort | uniq

または、straceで:

strace CMD.... 2>&1 | grep '^open(".*\.so"'

これらは両方とも、共有ライブラリのパスに「.so」があることを前提としていますが、変更できます。 1つ目は、1行に1つだけのライブラリのリストとして、かなりきれいな出力を提供します。 2つ目は、ライブラリが開かれたときにライブラリを一覧表示し続けるので、それは素晴らしいことです。

編集:そしてもちろんlsof...

lsof -p NNNN | awk '{print $9}' | grep '\.so'
74
Dietrich Epp

lsofかもしれません-Linuxのスイスアーミーナイフが役立ちますか?

編集:実行するには、lsof -p <pid>、すべての種類の有用な情報をリストします。たとえば、プロセスがJavaの場合、開いているすべてのjarをリストします-非常にクールです...

15
Nim

実際、次の方法でコードでこれを行うことができます。

_#include <link.h>

using UnknownStruct = struct unknown_struct {
   void*  pointers[3];
   struct unknown_struct* ptr;
};
using LinkMap = struct link_map;

auto* handle = dlopen(NULL, RTLD_NOW);
auto* p = reinterpret_cast<UnknownStruct*>(handle)->ptr;
auto* map = reinterpret_cast<LinkMap*>(p->ptr);

while (map) {
  std::cout << map->l_name << std::endl;
  // do something with |map| like with handle, returned by |dlopen()|.
  map = map->l_next;
}
_

_link_map_構造には、少なくともベースアドレスと絶対ファイル名が含まれます。最初の引数がNULLでないdlopen()によって実際に返されるのは構造です。詳細については、 here を参照してください。

11
abyss.7

ltraceはあなたの友達のようです。

ltraceマニュアルから:

ltraceは、指定されたコマンドを終了するまで実行するプログラムです。実行されたプロセスによって呼び出される動的ライブラリ呼び出しと、そのプロセスによって受信される信号をインターセプトして記録します。また、プログラムによって実行されるシステムコールをインターセプトして印刷することもできます。

       Its use is very similar to strace(1).
7
chaos.ct

Linuxでは、/proc/<processid>/mapsにはメモリにマッピングされたすべてのファイルのリストが含まれます。これにはdlopen()によってロードされたすべてのファイルが含まれるはずです。

6
Kieron

Solarisには、plddコマンドもあります。

3
Christian.K

straceは、開かれているライブラリファイルをトレースしますか?

1