内核跟踪调试工具--ftrace案例使用

前言 本文为原创,可能会存在一些知识点或理解上的问题,欢迎切磋和交流  ^_^

一、简单聊聊ftrace

在定位内核问题时,往往需要深入到代码层面进行分析。在使用ftrace之前,我往往采用的是最笨的方法,即在认为可能走到的函数接口里打点,重新编包,进行替换验证,看函数是否有走到打点的流程里,通过这种添加调试日志方法进行分析函数调用关系,效率不能太低!编译一把内核包所花费的时间是是可想而知的!

有一天,在网上搜一些内核调试工具,看到ftrace这么个东东,简单操作了一下,溜的很,于是有了这篇文章的由来。

通过查看内核文档documentation/trace/ftrace.txt,可以知道ftrace是做啥的,如下图所示(翻译水平有限,感受一下原汁原味的介绍吧)。

内核跟踪调试工具--ftrace案例使用_第1张图片

ftrace是Function Trace的简写,该工具能够深入到代码级别,对内核进行跟踪和分析。

ftrace工作在debugfs文件系统上,所以要使用ftrace,首先要进入到/sys/kernel/debug/tracing目录下进行参数配置,该目录内容的样子是长这样的。

内核跟踪调试工具--ftrace案例使用_第2张图片

其中,着重用到的几个文件如下(具体作用通过内核文档进行翻译过来)

  • ·current_tracer:用于设置或显示已配置的当前跟踪器
  • ·available_tracers:包含并显示内核能够支持的不同类型跟踪器
  • ·tracing_on:负责启用或禁用数据写入到 Ring 缓冲区(如果启用它,数字 1 被写入到文件中,禁用它,数字 0 被写入)
  • ·trace:简单说,用于输出跟踪的函数调用关系
  • ·set_ftrace_filter:简单说,就是跟踪器会跟踪写入到该文件中的函数。默认情况下是所有函数,截图如下所示。

当写入vfs_read函数到该文件时,再cat一下,则跟踪器只跟踪vfs_read函数,如下图所示。

  • ·available_filter_functions_filter:该文件输出的是可以跟踪的所有函数列表,如果不确认函数是否可被跟踪,可以通过该配置进行搜索。
  • ·set_ftrace_notrace:该文件作用与set_ftrace_filter相反,写入该文件的函数将不会被跟踪器跟踪
  • ·set_ftrace_pid:简单说,就是跟踪写入到该文件的PID的线程
  • ·set_graph_function:函数图跟踪器,用于跟踪被列到该文件中的函数以及函数调用关系
  • ·set_graph_notrace:简单说就是列在该文件中的函数以及函数调用关系不会被跟踪器跟踪

可用的跟踪程序--available_tracers

可以使用如上命令查看该文件下支持的跟踪程序,一般用到的有如下三个(其他几个暂未用到)

  • ·function--无需参数的函数调用跟踪程序
  • ·function_graph--显示子调用的函数调用跟踪程序
  • ·nop--清空所有写入的跟踪器

二、小试牛刀

2.1.编写应用程序demo

我们使用ftrace工具跟踪vfs_read()函数,为方便调试起见,在执行open()前睡眠10s。

内核跟踪调试工具--ftrace案例使用_第3张图片

2.2.编写ftrace执行脚本

内核跟踪调试工具--ftrace案例使用_第4张图片

echo > $debugfs/tracing/set_ftrace_pid表示清空set_ftrace_pid

echo 1 > $debugfs/tracing/tracing_on表示启用ring缓冲区

echo `pidof read` > $debugfs/tracing/set_ftrace_pid 表示跟踪执行进程名称为read的进程号的进程

echo function_graph > $debugfs/tracing/current_tracer表示启用function_graph跟踪器

echo vfs_read > $debugfs/tracing/set_graph_function表示特别跟踪并显示vfs_read函数调用关系

echo 0 > $debugfs/tracing/tracing_on表示关闭ring缓冲区

cat ${debugfs}/tracing/trace > /root/DEMO/ftrace_example/vfs_read_ftrace.txt获取trace缓冲区内容并写到本地磁盘

===============================================================================

注意:

echo 1 > tracing_on,使能ring缓冲区打开,就会使得缓冲区打印大量无用函数调用,之前在用的时候,总是无缘无故打印几w行函数,查看起来很臃肿,后来再加入延时后,发现可以降低跟踪的函数行数。所以应该先关闭使能ring缓冲区,当设置好配置选项后,延时一段时间,再打开。

脚本类似如下:

内核跟踪调试工具--ftrace案例使用_第5张图片

脚本操作步骤:

(1)echo 0 > tracing_on  关闭使能ring缓存区

(2)echo nop > current_trace 清除跟踪器信息

(3)echo function_graph > current_trace 打开跟踪器

(4)echo function > set_graph_function 设置跟踪函数

(5)dd if=/dev/zero of=image ./bin  执行程序

(6)sleep xS  间隔一段时间

(7)echo 1 > tracing_on 打开使能ring缓冲区

===============================================================================

2.3.执行并获取跟踪文件

内核跟踪调试工具--ftrace案例使用_第6张图片

最后生成vfs_read_ftrace.txt文件,打开文件如下图所示

内核跟踪调试工具--ftrace案例使用_第7张图片

通过分析该文件,即可清晰知道vfs_read函数执行流程,每一个函数执行所花费时间。

但是,但是,但是,还没有完!(重要的事情说三遍)

该文件一共28927行!这么长个文件,该如何进行分析,是个问题!

2.4.vim对ftrace折叠处理

通过vim进行配置,编写vim配置文件.fungraph-vim,具体内容如下图

内核跟踪调试工具--ftrace案例使用_第8张图片

===============================================================================

特别说明:该vim配置文件和方法引用自宋宝华老师文章:《关于Ftrace的一个完整案例

===============================================================================

执行命令如下:

vim -S ~/.fungraph-vim vfs_read_ftrace.txt

即可将该文件进行折叠,通过空格键即可输出每个折叠的函数,方便查看和分析

内核跟踪调试工具--ftrace案例使用_第9张图片

左侧DURATION一栏用于显示函数执行占用的时间,关系图如下图所示。

内核跟踪调试工具--ftrace案例使用_第10张图片

如果有函数延时较大,会有相应特殊符号表示,如下表表示。

特殊符号

表示延时时间

‘$’

greater than 1 second

‘@’

greater than 100 milisecond

‘*’

greater than 10 milisecond

‘#’

greater than 1000 microsecond

‘!’

greater than 100 microsecond

‘+’

 greater than 10 microsecond

‘ ’

less than or equal to 10 microsecond

三、trace-cmd命令行工具

简单说,trace-cmd是用于操作ftrace的命令行工具,帮助信息如下图所示(不一一翻译)。

内核跟踪调试工具--ftrace案例使用_第11张图片

3.1.举个栗子

应用demo还是上述read文件,通过trace-cmd工具调试获取vfs_read()函数调用关系。执行程序截图如下所示。

内核跟踪调试工具--ftrace案例使用_第12张图片

内核跟踪调试工具--ftrace案例使用_第13张图片

 

其中命令为:trace-cmd record -p function_graph -g vfs_read -P 13947

通过帮助信息,可以知道其中每个选项作用。命令执行完后,按ctrl+C终止该命令,生成trace.dat文件。

通过trace-cmd report命令输出跟踪到本地磁盘文件,即可获取跟踪调用函数关系。

四、ftrace常见问题

4.1.跟踪器function_graph在低内核版本(比如3.10.0内核版本)中设置不了,导致系统重启

通过对比不同内核版本,trace配置并无差别,且ftrace中available_tracers支持function_graph跟踪器。

该疑问目前仍不清楚,如有知道的朋友,可随时沟通和交流。

4.2.有同事在使用ftrace跟踪函数调用关系过程中,说trace文件非常大,不方便定位想要看的那个函数调用关系

trace跟踪文件非常之大,是因为没有设置跟踪条件以及添加时延,导致跟踪所有的函数并且打印出来。该问题解决需要设置跟踪条件,针对某一具体函数执行流程进行trace,并且在设置配置后,使能ring缓冲区。

 

4.3.有同事在使用ftrace工具跟踪内核ko过程中,不知道做了什么操作,导致cat trace没有输出

出现该问题推测是因为设置的ftrace跟踪器配置未清除干净,而加载调试的内核ko由于使用未卸载,所以再次cat trace时没有任何输出,解决该问题比较暴力的方法是重启系统,或者先卸载掉内核ko,重置trace跟踪器条件。

五、参考网址

https://linux.cn/article-9273-1.html

https://linux.cn/article-9838-1.html

https://www.ibm.com/developerworks/cn/linux/l-cn-ftrace/index.html

http://www.voidcn.com/article/p-movbzbwr-ym.html

你可能感兴趣的:(内核调试工具,linux,kernel内核调试,ftrace应用分析)