tracefs
Last updated
Was this helpful?
Last updated
Was this helpful?
tracefs 是 Linux 内核自带的调试工具,从久远的 2.6 内核就支持了,可以辅助定位 内核问题,原理参考 。
tracefs 有以下 tracer:
ftrace tracer(e.g. function tracer, function_graph tracer)
event tracer(e.g. 静态 tracepoint event, 动态 kprobe event)
基于 ftrace tracer,通过 current_tracer
节点来激活使用。
默认 event 是静态的,并且使用 tracepoint 实现,而利用 kprobe 机制,可以 动态的插入 event,实现静态 event 同样功能。 换句话说,静态 event 只能在代码中使用 tracepoint 写好后进行编译,动态 event 能够在系统运行中利用 kprobe 增加/删除。
最初 kprobe 是以内核模块形式开发(e.g. samples/kprobes/kprobe_example.c
), 但是开发代码不方便并且容易影响内核运行的稳定性。如何避免?
将 kprobe 封装成动态 kprobe event
通过 eBPF (e.g. bpftrace) 使用 kprobe
基于 event tracer,不需要通过 current_tracer
节点来激活使用。
静态 event 只需要通过 events/xxx/enable
打开 event 即可
动态 event,只需要通过 kprobe_events
增加/删除 event,并且通过 events/kprobes/xxx/enable
打开 event 即可。
trace
输出 ftrace buffter 内容
trace_pipe
以 PIPE 方式输出 ftrace buffter 内容
tracing_on
ftrace 总开关
current_tracer
指定 tracer 类型,默认是nop
available_tracers
所有可用的 tracer 类型
set_graph_function
指定要跟踪的函数,能够输出调用哪些函数
set_ftrace_filter
指定要过滤的函数,只输出单一函数
set_event
指定要跟踪的 event
available_events
所有可用的 events
kprobe_events
添加/删除动态 event
trace_marker
用户空间直接写内容到 ftrace buffer 中
set_ftrace_pid
指定要跟踪的进程 pid
trace_options
所有可选功能的打开/关闭情况
options/trace_printk
控制 trace_printk() 是否能够输出 comment 到 ftrace buffer
options/markers
控制 trace_marker 节点是否可写
options/funcgraph-retval
显示 function_graph tracer 的函数返回值
options/funcgraph-retaddr
显示 function_graph tracer 的函数返回地址
options/funcgraph-proc
显示 function_graph tracer 在哪个进程触发
options/func_stack_trace
显示 function tracer 的函数调用栈
options/stacktrace
显示 event 的函数调用栈
events/xxx/format
显示 event 输出格式
events/xxx/filter
过滤 event,如:echo "pid==123" > filter
只显示 pid 123 的 event
events/xxx/trigger
触发 event 的额外操作,如:echo stacktrace > trigger
打印函数调用栈
events/xxx/enable
使能 event
设置 function_graph tracer + set_graph_function
跟踪一个函数往下的调用路径
设置 function_graph tracer + set_graph_function + funcgraph-retval
跟踪 一个函数返回错误码的调用路径,再加上 kprobe_events
打印函数参数
设置 function_graph tracer + set_graph_function + funcgraph-retaddr
跟踪 一个函数返回地址,利用 faddr2line
获得 inline 函数的调用路径
设置 function tracer + set_ftrace_filter + func_stack_trace
跟踪 一个函数往上的调用路径
设置 event + stacktrace
跟踪一个函数往上的调用路径
第1行 tracer 类型
第2行 缓冲区中的事件数以及总数,如:358096/10552611,代表缓冲区因填满而丢失的 事件数为 10552611−358096=10194515
)。最后是 CPU数量
其它是记录的事件内容:进程名,PID,运行在哪个CPU上,延迟时间戳(格式:<秒>.<微秒>
), 函数名,打印内容
注意:如果结构体的成员变量是 char *
类型,如下:
使用 name=+0(+168($argN))
来打印。
与前面直接读写/sys/kernel/tracing/xxx
一样,如下:
参数解释:
-p
:指定当前的 tracer,类似 echo function > current_tracer
,支持 available_tracers
中的任意一个
-l
:指定过滤的函数,可以设置多个,类似 echo function_name > set_ftrace_filter
-g
:指定跟踪的函数,显示调用哪些函数,类似 echo function_name > set_graph_function
--func-stack
:记录被跟踪函数的调用栈,类似 echo 1 > options/func_stack_trace
-O
:指定可选功能,如 funcgraph-retval
,类似 echo 1 > options/funcgraph-retval
在 Linux Kernel 中有一个 vim 配置文件,用于方便阅读 function_graph 输出的日志,如下: