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
この関数をフィルタリングするように設定し、トレースをオンにしましたがthread_fn
、関数が呼び出されたことを示す dmesg ログを取得しているにもかかわらず、トレースには何も表示されません。
/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)
私はここで愚かなことをしていますか?それとも、既知の問題にぶつかっていますか?
編集
rootfs として Buildroot を使用しています。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
関数からトレースを取得することを期待していましたが、トレースで何も取得しません。今何が問題なのですか?