ftrace基础知识学习+使用实例 (仅作学习记录)

Trace 对于软件的维护和性能分析至关重要,ftrace 是当前 Linux 内核中一种新的 trace 工具。

ftrace(函数跟踪)是内核跟踪的“瑞士军刀”。它是内建在Linux内核中的一种跟踪机制。它能深入内核去发现里面究竟发生了什么,并调试它。ftrace不只是一个函数跟踪工具,它的跟踪能力之强大,还能调试和分析诸如延迟、意外代码路径、性能问题等一大堆问题。它也是一种很好的学习工具。

ftrace是由Steven Rostedy和Ingo Molnar在内核2.6.27版本中引入的。它有自己存储跟踪数据的环形缓冲并使用GCC配置机制

Ftrace 安装
http://www.omappedia.org/wiki/Installing_and_Using_Ftrace
==================================================

ftrace 相关的配置选项比较多,针对不同的跟踪器有各自对应的配置选项。不同的选项有不同的依赖关系,内核源码目录下的 kernel/trace/Kconfig 文件描述了这些依赖关系。读者可以参考 Makefile 文件和 Konfig 文件,然后选中自己所需要的跟踪器。

通常在配置内核时,使用 make menuconfig 会更直观一些。要将 ftrace 编译进内核,选中如下选项:

Kernel Hacking -> Tracers -> FUNCTION_TRACER
Kernel Hacking -> Tracers -> FUNCTION_GRAPH_TRACER (if possible)
Kernel Hacking -> Tracers -> STACK_TRACER  //  Trace max stack
Kernel Hacking -> Tracers -> DYNAMIC_FTRACE // enable/disable ftrace tracepoints dynamically


ftrace 通过 debugfs 向用户态提供访问接口。配置内核时激活 debugfs 后会创建目录 /sys/kernel/debug ,debugfs 文件系统就是挂载到该目录。要挂载该目录,挂载方法:

# mount -t debugfs nodev /sys/kernel/debug

激活内核对 ftrace 的支持后会在 debugfs 下创建一个 tracing 目录 /sys/kernel/debug/tracing 。该目录下包含了 ftrace 的控制和输出文件,根据编译内核时针对 ftrace 的设定不同,该目录下实际显示的文件和目录与这里也会不同。

tracing目录(/sys/kernel/debug/tracing)中的文件控制着跟踪的能力。根据你在内核配置时的选项的不同,这里列的文件可能稍有差异。你可以在内核源代码目录下/Documentation/trace[1]目录中找到这些文件的信息。

root@debian:/sys/kernel/debug# ls tracing/
available_events	    kprobe_events	set_graph_function
available_filter_functions  kprobe_profile	snapshot
available_tracers	    max_graph_depth	trace
buffer_size_kb		    options		trace_clock
buffer_total_size_kb	    per_cpu		trace_marker
current_tracer		    printk_formats	trace_options
dyn_ftrace_total_info	    README		trace_pipe
enabled_functions	    saved_cmdlines	trace_stat
events			    set_event		tracing_cpumask
free_buffer		    set_ftrace_filter	tracing_max_latency
function_profile_enabled    set_ftrace_notrace	tracing_on
instances		    set_ftrace_pid	tracing_thresh

让我们看看里面几个重要的文件:

● available_tracers: 被编译里系统的跟踪器。
● current_tracer: 这表示当前启用的哪个跟踪器。可以通过echo向表输入一个新的跟踪器来改变相应值。
● tracing_enabled: 让你可以启用或者禁用当前跟踪功能
● trace: 实际地的跟踪输出。
● set_ftrace_pid: 设置跟踪所作用的进程的PID。

要找到哪些跟踪器可用,你可以对available_tracers文件执行cat操作。与输出空间分离的跟踪器有:nop(它不是一个跟踪器,是默认设置的一个值)、函数(函数跟踪器)、函数图(函数图跟踪器),等等,如下所示:

root@debian:/sys/kernel/debug/tracing# cat available_tracers 
blk function_graph wakeup_rt wakeup irqsoff function nop

当你知道你需要使用哪个跟踪器后,启用它(ftrace每次只能打开一个跟踪器):

# cat current_tracer ##查看当前在用哪个跟踪器。

# echo function > current_tracer ##选择一个特定的跟踪器。

# cat current_tracer ##检查是否是你所设置的跟踪器。


使用下面的命令可以开始跟踪:

# echo 1 > tracing_on ##初始化跟踪。

# cat trace > /tmp/trace.txt ##将跟踪文件保存到一个临时文件。

# echo 0 > tracing_on ##禁用跟踪功能

# cat /tmp/trace.txt ##查看trace文件的输出。
现在trace文件的输入在trace.txt文件中。通过上面操作所得到的函数跟踪的一个示例输出

root@debian:/sys/kernel/debug/tracing# cat /tmp/trace.txt  | head -25
# tracer: function
#
# entries-in-buffer/entries-written: 88013/1669673   #P:2
#
#                              _-------=> irqs-off          
#                            /  _------=> need-resched      
#                            |/  _-----=> need-resched_lazy 
#                            ||/  _----=> hardirq/softirq   
#                            |||/  _---=> preempt-depth     
#                            ||||/  _--=> preempt-lazy-depth
#                            ||||| / _-=> migrate-disable   
#                            |||||| /     delay
#           TASK-PID   CPU#  ||||||  TIMESTAMP  FUNCTION
#              | |       |   ||||||     |         |
            bash-19599 [001] .....11 180574.090770: rt_spin_lock <-lockref_put_or_lock
            bash-19599 [001] .....11 180574.090770: rt_spin_unlock <-lockref_put_or_lock
            bash-19599 [001] .....11 180574.090770: migrate_enable <-lockref_put_or_lock
            bash-19599 [001] .....11 180574.090771: add_preempt_count <-migrate_enable
            bash-19599 [001] ....11. 180574.090771: unpin_current_cpu <-migrate_enable
            bash-19599 [001] ....11. 180574.090771: sub_preempt_count <-migrate_enable
            bash-19599 [001] ....... 180574.090772: inode_permission <-link_path_walk
            bash-19599 [001] ....... 180574.090772: __inode_permission <-inode_permission
            bash-19599 [001] ....... 180574.090772: generic_permission <-__inode_permission
            bash-19599 [001] ....... 180574.090773: security_inode_permission <-__inode_permission
            bash-19599 [001] ....... 180574.090773: selinux_inode_permission <-security_inode_permission
root@debian:/sys/kernel/debug/tracing# 

tracer的选项:

tracing的输入可以由一个叫trace_options的文件控制。可以通过更新/sys/kernel/debug/tracing/trace_options文件的选项来启用或者禁用各种域。trace_options的一个示例:

root@debian:/sys/kernel/debug/tracing# cat trace_options 
print-parent
nosym-offset
nosym-addr
noverbose
noraw
nohex
nobin
noblock
nostacktrace
trace_printk
noftrace_preempt
nobranch
annotate
nouserstacktrace
nosym-userobj
noprintk-msg-only
context-info
nolatency-format
sleep-time
graph-time
record-cmd
overwrite
nodisable_on_free
irq-info
markers
function-trace
nofunc_stack_trace

要禁用一个跟踪选项,只需要在相应行首加一个“no”即可。比如,echo notrace_printk >trace_options。(no和选项之间没有空格。)要再次启用一个跟踪选项,你可以这样:echo trace_printk >trace_options。

ftrace之特殊进程:

ftrace允许你对一个特殊的进程进行跟踪。在/sys/kernel/debug/tracing目录下,文件set_ftrace_pid的值要更新为你想跟踪的进程的PID。

当跟踪完成后,你需要清除set_ftrace_pid文件,用如下命令:> set_ftrace_pid

root@debian:/sys/kernel/debug/tracing# cat set_ftrace_pid 
19599
root@debian:/sys/kernel/debug/tracing# > set_ftrace_pid
root@debian:/sys/kernel/debug/tracing# cat set_ftrace_pid 
no pid




函数图跟踪器

函数图跟踪器对函数的进入与退出进行跟踪,这对于跟踪它的执行时间很有用。函数执行时间超过10微秒的标记一个“+”号,超过1000微秒的标记为一个“!”号。通过echo function_graph > current_tracer可以启用函数图跟踪器。

root@debian:~# echo function_graph > /sys/kernel/debug/tracing/current_tracer 
root@debian:~# cat /sys/kernel/debug/tracing/current_tracer
function_graph
root@debian:/sys/kernel/debug/tracing# cat trace | head -10
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |




有很多跟踪器,所有的列表在linux/ Documentation/trace/ftrace.txt文件中找得到。通过将跟踪器的名字echo到current_tracer文件中可以启用或禁用相应跟踪器。






动态跟踪:

我们会很轻易地被淹没在函数跟踪器所抛给我们的大量数据中。有一种动态的方法可以过滤出我们所需要的函数,排除那些我们不需要的:在文件set_ftrace_filter中指明。(首先从available_filter_functions文件中找到你需要的函数。)


你甚至可以对函数的名字使用通配符。我需要用所有的vmalloc_函数,通过echo vmalloc_* > set_ftrace_filter进行设置。

root@debian:/sys/kernel/debug/tracing# cat available_filter_functions | grep vmalloc
vmalloc_sync_all
is_vmalloc_or_module_addr
is_vmalloc_or_module_addr
vmalloc_open
get_vmalloc_info
setup_vmalloc_vm
vmalloc_to_page
remap_vmalloc_range_partial
remap_vmalloc_range
vmalloc_to_pfn
__vmalloc_node_range
__vmalloc_node
vmalloc_32_user
vmalloc_32
vmalloc_exec
vmalloc_node
vmalloc_user
__vmalloc
vmalloc
ext4_kvmalloc
snd_pcm_lib_get_vmalloc_page
snd_pcm_lib_free_vmalloc_buffer
_snd_pcm_lib_alloc_vmalloc_buffer
vmalloc_fault
root@debian:/sys/kernel/debug/tracing# 
 

事件跟踪:

也可以在系统特定事件触发的时候打开跟踪。可以在available_events文件中找到所有可用的系统事件.
root@debian:/sys/kernel/debug/tracing# cat available_events | head -10
irq_vectors:thermal_apic_exit
irq_vectors:thermal_apic_entry
irq_vectors:threshold_apic_exit
irq_vectors:threshold_apic_entry
irq_vectors:call_function_single_exit
irq_vectors:call_function_single_entry
irq_vectors:call_function_exit
irq_vectors:call_function_entry
irq_vectors:irq_work_exit
irq_vectors:irq_work_entry
root@debian:/sys/kernel/debug/tracing# 


为了启用某个事件,你需要:echo sys_enter_nice >>set_event(注意你是将事件的名字追加到文件中去,使用>>追加定向器,不是>)。要禁用某个事件,需要在名字前加上一个“!”号:echo '!sys_enter_nice' >> set_event 。
root@debian:/sys/kernel/debug/tracing# echo sys_enter_nice >> set_event 
root@debian:/sys/kernel/debug/tracing# cat set_event 
syscalls:sys_enter_nice
root@debian:/sys/kernel/debug/tracing# echo '!sys_enter_nice' >> set_event 
root@debian:/sys/kernel/debug/tracing# cat set_event 
root@debian:/sys/kernel/debug/tracing# 

以上内容为周六早对ftrace的基础知识的学习,内还是会继续。因为还木有学完!!

参考内容:http://blog.csdn.net/ganggexiongqi/article/details/6710201









你可能感兴趣的:(sil4linux,project,notes)