摘要
Ftrace 是一个设计用来帮助开发者和设计者监视内核的追踪器,可用于调试或分析延迟以及性能问题。ftrace 令人印象最深刻的是作为一个 function tracer,内核函数调用、耗时等情况一览无余。另外,ftrace 最常见的用途是事件追踪,通过内核是成百上千的静态事件点,看到系统内核的哪些部分在运行。实际上,ftrace 更是一个追踪框架,它具备丰富工具集:延迟跟踪检查、何时发生中断、任务的启用、禁用及抢占等。在 ftrace 的基线版本之上,还有很多第三方提供的开源工具,用于简化操作或者提供数据可视化等扩展应用。
一、Introduction
Developer(s): Steven Rostedt(RedHat) and others
Initial release: October 9, 2008;
Operating system: Linux (merged into the Linux kernel mainline in kernel version 2.6.27)
Type: Kernel extension
License: GNU GPL
Website: www.kernel.org/doc/Documentation/trace
二、ABC
在使用ftrace之前,需要确认调试目录是否已经挂载,默认目录:/sys/kernel/debug/ 。
debugfs是Linux内核中一种特殊的文件系统,非常易用、基于RAM,专门设计用于调试。(since version 2.6.10-rc3,https://en.wikipedia.org/wiki/Debugfs)。
1 | mount -t debugfs none /sys/kernel/debug |
挂载之后会自动创建如下文件:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50/sys/kernel/debug# ls -lrt
drwxr-xr-x. 2 root root 0 12月 28 17:24 x86
drwxr-xr-x. 3 root root 0 12月 28 17:24 boot_params
drwxr-xr-x. 34 root root 0 12月 28 17:24 bdi
-r--r--r--. 1 root root 0 12月 28 17:24 gpio
drwxr-xr-x. 3 root root 0 12月 28 17:24 usb
drwxr-xr-x. 4 root root 0 12月 28 17:24 xen
drwxr-xr-x. 6 root root 0 12月 28 17:24 tracing
drwxr-xr-x. 2 root root 0 12月 28 17:24 extfrag
drwxr-xr-x. 2 root root 0 12月 28 17:24 dynamic_debug
drwxr-xr-x. 2 root root 0 12月 28 17:24 hid
-rw-r--r--. 1 root root 0 12月 28 17:24 sched_features
drwxr-xr-x. 2 root root 0 12月 28 17:24 mce
drwxr-xr-x. 2 root root 0 12月 28 17:24 kprobes
-r--r--r--. 1 root root 0 12月 28 17:24 vmmemctl
/sys/kernel/debug/tracing# ls -lrt
-rw-r--r--. 1 root root 0 12月 28 17:24 tracing_thresh
-rw-r--r--. 1 root root 0 12月 28 17:24 tracing_on
-rw-r--r--. 1 root root 0 12月 28 17:24 tracing_max_latency
-rw-r--r--. 1 root root 0 12月 28 17:24 tracing_enabled
-rw-r--r--. 1 root root 0 12月 28 17:24 tracing_cpumask
drwxr-xr-x. 2 root root 0 12月 28 17:24 trace_stat
-r--r--r--. 1 root root 0 12月 28 17:24 trace_pipe
-rw-r--r--. 1 root root 0 12月 28 17:24 trace_options
--w--w----. 1 root root 0 12月 28 17:24 trace_marker
-rw-r--r--. 1 root root 0 12月 28 17:24 trace_clock
-rw-r--r--. 1 root root 0 12月 28 17:24 trace
-rw-r--r--. 1 root root 0 12月 28 17:24 sysprof_sample_period
-r--r--r--. 1 root root 0 12月 28 17:24 set_graph_function
-rw-r--r--. 1 root root 0 12月 28 17:24 set_ftrace_pid
-rw-r--r--. 1 root root 0 12月 28 17:24 set_ftrace_notrace
-r--r--r--. 1 root root 0 12月 28 17:24 saved_cmdlines
-r--r--r--. 1 root root 0 12月 28 17:24 README
drwxr-xr-x. 2 root root 0 12月 28 17:24 options
-rw-r--r--. 1 root root 0 12月 28 17:24 function_profile_enabled
-r--r--r--. 1 root root 0 12月 28 17:24 dyn_ftrace_total_info
-rw-r--r--. 1 root root 0 12月 28 17:24 buffer_size_kb
-r--r--r--. 1 root root 0 12月 28 17:24 available_tracers
-r--r--r--. 1 root root 0 12月 28 17:24 available_filter_functions
-rw-r--r--. 1 root root 0 12月 28 17:24 set_event
-r--r--r--. 1 root root 0 12月 28 17:24 printk_formats
drwxr-xr-x. 34 root root 0 12月 28 17:24 per_cpu
drwxr-xr-x. 24 root root 0 12月 28 17:24 events
-r--r--r--. 1 root root 0 12月 28 17:24 available_events
-r--r--r--. 1 root root 0 12月 28 17:24 kprobe_profile
-rw-r--r--. 1 root root 0 12月 28 17:24 kprobe_events
-r--r--r--. 1 root root 0 12月 28 17:24 stack_trace
-rw-r--r--. 1 root root 0 12月 28 17:24 stack_max_size
-rw-r--r--. 1 root root 0 5月 31 11:50 current_tracer
-rwxr-xr-x. 1 root root 0 5月 31 11:57 set_ftrace_filter
三、BASIC
1. Function tracer
以Function tracer为例,结果存储在 trace,该文件类似一张报表,该表将显示 4 列信息。首先是进程信息,包括进程名和PID ;第二列是CPU;第三列是时间戳;第四列是函数信息,缺省情况下,这里将显示内核函数名以及它的上一层调用函数。
1 | cd /sys/kernel/debug/tracing |
2. Function graph tracer
Function graph tracer 和 function tracer 类似,但输出为函数调用图,更加容易阅读:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# tracer: function_graph
#
# TIME CPU DURATION FUNCTION CALLS
# | | | | | | | |
21) ==========> |
21) | smp_apic_timer_interrupt() {
31) ==========> |
31) | smp_apic_timer_interrupt() {
8) | smp_apic_timer_interrupt() {
11) 2.598 us | native_apic_mem_write();
18) 3.106 us | native_apic_mem_write();
30) ==========> |
30) | smp_apic_timer_interrupt() {
3) 3.590 us | native_apic_mem_write();
22) 2.944 us | native_apic_mem_write();
7) 3.392 us | native_apic_mem_write();
17) ==========> |
17) | smp_apic_timer_interrupt() {
27) ==========> |
27) | smp_apic_timer_interrupt() {
16) ==========> |
16) | smp_apic_timer_interrupt() {
四、体系结构
Ftrace有两大组成部分,framework和一系列的tracer 。每个tracer完成不同的功能,它们统一由framework管理。 ftrace 的trace信息保存在ring buffer中,由framework负责管理。Framework 利用debugfs建立tracing目录,并提供了一系列的控制文件。
ftrace is a dynamic tracing system. 当你开始“ftracing”一个内核函数的时候,该函数的代码实际上就已经发生变化了。内核将在程序集中插入一些额外的指令,使得函数调用时可以随时通知追踪程序。
WARNNING:使用ftrace追踪内核将有可能对系统性能产生影响,追踪的函数越多,开销越大。
使用者必须提前做好准备工作,生产环境必须谨慎使用。
1 | #cat available_tracers //查看支持的tracers |
五、Useful Tools
1. trace-cmd
trace-cmd是一个非常有用的Ftrace命令行工具。1
2
3sudo apt-get install trace-cmd
或者
git clone git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git
使用方法:1
2
3
4
5
6
sudo trace-cmd record --help #help
sudo trace-cmd record -p function -P 123456 #record for PID
sudo trace-cmd record -p function -l do_page_fault #record for function
plugin 'function'
Hit Ctrl^C to stop recording
trace.dat1
2
3
4
5
6
7
8
9
10
11
12$ sudo trace-cmd report
chrome-15144 [000] 11446.466121: function: do_page_fault
chrome-15144 [000] 11446.467910: function: do_page_fault
chrome-15144 [000] 11446.469174: function: do_page_fault
chrome-15144 [000] 11446.474225: function: do_page_fault
chrome-15144 [000] 11446.474386: function: do_page_fault
chrome-15144 [000] 11446.478768: function: do_page_fault
CompositorTileW-15154 [001] 11446.480172: function: do_page_fault
chrome-1830 [003] 11446.486696: function: do_page_fault
CompositorTileW-15154 [001] 11446.488983: function: do_page_fault
CompositorTileW-15154 [001] 11446.489034: function: do_page_fault
CompositorTileW-15154 [001] 11446.489045: function: do_page_fault
在很有情况下不能使用函数追踪,需要依赖 事件追踪 的支持,例如:
1 | # cat available_events //查看支持的事件类型 |
输出如下:1
2
3
4
516169.624862: Chrome_ChildIOT:24817 [112] S ==> chrome:15144 [120]
16169.624992: chrome:15144 [120] S ==> swapper/3:0 [120]
16169.625202: swapper/3:0 [120] R ==> Chrome_ChildIOT:24817 [112]
16169.625251: Chrome_ChildIOT:24817 [112] R ==> chrome:1561 [112]
16169.625437: chrome:1561 [112] S ==> chrome:15144 [120]
切换路径:PID 24817 -> 15144 -> kernel -> 24817 -> 1561 -> 15114。
2. perf-tools
perf-tools 是性能调试大神Brendan Gregg开发的一个工具包,提供了很多强大的功能,例如:
iosnoop: 磁盘I/O分析详细包括延迟
iolatency: 磁盘I/O分析概要(柱状图)
execsnoop: 追踪进程exec()
opensnoop: 追踪open()系统调用,包含文件名
killsnoop: 追踪kill()信号(进程和信号详细)
代码下载:https://github.com/brendangregg/perf-tools
1 | # ./execsnoop //显示新进程和参数: |
六、可视化工具:KernelShark
KernelShark是trace-cmd的前端工具,提供了对trace.dat的可视化分析(Graph View 、List View、Simple and Advance filtering)。
扩展阅读:动态追踪技术
- 操作系统原理 | How Linux Works(一):How the Linux Kernel Boots
- 操作系统原理 | How Linux Works(二):User Space & RAM
- 操作系统原理 | How Linux Works(三):Memory
- 动态追踪技术(一):DTrace 导论
- 动态追踪技术(二):strace+gdb 溯源 Nginx 内存溢出异常
- 动态追踪技术(三):Tracing Your Kernel Function!
- 动态追踪技术(四):基于 Linux bcc/BPF 实现 Go 程序动态追踪
- 动态追踪技术(五):Welcome DTrace for Linux
参考文献
- (Key)Julia Evans:ftrace: trace your kernel functions!
- (Key)IBM developerWorks@刘明:ftrace简介,2009
- Debugging the kernel using Ftrace - part 1 (Dec 2009, Steven Rostedt)
- Debugging the kernel using Ftrace - part 2 (Dec 2009, Steven Rostedt
- Secrets of the Linux function tracer (Jan 2010, Steven Rostedt)
- trace-cmd: A front-end for Ftrace (Oct 2010, Steven Rostedt)
- Using KernelShark to analyze the real-time scheduler (2011, Steven Rostedt)
- Ftrace: The hidden light switch (2014, Brendan Gregg)
- (Key)the kernel documentation:ftrace.txt
- documentation on events you can trace Documentation/events.txt
- some docs on ftrace design for linux kernel devs (not as useful, but interesting)
- Documentation/ftrace-design.txt
- trace-cmd图形化工具:KernelShark
- Youtube:ELC2011 Ftrace GUI (KernelShark)
- (Key)StevenRostedt:ELC2011_KernelShark(quick tutorial)(PDF)