問題タブ [kprobe]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
linux - /sys/kernel/debug/kprobes/blacklist にある機能を除くすべての機能で kprobe を使用できますか?
kprobe コマンドを使用して、いくつかのカーネル機能をトレースしています。私が使用するコマンドは次のとおりです。
kprobe "p:balance_pgdat"
しかし、次のエラーが発生します:
エラー: func balance_pgdat がありません
balance_pgdat が available_filter_functions にないことを確認しました。しかし、私の理解では、追跡できない機能は /sys/kernel/debug/kprobes/blacklist に保持されています。なぜ他の機能が kprobe で機能しないのでしょうか?
誰の助けにも感謝します!
bpf - BPF プログラムで常に 0 セッション ID を取得する
tty_write
カーネル関数を呼び出すプロセスのセッション ID を調べる BPF プログラムを作成しようとしています。現在の構造体からフィールドを取得することでこれを実行しようとしていますtask_struct
。私のコードは次のとおりです。
clang
ELF ファイルを使用して BPF プログラムをコンパイルし、それをgobpf のELF パッケージでロードしていることに注意してください。残念ながら、 の値sessionid
は常に 0 です。これはなぜですか? 4.11カーネルでbccを使用する前にこれを行ったので、セッションIDに間違ってアクセスしているとは思いません(bccがBPFプログラムを書き換える方法のため、プログラムを自分でコンパイルしたいときに同じコードを単純に使用することはできません)。にアクセスするための同等の作業 bcc コードsessionid
は次のとおりです。これは 4.11 カーネルでのみ機能することに注意してください。次のコードは 4.13 カーネルでは機能しません。ただし、上記のコードはどちらのカーネルでも機能しません。
4.11 カーネル:
uname -a
:Linux ubuntu16 4.11.0-14-generic #20~16.04.1-Ubuntu SMP Wed Aug 9 09:06:22 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
4.13 カーネル:
uname -a
: Linux ubuntu1710 4.13.0-32-generic #35-Ubuntu SMP Thu Jan 25 09:13:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
linux-kernel - 「echo 0 > /proc/sys/kernel/ftrace_enabled」を実行した後、kprobe モジュールが機能しない
ftrace について少し調べてみてください。
2 つのホスト間で TCP エコー プログラムが実行されています。
big switch( echo 0 > /proc/sys/kernel/ftrace_enabled
) をシャットダウンすると、自分の kprobe モジュールも機能しなくなります。カーネル ログ ファイルに printk メッセージが表示されません。また、pkt の変更操作が失敗し、pkt を正常に受信できます。それは本当に私をとても混乱させました。
私のテスト kprobe モジュールは次のとおりです。
linux - 一部の関数で kprobe が機能しない
handle_pte_fault
Linux カーネルで関数呼び出しを追跡するために kprobe を使用しようとしています。プローブできますhandle_mm_fault
が、プローブしようとするとhandle_pte_dault
、kprobe のハンドラはhandle_pte_fault
何も出力しません。
これを使用して、インラインであり、おそらく静的な関数をプローブできないことがわかりました。そこで、handle_pte_fault
関数の定義を次のように変更し、カーネルを再コンパイルしました。
から:
に:
handle_pte_fault
また、シンボルが存在することを確認するために以下を追加しました
それでも、handle_pte_fault 関数を追跡/調査することはできません。任意のヘルプまたは説明。kprobe は一部のランダム関数でしか機能しないということですか?
カーネル v4.13 を使用しています。
以下は、私が使用している kprobe のカーネル モジュール コードです。
c - Linux でハード irq をトレースする
Linux カーネルに関する私の経験はごくわずかです。私は最近それをいじり始めたばかりです。
研究目的で、パケットの最も早い到着時刻を追跡しようとしています。デバイス ドライバーを変更し、デバイス ドライバーの割り込みハンドラー関数にタイムスタンプを記録することで、デバイス ドライバー レベルでこれを行うことができます。申し訳ありませんが、この投稿は少し長くなる可能性があります。
たとえば、呼び出しのタイムスタンプを追跡するために、この関数 ( https://elixir.bootlin.com/linux/v4.7/source/drivers/net/ethernet/intel/i40e/i40e_main.c#L3232 ) を変更しました。この機能の。
さらに深く掘り下げて、この呼び出しのスタック トレースをたどると、以下のようなスタック トレースが見つかります。
- i40e_msix_clean_rings() -上記のリンクにある i40e ドライバーの i40e_main.c
- __handle_irq_event_percpu() -カーネル/irq/handle.c
- handle_irq_event_percpu() - kernel/irq/handle.c
- handle_irq_event() -カーネル/irq/handle.c
- handle_edge_irq() -カーネル/irq/chip.c
- handle_irq() - arch/x86/kernel/irq_64.c
- do_IRQ() - arch/x86/kernel/irq.c
- common_interrupt() -よくわかりませんが、実装は arch/x86/kernel/head_32.s の Early_idt_handler_common() に似ているはずです
関数 do_IRQ() 関数 (上記のスタック トレースの太字) でパケットの到着のタイムスタンプをトレースしようとしています。参考までに、do_IRQ 関数は次のようになります。
私の意図をもう少し明確にするために、この関数の変更を「 ** 」で囲んで示しました。
たとえば、私のテスト マシンでは、私の NIC は IRQ 番号 19 にバインドされています。int_number変数はその番号を表します。したがって、これにより、特定の IRQ 番号の IRQ を追跡できます。
シングル キュー NIC アダプターには関係ないように聞こえるかもしれませんが、フロー ディレクタを使用してパケットを固定キューに送信でき、各キューが特定の IRQ 番号にバインドされるため、マルチキュー アダプターには適用できます。したがって、これはパケットを簡単に追跡するのに役立ちます。
私のアプローチ:
- この関数内に手動実装を追加します。これは正しいアプローチではないと思います。
- kprobe を使用します。しかし、変数または引数の内容に基づいてトレースをフィルタリングできますか?
- ジェイプローブを使用。私は、このアプローチで、議論で遊ぶことができると思います。でもなんとかイベントをこなすことができました。私は単純に jprobe の例に従いました。( https://stuff.mit.edu/afs/sipb/contrib/linux/samples/kprobes/jprobe_example.c ) その他いくつか。
- 上記のアプローチを行っているときに、他のツールにも出くわしました。perf、perf-tools、eBPF など。しかし、どちらが私にとって最良のアプローチであるかはわかりません。
私の最終的なタスクを明確にするために、次のようなパケットの最も早い到着のタイムスタンプをキャプチャしようとしています:
これに関するあらゆる種類の情報をいただければ幸いです。
ありがとうございました !