モジュールをロードするときにカーネルモジュール関数でSystemtapプローブを使用する方法。ロード中の特定のモジュールから呼び出される関数を印刷しようとしています。hello.ko
ロードされていないカーネルモジュールがあるとしましょう。今hello_init()
このモジュールの機能を追跡したいと思います。次のSystemtapスクリプトを試しましたが、うまくいきません。
注文する:
stap test10.stp -c "modprobe hello"
-->何も印刷されません。
システムタブスクリプト:
#!/usr/bin/env stap
global traces
probe module("hello").function("hello_init") {
printf("hello")
print_stack(backtrace())
}
カーネルモジュール:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static int __init hello_init(void)
{
printk(KERN_INFO "Hello world\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "Done\n");
}
module_init(hello_init);
module_exit(hello_exit);
答え1
私が知る限り、生成されたカーネルモジュールにのみstaprun
送信し、カーネルモジュールにプローブシンボルが見つからないため、カーネルモジュールにkprobeアドレスを設定しません。迅速な「テスト」のために代わりにアドレスを送信することができ、両方の機能が同じ署名を持つために機能します。kallsyms_on_each_symbol
int send_relocation_kernel()
staprun.c
kallsyms_on_each_symbol
module_kallsyms_on_each_symbol
kallsyms_on_each_symbol
int send_relocation_kernel()
変える
else if (linesize - pos == sizeof "kallsyms_on_each_symbol"
&& !strcmp(line + pos, "kallsyms_on_each_symbol" "\n"))
{
rc = send_a_relocation ("kernel", "kallsyms_on_each_symbol", address);
そして
else if (linesize - pos == sizeof "module_kallsyms_on_each_symbol"
&& !strcmp(line + pos, "module_kallsyms_on_each_symbol" "\n"))
{
rc = send_a_relocation ("kernel", "kallsyms_on_each_symbol", address);
この変更により、関数の検出器がinit()
何かを印刷する必要があります。