ftrace使用说明
ftrace简述
ftrace是一个Linux下的追踪框架,从kernel version 2.6.27由Steven Rostedt首次引入,用于追踪内核中函数的调用流程、调试和分析系统延迟信息等目的,了解内核中的正在发生的一些细节信息,方便内核开发人员或者系统运维人员快速定位问题。
ftrace的实现核心原理是利用了动态插桩的技术,在内核编译过程中为每个内核函数插入桩函数_mcount,这些桩函数调用指令在实际运行过程中默认都会被替换为nop,不会产生运行开销,只有在需要做追踪调试时,才会被替换为_mcount,并调用到相应的tracer来实现追踪对应的调试信息,调试信息就会写入到内核的RingBuffer结构中,当使用者需要使用用户态的程序获取这些信息时,都是通过debugfs的文件来直接读取的(一般挂载位置为/sys/kernel/debug/tracing)。
为了学习如何使用这个工具框架,以下我们使用kali linux 2022.3进行实验(内核版本为5.18.5),演示如何使用ftrace查看scp命令传输文件时的内核调用栈信息。

tracing文件简介
在/sys/kernel/debug/tracing目录下可以看到很多文件,以下挑选几个我们比较关注的文件作一个简介:
- trace
记录追踪调试信息,可以通过cat或者view等查看,可以用echo > tracer方式清空,它对应的是一个环形队列,所以其中的内容是有限的,到达最大容量后,新增的追踪内容会自动淘汰最老的追踪内容 - available_tracers
所有可以使用的追踪器,包括function, function_graph, blk,nop等,具体有哪些要看内核编译时启用了哪些追踪器 - tracing_on
控制是否启动追踪,为1时表示会向trace中自动追加新的内容,为0表示停止追踪 - trace_pipe
追踪信息的pipe版本,从该文件中读取时如果没有内容就会一直阻塞等待,有内容时就会立即读出内容并返回 - current_tracer
当前生效的追踪器,从available_tracers中选择一个填入 - set_ftrace_pid
指定追踪的进程id,这样ftrace就只会追踪其中指定的进程 - option/function-fork
是否追踪fork的子进程,如果为1表示fork出来的子进程id也会自动添加到set_ftrace_pid中,结束的进程的id也会从该文件中自动移除 - README
一个迷你版本的说明文件,简练得介绍了tracing中所有文件的含义
function追踪器
以下命令的执行可以收集scp命令开始执行1秒后连续2秒的所有内核态调用栈信息:
echo function > current_tracer
echo > trace
nohup scp ~/test.dat root@10.0.2.15:~/test2.dat >/dev/null 2>&1 &
scp_pid=$!
sleep 1
echo $scp_pid > set_ftrace_pid
echo 1 > tracing_on
sleep 2
echo 0 > tracing_on
view trace
执行结果:

输出内容包含三列TASK-PID,CPU,一些标识位,TIMESTAMP,FUNCTION这些部分组成。
其中需要说明下FUNCTION是由一个左箭头符号构成,箭头左边表示被调用的函数,右边表示主动调用的函数,通过这样的信息也能构建出系统调用的执行路径。
function_graph追踪器
以下命令的执行可以收集scp命令开始执行1秒后连续2秒的所有内核态调用栈信息:
echo function_graph > current_tracer
echo > trace
nohup scp ~/test.dat root@10.0.2.15:~/test2.dat >/dev/null 2>&1 &
scp_pid=$!
sleep 1
echo $scp_pid > set_ftrace_pid
echo 1 > tracing_on
sleep 2
echo 0 > tracing_on
view trace
执行结果:

trace中的结果有三列:CPU,DURATION,FUNCTION CALL
- CPU表示在第几个CPU上执行
- DURATION表示函数执行耗时,如果某一行没有显示DURATION的话,就表示该行对应的函数是入口,还有一些DURATION前面有加号,这是表示DURATION大于10us,其他还有类似的标记如下:
- $ :延迟大于1秒
- @ :延迟大于 100 ms
- * :延迟大于 10 ms
- # :延迟大于 1 ms
- ! :延迟大于 100 μs
- + :延迟大于 10 μs
- FUNCTION CALL表示函数调用的完整执行流程图:
- 以(){结尾的行表示进入该函数,对应在DURATION是没有值的;
- 以();结尾的行表示执行当前行的单个函数,对应的DURATION表示该函数执行的耗时;
- 以}结尾的行表示执行到该函数结尾,对应的DURATION表示与前面的(){配对的函数名的执行总耗时
trace-cmd工具
直接通过debugfs中tracing目录下的这些文件操作起来比较繁琐,并且报告并不易懂,所以有人开发了这个工具,让操作更便捷。
安装步骤:
apt install trace-cmd
执行步骤:
trace-cmd record -p function-graph -- scp ~/test.dat root@10.0.2.15:~/test2.dat
trace-cmd report | less
执行结果:

trace-cmd report分析结果:

kernelshark工具
此工具是针对trace-cmd的输出文件trace.dat进行分析后图形化展示结果,使用方法可以参考本文后面的链接。
安装步骤:
apt install kernelshark

参考
- ftrace的使用相关:
【一文秒懂】Ftrace系统调试工具使用终极指南
ftrace: trace your kernel functions!
ftrace
Linux Tracing Technologies - ftrace的原理相关:
linux性能工具--ftrace使用
Linux 内核的 ftrace 实现思路
一文搞懂 Ftrace 的实现原理 - ftrace的前端工具trace-cmd相关:
trace-cmd(1) — Linux manual page
使用trace-cmd跟踪Linux内核函数:一次愉快的内核探险 - ftrace的前端工具kernelshark:
KernelShark - DebugFS相关:
DebugFS
wikipedia的debugfs说明
浙公网安备 33010602011771号