私は多くのプロセスが同時に実行される最新のLinuxデスクトップを持っています。プロセスの1つ(どのプロセスかはわかりません)が、人気のsome_func
ある動的ライブラリsome_lib
(libc
またはlibx11
と思います)の関数を呼び出します。たくさんこれを使用するプロセス)どのプロセスがこれを行うかを知りたいです(理想的には、各呼び出しにスタックトレースが必要です)。
どのプロセスが呼び出されたかを確認するにはsome_lib
?
これまでに考慮したオプションは次のとおりです。
ltrace
または使用latrace
:ltrace
呼び出したい関数とどの引数が完全であるかについての詳細なプロセスのリストがありますが、ltrace
単一のプロセスまたはプロセスグループにのみ適用されます。ただ入力ltrace -e some_func@some_lib -fp 1
し、システム全体ですべての使用を見ることはできません。- 私のライブラリを使用しているプロセスを見つけて
lsof
ステップ1に進みます。同じライブラリを使用しても関数を呼び出さないプロセスが多すぎるため、これは非常に面倒な作業です。 grep -r some_func /usr
次に、少数のバイナリだけが関数を呼び出し、そこで作業できることを確認します。たとえできるいくつかの限られたケースでは動作しますが、これはsome_func
決して一般的な解決策ではなく、たとえば、さまざまなバイナリに組み込まれていますが、ほとんど呼び出されない場合は機能しません。- カーネル監査システムを使用してください。システムコールを追跡している場合は入力できます。
auditctl -S some_syscall ...
これはシステム全体のコールを記録するのに役立ちます。だが、auditctl
それにすることは不可能に見える。ライブラリ機能。 - やっとできます再建ライブラリ内の目的の関数に新しい行を追加すると、すべての呼び出しが記録されます。これは私の問題を解決することを保証しますが、この解決策は面倒でライブラリを修正/再コンパイルする必要があり、検出ライブラリをロールアウトし、犯人が見つかった場合はロールバックするために少なくとも2回再起動する必要があります。
より簡単な方法がありますか?
(これは一般的な質問であることを指摘したいです。考えられる一般的な解決策に最も興味があります。)
良いものを見つけました。比較記事私が知らなかったいくつかの追跡施設について言及しましたが、これは探索する価値があるかもしれません。
答え1
debuginfoを含むSystemTapは、Centos 7システムのライブラリで関数呼び出しを追跡できます。
$ sudo stap -L 'process("/lib64/libglib*").function("*strndup*")'
process("/usr/lib64/libglib-2.0.so.0.5000.3").function("g_strndup")
$
probe
これは、印刷バックトラックまたはSystemTapで作成できる任意のポイントとして使用できます。
probe begin {
printf("ok\n")
}
probe process("/usr/lib64/libglib-2.0.so.0.5000.3").function("g_strndup") {
/* printf("%s[%d]\n", execname(), pid()) */
print_usyms(ubacktrace())
}
別の名前で保存すると、probelibraryfunc.stp
次のように実行できます。
$ sudo stap probelibraryfunc.stp
呼び出しが一般的な場合、多くの出力が発生する可能性がありますが...