この質問にすぐに戻ることはできないかもしれませんが、私はそれを見つけたので書き留めておこうと思いました:
まず、これを呼び出す適切な方法がわかりません。タイトルに「降臨」「解決」をつけてみましたが、もっと適切な言葉があれば知りたいです。本質的に、私が望むのは、カーネル システム コール - ar.linux.itから取得したこの画像に示されているようなものを取得することです。
より具体的な例を次に示します。次の小さくて機能しない ( 「Assertion failed」が発生するだけです) が、コンパイル可能な ALSA コードを考えてみましょう。
// atest.c
#include <alsa/asoundlib.h>
static snd_pcm_t *playbck_pcm_handle;
static char wrsrcbuf[256] = {[0 ... 255] = 5}; // initialization gcc specific
static snd_pcm_uframes_t period_frames = 32;
static int ret;
int main() {
ret = snd_pcm_writei(playbck_pcm_handle, wrsrcbuf, period_frames);
return 0;
}
私はこれを構築することができます:
gcc -Wall -g atest.c -lasound -o atest
...そして、次の方法でアセンブリを観察できますobjdump
:
$ objdump -d -M intel -S atest
...
int main() {
...
ret = snd_pcm_writei(playbck_pcm_handle, wrsrcbuf, period_frames);
804842d: 8b 15 40 a1 04 08 mov edx,DWORD PTR ds:0x804a140
...
8048447: e8 0c ff ff ff call 8048358 <snd_pcm_writei@plt>
...
return 0;
8048451: b8 00 00 00 00 mov eax,0x0
}
...
...そして、これはサブルーチン<snd_pcm_writei@plt>
が呼び出されることだけを教えてくれます-しかし、たとえば、どのライブラリオブジェクトファイルで教えてくれません(補足:コンパイルがパスした場合gcc
、ライブラリの場所を次のように知ることになります)現在のシステム上のオブジェクト ファイル?)
次に、原則としてプログラムを実行し (ただし、このプログラムではありません)、組み込みの Linux トレース ( ftrace
) 機能を使用し/sys/kernel/debug/tracing/trace
て、ランタイム カーネル ログを取得します。カーネルのプリエンプティブな性質とスケジューリングにより、実行順序の一定性を実際に期待することはできませんが、原則として、次のようなものを得ることができます (ただし、適切なデバイスを実行しないため、上記の例からではありません)。初期化):
sys_ioctl() {
...
do_vfs_ioctl() {
snd_pcm_playback_ioctl() {
snd_pcm_playback_ioctl1() {
_cond_resched();
copy_from_user() {
...
}
snd_pcm_lib_write() {
snd_pcm_lib_write1() {
_raw_read_lock_irq();
_raw_spin_lock();
snd_pcm_update_hw_ptr() {
snd_pcm_update_hw_ptr0() {
azx_pcm_pointer() {
...
したがって、これは、snd_pcm_writei
コマンドに応答して - 最終的にsys_ioctl
-> snd_pcm_playback_ioctl
->snd_pcm_lib_write
が呼び出されることを示しています。これは、カーネルに組み込まれた ALSA 関数です。ただし、次のような関数もazx_pcm_pointer()
呼び出されます。これらはデバイス ドライバーのazx_pcm_pointer
一部です ( はhda-intel
driverの一部です)。
だから私の質問は - プログラムの関数「降下」ツリーをユーザー空間からカーネル空間に出力できるアプリケーションはありますか? コンパイル時に (それgcc
自体になりますが、その目的のために存在する場合はいくつかの特別なスイッチを使用します) 、またはポストコンパイル(objdump
分析されたプログラム自体が実行されていないため、「実行時」ではない を使用する場合など)?たとえば、この例では、次のような出力が必要です。
int main() { # atest
...
ret = snd_pcm_writei(playbck_pcm_handle, wrsrcbuf, period_frames); # atest
...
<snd_pcm_writei@plt> # libasound.so ??
...
sys_ioctl() { # ???.(k)o?
...
snd_pcm_playback_ioctl() { # ???.(k)o?
...
azx_pcm_pointer() { # /lib/modules/.../sound/pci/hda/snd-hda-intel.ko
...
...
コードが多数のコード パスを取る可能性があることを理解しています。したがって、このツールがそれらすべてを解決できることを願っています。または、コード パスの数を制限するために変数を設定できるようにすることもできます。しかし、一般に、出力はツリーになります (これは、たとえば で視覚化できますgraphviz
)。
また、ランタイムに入らないとドライバーを解決できない可能性があることも理解しています(デバイスとそのドライバーは、ユーザー空間プログラムのコマンドライン引数などによって実行時に指定できるため)。しかし、少なくとも「ここで未指定のドライバー関数が呼び出されます」のような通知が届くことを願っています。