Ftrace是一个内部追踪,用来帮助开发者和设计者来发现内核正在干啥,可以用来调试和分析发生在用户态之外的延迟以及性能问题,
虽然ftrace被认为是function tracer,但是它是多种tracing工具的框架。有一个latency tracing来检查中断开关的延迟,有一个preemption来检查进程唤醒到调度的时间。
ftrace最常用的用途是event tracing。通过数百个内核静态事件点,并通过tracefs来激活,来发现内核发生了啥。
修改/etc/fstab
tracefs /sys/kernel/tracing tracefs defaults 0 0
或直接挂载
mount -t tracefs nodev /sys/kernel/tracing
4.1之前的系统,ftrace tracing control files在debugfs内,为了兼容性,当挂载debugfs文件系统时,自动挂载tracefs到:
/sys/kernel/debug/tracing
关键文件
current_tracer
当前配置的tracer,当打开trace_pipe读取事件时无法更改current_tracer。
# echo function > current_tracer
available_tracers
支持的tracers,注意static event points和kprobes使用nop,而不是function。
# cat available_tracers
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop
tracing_on
设置是否输出事件到ring buffer。
trace
存储当前trace的可读形式,可以cat查看,并且查看不消耗当前事件。
trace_pipe
输出内容和trace一样,但是消耗ring buffer。
trace_options
控制上述两个输出文件的内容。
options
set_ftrace_filter
对于function tracer和function_graph tracer,控制只输出哪些函数
set_ftrace_notrace
对于function tracer和function_graph tracer,控制不输出哪些函数
available_filter_functions
可用的function tracer的函数
kprobe_events
开启dynamic trace points,将在events目录下创建kprobes目录,该目录下是多个动态创建的时间目录,和静态事件一样。
# echo 'p:open do_sys_open file=+0(%si):string' > kprobe_events
#
# tree events/kprobes/
events/kprobes/
├── enable
├── filter
└── open
├── enable
├── filter
├── format
├── hist
├── id
└── trigger
静态事件是通过tracepoint实现的, tracepoints需要code snippets,来决定要提供的tracing information。
通过set_event开启,首先available_events查看支持的事件,然后echo进set_event
# echo sched_wakeup >> /sys/kernel/debug/tracing/set_event
要取消一个事件
# echo > /sys/kernel/debug/tracing/set_event
要激活所有事件
# echo *:* > /sys/kernel/debug/tracing/set_event
事件按subsystem组织。全名<subsystem>:<event>,支持通配符
通过event下面的enable文件开启
echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
查看事件的格式
# cat /sys/kernel/debug/tracing/events/sched/sched_wakeup/format
name: sched_wakeup
ID: 60
format:
field:unsigned short common_type; offset:0; size:2;
field:unsigned char common_flags; offset:2; size:1;
field:unsigned char common_preempt_count; offset:3; size:1;
field:int common_pid; offset:4; size:4;
field:int common_tgid; offset:8; size:4;
field:char comm[TASK_COMM_LEN]; offset:12; size:16;
field:pid_t pid; offset:28; size:4;
field:int prio; offset:32; size:4;
field:int success; offset:36; size:4;
field:int cpu; offset:40; size:4;
print fmt: "task %s:%d [%d] success=%d [%03d]", REC->comm, REC->pid,
REC->prio, REC->success, REC->cpu
事件过滤
通过filter文件设置。格式
field-name relational-operator value
The operators available for numeric fields are:
==, !=, <, <=, >, >=, &
And for string fields they are:
==, !=, ~
参考
Document/kprobes.txt
Documet/trace/ftrace.rst
Documet/trace/events.rst
Documet/trace/kprobetrace.rst