多くのプロセスが同時に実行されている最新のLinuxデスクトップがあります。それらのプロセスの1つで、どれがどれかはわかりませんが、人気のあるダイナミックライブラリsome_func
から関数some_lib
を呼び出します(libc
またはlibx11
を考えてください。したがって、- lotのプロセスがそれを使用します)、そしてどのプロセスがそれを行うのか知りたいです(そして理想的には、各呼び出しのスタックトレースがあります)。
どのプロセスがsome_lib
を呼び出すかを判断するにはどうすればよいですか?
これまでに検討したオプション:
ltrace
またはlatrace
を使用します。どの引数が完璧であるかについて、興味のある関数を呼び出すプロセスのltrace
スタイルの詳細なリストを用意しますが、ltrace
は個々のプロセスまたはプロセスグループでのみ機能します。 ltrace -e some_func@some_lib -fp 1
と入力して、システム全体のすべての使用法を確認することはできません。lsof
でライブラリを使用しているプロセスを見つけて、手順1に進みます。同じライブラリを使用しているが、その関数を呼び出さないプロセスが多すぎるため、これは非常に面倒です。grep -r some_func /usr
次に、関数を呼び出すことができるバイナリが2つしかないかどうかを確認し、そこから作業を進めます。 couldいくつかの限られたケースで機能しますが、これは決して一般的な解決策ではなく、たとえば次の場合は機能しません。 some_func
はさまざまなバイナリに遍在していますが、呼び出されることはめったにありません。auditctl -S some_syscall ...
と入力すると、システム全体の呼び出しをログに記録するのに役立ちます。ただし、auditctl
は、ライブラリ関数と同じレベルの粒度を実行できないようです。もっと簡単な方法はありますか?
(これは一般的な質問であり、ほとんどの場合、正しく機能する一般的なソリューションに関心があることを指摘したいと思います。)
ニースを見つけました 比較記事 私が知らなかったいくつかのトレース機能について言及しているので、調べる価値があるかもしれません。
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")
$
そして、これは、バックトレースまたはSystemTapで記述できる必要なものを出力するprobe
ポイントとして使用できます。
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
ただし、呼び出しが一般的である場合は、異常な量の出力が生成される可能性があります...