By Falcon of TinyLab.org
2015/04/18
最初发表:泰晓科技 – 聚焦嵌入式 Linux,追本溯源,见微知著!
原文链接:源码分析:动态分析 Linux 内核函数调用关系
评论说明:为更好地聚合大家的讨论,请到上面原文的评论区回复。
缘由
源码分析是程序员离不开的话题。
无论是研究开源项目,还是平时做各类移植、开发,都避免不了对源码的深入解读。
工欲善其事,必先利其器。
前两篇介绍了静态分析和应用程序部分的动态分析。这里开始讨论如何动态分析 Linux 内核部分。
准备工作
Ftrace
类似于用户态的 gprof
,在跟踪内核函数之前,需要对内核做额外的一些配置,在内核相关函数插入一些代码,以便获取必要信息,比如调用时间,调用次数,父函数等。
早期的内核函数跟踪支持有 KFT,它基于 -finstrument-functions
,在每个函数的出口、入口插入特定调用以便截获上面提到的各类信息。早期笔者就曾经维护过 KFT,并且成功移植到了 Loongson/MIPS 平台,相关邮件记录见:kernel function tracing support for linux-mips。不过 Linux 官方社区最终采用的却是 Ftrace
,为什么呢?虽然是类似的思路,但是 Ftrace
有重大的创新:
- Ftrace 只需要在函数入口插入一个外部调用:mcount,而 KFT 在入口和出口都要加
- Ftrace 巧妙的拦截了函数返回的地址,从而可以在运行时先跳到一个事先准备好的统一出口,记录各类信息,然后再返回原来的地址
- Ftrace 在链接完成以后,把所有插入点地址都记录到一张表中,然后默认把所有插入点都替换成为空指令(nop),因此默认情况下 Ftrace 的开销几乎是 0
- Ftrace 可以在运行时根据需要通过 Sysfs 接口使能和使用,即使在没有第三方工具的情况下也可以方便使用
所以,本文只介绍 Ftrace
,关于其详细用法,推荐看 Ftrace
作者 Steven 在 LWN 写的序列文章,例如:
- Debugging the kernel using Ftrace: 1, 2
- Secrets of the Ftrace function tracer
- trace-cmd: A front-end for Ftrace
对于本文要介绍的内容,大家只要使能 Ftrace
内核配置就可以,我们不会直接使用它的底层接口:
CONFIG_FUNCTION_TRACER
CONFIG_DYNAMIC_FTRACE
CONFIG_FUNCTION_GRAPH_TRACER
除此之外,还需要把内核函数的符号表编译进去:
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
如果要直接使用 Ftrace
的话,可以安装下述工具,不过本文不做进一步介绍:
$ sudo apt-get install trace-cmd kernelshark pytimerchart
Perf
Perf
最早是为取代 Oprofile
而生,从 2009 年开始只是增加了一个新的系统调用,如今强大到几乎把 Oprofile
逼退历史舞台。因为它不仅支持硬件性能计数器,还支持各种软件计数器,为 Linux 世界提供了一套完美的性能 Profiling 工具,当然,内核底层部分的函数 Pro