我编写了一个名为的测试内核模块hello.ko
,它产生一个具有以下功能的内核线程:
static int thread_fn(void *data)
{
while(1)
{
printk(KERN_INFO "thread is running....\n");
ssleep(5);
printk(KERN_INFO "checking if I need to stop\n");
if(kthread_should_stop())
break;
}
printk(KERN_INFO "thread exiting\n");
return 0;
}
static int __init hello_init(void)
{
printk(KERN_INFO "This is from init \n");
mythread = kthread_create(thread_fn, NULL, "mythread");
if(!mythread)
{
printk(KERN_ERR "Thread creation failed\n");
return 1;
}
else
{
printk(KERN_INFO "Thread created successfully.\n");
//thread is not running yet. Its in sleep state.
}
//bind to CPU 1
kthread_bind(mythread,2);
//start the thread
wake_up_process(mythread);
return 0;
}
static void __exit hello_exit(void)
{
int rc;
printk(KERN_INFO "This is from exit \n");
rc = kthread_stop(mythread);
if(rc)
printk(KERN_ERR "kthread stop failed\n");
}
module_init(hello_init);
module_exit(hello_exit);
现在我想通过 ftrace 跟踪这个函数。因此,我可以看到加载模块后该符号可用。
/sys/kernel/debug/tracing # cat available_filter_functions | grep thread_fn
smpboot_thread_fn
irq_thread_fn
irq_forced_thread_fn
thread_fn [hello] <<<< my module's function that is to be traced
我将此函数设置为过滤并打开跟踪,但我在跟踪上看不到任何内容,即使我从我的 dmesg 日志中获取thread_fn
表明该函数正在被调用。
/sys/kernel/debug/tracing # cat set_ftrace_filter
thread_fn [hello]
/sys/kernel/debug/tracing # cat set_graph_function
thread_fn [hello]
/sys/kernel/debug/tracing # cat tracing_on
1
/sys/kernel/debug/tracing # cat current_tracer
function_graph
/sys/kernel/debug/tracing # cat trace
# tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
/sys/kernel/debug/tracing #
我没有得到任何跟踪,但下面是dmesg
我从我试图跟踪的同一函数中反复获得的日志:
[ 856.633370] thread is running....
[ 861.752050] checking if I need to stop
[ 861.752476] thread is running....
[ 866.872571] checking if I need to stop
[ 866.872978] thread is running....
[ 871.992339] checking if I need to stop
[ 871.992821] thread is running....
[ 877.113347] checking if I need to stop
[ 877.113712] thread is running....
[ 882.232438] checking if I need to stop
我的内核版本是5.8.0
,我正在运行它qemu-aarch64 version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.37~cloud0)
我在这里做了什么愚蠢的事吗?还是我遇到了一些已知问题?
编辑
我使用 Buildroot 作为我的 rootfs。我trace-cmd
这次用的是而不是直接与 ftrace 交互。我加载了我的模块,可以dmesg
从thread_fn
.
trace-cmd record -p function_graph -l thread_fn
但我又没有得到任何东西。
编辑 在从@IanAbbott 评论中意识到错误之后,我稍微修改了我的代码,以便至少在跟踪处于活动状态时调用正在跟踪的函数(而不是之前没有进入/退出但只有几行的情况)在跟踪处于活动状态时循环执行)。
void hello_log(void)
{
printk(KERN_INFO "should I stop\n");
}
EXPORT_SYMBOL(hello_log);
static int thread_fn(void *data)
{
while(1)
{
printk(KERN_INFO "thread is running....\n");
ssleep(5);
hello_log();
if(kthread_should_stop())
break;
}
printk(KERN_INFO "thread exiting\n");
return 0;
}
现在我期待从hello_log
函数中获取跟踪,但我再次在跟踪中没有得到任何东西。现在怎么了?