这章我们先来看看如何使用ftrace。
说来惭愧,多少年前同事告诉我这种高级方法的时候,我还觉得麻烦,依然在使用printk。现在回想起来真实井底之蛙啊。
有几个非常不错的参考资料:
接下来就从来看几个例子:
Tracing测试文件目录
要和trace打交道都是要通过它的debugfs接口,默认情况下这个文件目录在 /sys/kernel/debug/tracing.
你也可以手动挂载到想要的位置:
Copy mount -t tracefs nodev /sys/kernel/tracing
在这个目录下有很多重要的文件,具体每个文件的作用可以在 中找到。这里解说几个比较重要的
设置当前使用的tracer
是否过滤函数
available_filter_functions
得到trace输出
控制是否将跟踪输出写入
像我这样的初级小白,了解这么几个文件就够用了。
使用function tracer
先来看一个完整的使用方法。
Copy echo 0 > tracing_on
echo function > current_tracer
echo 1 > tracing_on
# wait a while
echo 0 > tracing_on
cat trace
cat per_cpu/cpu0/trace
tracing_on用来控制是否实际输出到trace文件,所以我们在开始和结束时,我们都关掉输出,以免有太多的输出内容。 第二个命令用来指定这次使用的是function trace。因为没有设置函数过滤,所以应该是所有的内核函数都会被记录。 打开输出,停一会儿再关掉后,就可以通过trace文件查看这段时间内的内核运行情况了。
另外还可以通过查看per_cpu/cpu0/trace文件来只观察在cpu0上发生的内核函数调用。这是一个非常不错去除多个cpu之间干扰的好方法。
使用function_graph tracer
这个例子和之前的区别在于选择了不同的tracer,function_graph的话可以打印出函数调用的关系,更加方便理解。
Copy echo 0 > tracing_on
echo function_graph > current_tracer
echo 1 > tracing_on
# wait a while
echo 0 > tracing_on
cat trace
cat per_cpu/cpu0/trace
也就不做过多的解释。
使用trace_printk()
这个函数的用法和printk()一样,只是输出不在console,而是在ftrace的ring buffer。
而且在nop tracer的情况下也能在trace中看到输出。这样就不会被函数调用信息干扰到了。
汗颜,现在才知道这个。
使用function command
方法如下
Copy # echo '__bad_area_nosemaphore:traceoff' > set_ftrace_filter
# cat set_ftrace_filter
#### all functions enabled ####
__bad_area_nosemaphore:traceoff:unlimited
这样就可以在函数__bad_area_nosemaphore触发时,停止trace,留住最后的案发现场。
现实谁调用了某个函数
在学习内核的过程中,我们有时候会想了解一下一个函数都会被谁调用,整个调用栈是什么样子的。ftrace也提供了这个功能。
Copy [tracing]# echo kfree > set_ftrace_filter
[tracing]# cat set_ftrace_filter
kfree
[tracing]# echo function > current_tracer
[tracing]# echo 1 > options/func_stack_trace
[tracing]# cat trace | tail -8
=> sys32_execve
=> ia32_ptregs_common
cat-6829 [000] 1867248.965100: kfree <-free_bprm
cat-6829 [000] 1867248.965100: <stack trace>
=> free_bprm
=> compat_do_execve
=> sys32_execve
=> ia32_ptregs_common
[tracing]# echo 0 > options/func_stack_trace
[tracing]# echo > set_ftrace_filter
Profiling
Ftrace也能做profile。
Copy [tracing]# echo nop > current_tracer
[tracing]# echo 1 > function_profile_enabled
[tracing]# cat trace_stat/function0 |head
Function Hit Time Avg
-------- --- ---- ---
schedule 22943 1994458706 us 86931.03 us
poll_schedule_timeout 8683 1429165515 us 164593.5 us
schedule_hrtimeout_range 8638 1429155793 us 165449.8 us
sys_poll 12366 875206110 us 70775.19 us
do_sys_poll 12367 875136511 us 70763.84 us
compat_sys_select 3395 527531945 us 155384.9 us
compat_core_sys_select 3395 527503300 us 155376.5 us
do_select 3395 527477553 us 155368.9 us
没实验成功,以后再看看。