高效分析Linux内核源码

最近在调试nvme的驱动 , 顺便分享一下分析内核代码的方法 , 我自己感觉异常高效 , 整体逻辑分分钟可以掌握的明明白白 。
对于给定的一个函数 , 例如nvme_probe()函数 , 如果想分析系统怎样调到这个函数,也就是想知道函数之前的调用栈 , 可以在函数中添加WARN_ON(1)打印堆栈 , 但是这样要重新编译源码 , 内核提供了ftrace 技术 , 可以使用ftrace function + 和enable func_stace_trace达到同样的效果 。
cd/sys/kernel/debug/tracing/echo nvme_probe > set_ftrace_filterecho 1 > ./options/func_stack_trace如果nvme_probe()函数中包含trace_event的内嵌函数 , 那就更加方便了 , 可以使用:
cd/sys/kernel/debug/tracing/echo 1 > ./events/nvme/nvme_probe/enableecho 1 > ./options/stacktrace 或者 echo 'stacktrace' > ./events/nvme/nvme_probe/trigger也可以设置内核启动参数:
trace_options=func_stack_trace,userstacktrace,sym-addr ftrace=function ftrace_filter="nvme_probe"效果图:
高效分析Linux内核源码文章插图
如果想知道nvme_probe()函数之后的调用逻辑 , 可以使用ftrace + func_graph的方式
debugfs=/sys/kernel/debugecho nop > $debugfs/tracing/current_tracerecho 0 > $debugfs/tracing/tracing_onecho 10 > $debugfs/tracing/max_graph_depth#echo $$ > $debugfs/tracing/set_ftrace_pidecho function_graph > $debugfs/tracing/current_tracerecho nvme_probe > $debugfs/tracing/set_graph_functionecho 1 > $debugfs/tracing/tracing_onexec "$@"【高效分析Linux内核源码】同样也可以设置内核启动参数:
ftrace=function_graph ftrace_graph_filter="nvme_probe"效果图:
高效分析Linux内核源码文章插图
(图中白色背景的函数还可以再展开详细查看)
呈现上图的效果可以借助折叠脚本:function-graph-fold.vim
脚本来源:
使用方法:
vim ./ftrace-nvme/func-graph-nvme-probe.log -S ./function-graph-fold.vim更详细的说明可以参考我的github: