多くのプロセスが同時に実行されている最新のLinuxデスクトップがあります。それらのプロセスの1つで、どれが関数some_func
を呼び出すかはわかりません。 人気のあるダイナミックライブラリsome_lib
から (libc
を考えてください またはlibx11
、つまりたくさん のプロセスがそれを使用します)、そして私はどのプロセスがそれを行うのか知りたいです(そして理想的には、各呼び出しのスタックトレースを持っています)。
some_lib
を呼び出すプロセスを特定するにはどうすればよいですか。 ?
これまでに検討したオプション:
-
ltrace
を使用する またはlatrace
:ltrace
を持っている -スタイルの詳細なリスト
どのプロセスが関数と呼ばれるかについての私が興味を持っている
引数は完璧ですが、ltrace
個々のプロセスまたはプロセスグループでのみ機能します。ltrace -e
と入力するだけでは不十分です。 システム全体のすべての使用法を確認してください。
[email protected]_lib -fp 1 -
lsof
でライブラリを使用しているプロセスを見つける 、次にステップ1に進みます。同じライブラリを使用しているプロセスが多すぎるが、その関数を呼び出さないため、これは非常に面倒です。 -
grep -r some_func /usr
、次に、関数を呼び出すことができるバイナリが2つしかないかどうかを確認し、そこから作業を進めます。それはできた 一部の限られたケースで機能しますが、これは決して一般的な解決策ではなく、たとえば次の場合は機能しません。some_func
さまざまなバイナリに遍在していますが、呼び出されることはめったにありません。 - カーネル監査システムを使用します。システムコールをトレースしている場合は、
auditctl -S some_syscall ...
と入力できます。 これで、システム全体の呼び出しをログに記録することができます。ただし、auditctl
ライブラリ関数で同じレベルの粒度を実行できないようです。 。 - 最後に、再構築できました ライブラリに、関心のある関数にすべての呼び出しをログに記録する新しい行を追加します。これで私の問題は確実に解決されますが、その解決策は面倒であり、ライブラリを変更/再コンパイルし、インストルメントされたライブラリをロールアウトして原因を見つけた後にロールバックするには、少なくとも2回再起動する必要があります。
もっと簡単な方法はありますか?
(これは一般的な質問であり、ほとんどの場合、適切に機能する一般的なソリューションに関心があることを指摘したいと思います。)
気づかなかったトレース機能について言及している素晴らしい比較記事を見つけました。これは調査する価値があるかもしれません。
承認された回答:
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("okn")
}
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
ただし、呼び出しが一般的である場合は、クレイジーな量の出力が生成される可能性があります…
関連:STDINを介してOpen Officeにフィードすることは可能ですか?