どのライブラリが実行中のプロセスであるかを確認する方法はありますか?
具体的には、プログラムが dlopen を使用していくつかの共有ライブラリをロードする場合、readelfまたはlddはそれを表示しません。実行中のプロセスからその情報を取得することはまったく可能ですか?はいの場合、どのように?
他の人々は正しい軌道に乗っています。いくつかの方法があります。
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'
lsof
かもしれません-Linuxのスイスアーミーナイフが役立ちますか?
編集:実行するには、lsof -p <pid>
、すべての種類の有用な情報をリストします。たとえば、プロセスがJavaの場合、開いているすべてのjarをリストします-非常にクールです...
実際、次の方法でコードでこれを行うことができます。
_#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 を参照してください。
ltrace
はあなたの友達のようです。
ltrace
マニュアルから:
ltraceは、指定されたコマンドを終了するまで実行するプログラムです。実行されたプロセスによって呼び出される動的ライブラリ呼び出しと、そのプロセスによって受信される信号をインターセプトして記録します。また、プログラムによって実行されるシステムコールをインターセプトして印刷することもできます。
Its use is very similar to strace(1).
Linuxでは、/proc/<processid>/maps
にはメモリにマッピングされたすべてのファイルのリストが含まれます。これにはdlopen()
によってロードされたすべてのファイルが含まれるはずです。
Solarisには、plddコマンドもあります。
strace
は、開かれているライブラリファイルをトレースしますか?