如何在加载模块时在内核模块函数上使用 Systemtap 探针。我正在尝试打印正在加载的特定模块所调用的函数。假设我有一个hello.ko
未加载的内核模块。现在我想跟踪hello_init()
该模块的函数。我尝试使用以下 Systemtap 脚本,但它不起作用。
命令:
stap test10.stp -c "modprobe hello"
--> 没有打印任何内容
系统tap脚本:
#!/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
仅发送kallsyms_on_each_symbol
到int send_relocation_kernel()
生成staprun.c
的内核模块,而该模块又不会在内核模块中设置 kprobe 地址,因为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()
应该打印一些内容。