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命令传输文件时的内核调用栈信息。

kernel_version

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

执行结果:

function

输出内容包含三列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

执行结果:

function_graph

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-function-graph

trace-cmd report分析结果:

trace-cmd-function-graph-result

kernelshark工具

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

apt install kernelshark

kernelshark

参考

posted @ 2025-05-04 10:12  bug批发零售  阅读(68)  评论(0)    收藏  举报