【一文秒懂】Ftrace系统调试工具使用终极指南

这篇具有很好参考价值的文章主要介绍了【一文秒懂】Ftrace系统调试工具使用终极指南。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【一文秒懂】Ftrace系统调试工具使用终极指南

1、Ftrace是什么

FtraceFunction Trace的简写,由 Steven Rostedt 开发的,从 2008 年发布的内核 2.6.27 中开始就内置了。

Ftrace是一个系统内部提供的追踪工具,旨在帮助内核设计和开发人员去追踪系统内部的函数调用流程。

随着Ftrace的不断完善,除了追踪函数调用流程的作用外,还可以用来调试和分析系统的延迟和性能问题,并发展成为一个追踪类调试工具的框架。

除了Ftrace外,追踪类调试工具还包括:

2、Ftrace的实现原理

为了帮助我们更好的使用Ftrace,我们有必要简单了解Ftrace的实现原理。

2.1 Ftrace框架图

Ftrace的框架图如下:

【一文秒懂】Ftrace系统调试工具使用终极指南

由框架图我们可以知道:

  • ftrace包括多种类型的tracers,每个tracer完成不同的功能

  • 将这些不同类型的tracers注册进入ftrace framework

  • 各类tracers收集不同的信息,并放入到Ring buffer缓冲区以供调用。

 

2.2 Ftrace是如何记录信息的

Ftrace采用了静态插桩和动态插桩两种方式来实现。

静态插桩

我们在Kernel中打开了CONFIG_FUNCTION_TRACER功能后,会增加一个-pg的一个编译选项,这个编译选项的作用就是为每个函数入口处,都会插入bl mcount跳转指令,使得每个函数运行时都会进入mcount函数。

Ftrace一旦使能,对kernel中所有的函数插桩,这带来的性能开销是惊人的,有可能导致人们弃用Ftrace功能。

为了解决这个问题,开发者推出了Dynamic ftrace,以此来优化整体的性能。

动态插桩

这里的动态,是指的动态修改函数指令。

  1. 编译时,记录所有被添加跳转指令的函数,这里表示所有支持追踪的函数。

  2. 内核将所有跳转指令替换为nop指令,以实现非调试状态性能零损失。

  3. 根据 function tracer 设置,动态将被调试函数的nop指令,替换为跳转指令,以实现追踪。

 

总而言之,Ftrace记录数据可以总结为以下几个步骤

  1. 打开编译选项-pg,为每个函数都增加跳转指令

  2. 记录这些可追踪的函数,并为了减少性能消耗,将跳转函数替换为nop指令

  3. 通过flag标志位来动态管理,将需要追踪的函数预留的nop指令替换回追踪指令,记录调试信息。

 

3、如何使用Ftrace

3.1 配置详解

 CONFIG_FTRACE=y                             # 启用了 Ftrace
 CONFIG_FUNCTION_TRACER=y # 启用函数级别的追踪器
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y # 表示内核支持图形显示
 CONFIG_FUNCTION_GRAPH_TRACER=y # 以图形的方式显示函数追踪过程
 CONFIG_STACK_TRACER=y # 启用堆栈追踪器,用于跟踪内核函数调用的堆栈信息。
 CONFIG_DYNAMIC_FTRACE=y # 启用动态 Ftrace,允许在运行时启用和禁用 Ftrace 功能。
 CONFIG_HAVE_FTRACE_NMI_ENTER=y # 表示内核支持非屏蔽中断(NMI)时进入 Ftrace 的功能
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # 表示内核支持通过 mcount 记录函数调用关系。
 CONFIG_FTRACE_NMI_ENTER=y                   # 表示内核支持通过 mcount 记录函数调用关系。  
 CONFIG_FTRACE_SYSCALLS=y # 系统调用的追踪
 CONFIG_FTRACE_MCOUNT_RECORD=y # 启用 mcount 记录函数调用关系。
 CONFIG_SCHED_TRACER=y # 支持调度追踪
 CONFIG_FUNCTION_PROFILER=y # 启用函数分析器,主要用于记录函数的执行时间和调用次数
 CONFIG_DEBUG_FS=y # 启用 Debug 文件系统支持

上面只是介绍了部分配置,更多详细配置可自行了解。

并且上述配置不一定全部打开,勾选自己需要的即可,通常我们选择CONFIG_FUNCTION_TRACERCONFIG_HAVE_FUNCTION_GRAPH_TRACER即可,然后编译烧录到开发板。

 

3.2 挂载debugfs文件系统

Ftrace是基于debugfs调试文件系统的,所以我们的第一步就是先挂载debugfs

 mount -t debugfs none /sys/kernel/debug

此时我们能够在/sys/kernel/debug下看到内核支持的所有的调试信息了。

 # cd /sys/kernel/debug/
 # ls
 asoc               gpio               regmap
 bdi                 ieee80211           sched_debug
 block               memblock           sched_features
 clk                 mmc0               sleep_time
 device_component   mmc1               suspend_stats
 devices_deferred   mtd                 tracing
 dma_buf             opp                 ubi
 extfrag             pinctrl             ubifs
 fault_around_bytes pm_qos             wakeup_sources

 

3.3 traceing目录介绍

/sys/kernel/debug目录下,包含的是kernel所有的调试信息,本章只关注与tracing目录,下面挑选一些比较重要的属性文件来分析。

 

万变不离其宗,如此复杂的框架,设计人员已经提供了README文件,里面详解了各个属性文件的含义,我建议抛弃本文,看README吧:)

3.3.1 trace

trace :包含当前追踪的内容,以人类可读的格式展现,通过echo > trace来清除。

 

3.3.2 trace_pipe

trace_pipetrace 一样,都是记录当前的追踪内容,但它和 trace 不一样的是:

  • trace_pipe 的读操作将会阻塞,直到有新的追踪数据进来为止;

  • 当前从trace_pipe 读取的内容将被消耗掉,再次读 trace_pipe 又会阻塞到新数据进来为止。

简单的来说,cat trace_pipe是堵塞读取,有数据就读,没数据就等待;而cat trace有没有数据都是直接返回的

 

3.3.3 tracing_on

tracing_on:向 tracing_on 写入 1,启用追踪;向 tracing_on 写入 0,停止追踪。

追踪使用 ring buffer 记录追踪数据。修改 tracing_on 不会影响 ring buffer 当前记录的内容。

 

3.3.4 current_tracer

current_tracer 表示当前启用的 tracer ,默认为 nop ,即不做任何追踪工作:

 # cat current_tracer
 nop

 

3.3.5 available_filter_functions

available_filter_functions:可以被追踪的函数列表,即可以写到 set_ftrace_filter,set_ftrace_notrace,set_graph_function,set_graph_notrace 文件的函数列表。

 

3.3.6 available_tracers

available_tracers 文件中包含的是当前编译到内核的 tracer 列表,也表示当前内核支持的tracer列表。

该列表的内容,就是可以写到 current_tracertracer 名。

 # cat available_tracers
 function_graph function nop
  • nop:表示为空,不追踪

  • function:追踪函数调用

  • function_graph:以图形形式追踪函数调用

 

3.3.7 buffer_size_kb

buffer_size_kb 记录 CPU buffer 的大小,单位为 KB

per_cpu/cpuX/buffer_size_kb 记录 每个CPU buffer 大小,单位为 KB 。可通过写 buffer_size_kb 来改变 CPU buffer 的大小。

 

3.3.8 buffer_total_size_kb

buffer_total_size_kb 记录所有 CPU buffer 的总大小,即所有 CPU buffer 大小总和。

如有 128 个 CPU buffer ,每个大小 7KB,则 buffer_total_size_kb 记录的总大小为 128 * 7KB = 896。

buffer_total_size_kb 文件是只读的。

 

3.3.9 set_ftrace_filter

set_ftrace_filter :过滤函数追踪,仅仅追踪写入该文件的函数名。

可填入的参数,可以通过available_filter_functions文件查看当前支持的函数名。

该过滤功能,也有很多其他变体,如追踪某个模块的函数调用等。

官方给的示例:

 Format: :mod:<module-name>
 example: echo :mod:ext3 > set_ftrace_filter # 该模块必须是已经加载进去的模块

 

3.3.10 set_ftrace_notrace

set_ftrace_notrace:和 set_ftrace_filter 刚好相反,系统禁用对其中列举函数的追踪。

 

3.3.11 set_ftrace_pid

系统对 set_ftrace_pid 文件中指定的 PID进程进行追踪。

如果开启了 options/function-fork 选项,fork 的子进程的 PID 也会自动加入文件,同时该选项也会引起系统自动将退出进程的 PID 从文件中移除。

 

3.3.12 set_graph_function

此文件中列出的函数将导致函数图跟踪器仅跟踪这些函数以及它们调用的函数

但是该跟踪的记录,仍然受set_ftrace_filterset_ftrace_notrace 的影响。

 

3.3.12 set_graph_notrace

set_graph_function 类似,但当函数被命中时,将禁用函数图跟踪,直到退出函数。

 

更多干货可见:高级工程师聚集地,助力大家更上一层楼!

 

3.4 简单使用示例

一般我们挂载上debugfs后,tracing_on是处于打开状态的。

3.4.1 函数追踪

 

3.4.2 追踪图形显示

 

3.4.3 动态过滤追踪

 

3.4.4 重置追踪

 echo 0 > tracing_on         # 关闭trace
 echo > trace # 清空当前trace记录
 cat available_tracers # 查看当前支持的追踪类型
 echo function_graph > current_tracer # 设置当前的追踪类型
 echo 1 > tracing_on # 开启追踪
 cat trace # 查看追踪结果

 

4、进阶用法

上述章节,只是介绍了Ftrace最基本的命令,下面来看一下Ftrace在具体问题中的用法!

4.1 追踪任意命令

如何追踪我们执行的命令呢?

Ftrace支持追踪特定进程,通过set_ftrace_pid属性来设置指定进程。然后在该进程中,执行特定的命令。

首先我们需要设置好我们的追踪器

 mount -t debugfs none /sys/kernel/debug
 cd /sys/kernel/debug/tracing
 echo 0 > tracing_on # 关闭追踪器
 echo function > current_tracer # 设置当前追踪类别
 

在我们设置好追踪器后,使用如下命令,即可追踪我们执行的命令your_command

echo > trace; echo $$ > set_ftrace_pid; echo 1 > tracing_on; your_command; echo 0 > tracing_on

为什么要写成一条语句?

因为ftrace当打开时,在没有过滤的情况下,瞬间会抓取到内核所有的函数调用,为了更准确的抓取我们执行的命令,所以需要打开trace,执行完命令后,马上关闭。

 

4.2 追踪指定函数的调用流程

跟踪函数的时候,设置 echo 1 > options/func_stack_trace 即可在 trace 结果中获取追踪函数的调用栈。

mount -t debugfs none /sys/kernel/debug
cd /sys/kernel/debug/tracing
echo 0 > tracing_on # 关闭追踪器
cat available_filter_functions | grep "xxxxxx" # 搜索函数是否存在
echo xxxxxx > set_ftrace_filter # 设定追踪的函数
echo function > current_tracer # 设置当前追踪类别
echo 1 > options/func_stack_trace # 记录堆栈信息
echo > trace # 清空缓存
echo 1 > tracing_on # 开始追踪

效果如下

# cat trace
# tracer: function
#
# entries-in-buffer/entries-written: 2/2 #P:3
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
kworker/1:1-59 [001] .... 168.954199: mmc_rescan <-process_one_work
kworker/1:1-59 [001] .... 168.954248: <stack trace>
=> mmc_rescan
=> process_one_work
=> worker_thread
=> kthread
=> ret_from_fork
=> 0

 

4.3 追踪指定模块的所有函数

要想我们的ko文件能够被Ftrace记录到,我们需要在编译模块的时候,加上编译参数-pg,这点很重要,否则你在available_filter_functions列表中,查找不到你想要的函数。

然后,需要我们设置过滤器,设置方法有以下几种:

  • 按模块直接过滤

# 示例
Format: :mod:<module-name>
example: echo :mod:ext3 > set_ftrace_filter

追踪ext3模块内的所有函数

 

  • 按函数直接过滤

如果该模块内的函数,命名都有一定的规则,可以按照正则表达式来过滤

# 示例
echo "mmc*" > set_ftrace_filter

过滤包含mmc字符的所有函数

 

  • 按照函数差异来过滤

如果函数命名没有规律,又想过滤该模块所有函数,该怎么办?

按照加载模块前后的函数差异,写入到文件中来过滤

cat available_filter_functions > /tmp/1.txt
cat available_filter_functions > /tmp/2.txt
diff /tmp/1.txt /tmp/2.txt > /tmp/3.txt
cat /tmp/3.txt | sed 's/^+//' | awk '{print $1}' # 如果diff出来格式前带有+-号,需要手动去掉
cat /tmp/3.txt > set_ftrace_filter

 

5、自动化管理

Ftrace功能很强大,在内核层面我们通过echocat即可获取我们想要的所有信息,但是通过一次一次敲命令显得有些繁琐,自己也对常用的功能整合了一个自动化脚本,能够通过命令行,直接追踪特定模块、函数、命令,极大提高了调试效率。

PS:自动化脚本获取:公~号【嵌入式艺术】

# /root/common_trace.sh 
Usage: /root/common_trace.sh {module|funcs|funcs_stack|command|clear}
/root/common_trace.sh module ext4
/root/common_trace.sh funcs sysfs
/root/common_trace.sh funcs_stack sysfs
/root/common_trace.sh command sysfs [functions]
/root/common_trace.sh clear

脚本主要实现的功能有:

  • 追踪指定模块,查看所有调用流程

  • 追踪指定函数,查看该函数的调用链

  • 追踪指定函数,获取堆栈信息

  • 追踪用户命令,查看所有调用流程,并可选择指定函数来查看调用流程。

脚本除了command功能外,其他功能都需要手动调用common_trace.sh clear来停止追踪。

 

6、总结

以上,介绍了Ftrace的由来,实现原理,以及如何使用Ftrace,并最终提供了自动化测试脚本,希望对大家有所帮助。文章来源地址https://www.toymoban.com/news/detail-817654.html

到了这里,关于【一文秒懂】Ftrace系统调试工具使用终极指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【调试】ftrace(三)trace-cmd和kernelshark

    之前使用ftrace的时候需要一系列的配置,使用起来有点繁琐,这里推荐一个ftrace的一个前端工具,它就是trace-cmd 安装trace-cmd及其依赖库 安装 kernelshark 依赖 下载kernelshark并安装 注意:禁止使用 sudo apt-get install kernelshark 安装! cmake 版本必须在3.12以上。cmake版本更新方法参考:

    2024年02月06日
    浏览(31)
  • 微服务必学!RedisSearch终极使用指南,你值得拥有!

    🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是尘缘,一个在CSDN分享笔记的博主。📚📚 👉点击这里,就可以查看我的主页啦!👇👇 尘缘的个人主页 🎁如果感觉还不错的话请给我点赞吧!🎁🎁 💖期待你的加入,一起学习,一起进步!💖💖 前些天发现了一个巨牛的人工智

    2024年02月08日
    浏览(39)
  • Git教程(超详细,一文秒懂)

    1.1 何为版本控制 版本控制软件功能: 版本管理 :回退到历史上的任何版本 共享代码 :团队之间共享代码 团队合作开发-代码整合: 版本控制是一种记录文件内容变化, 以便将来查阅特定版本修订情况的系统。 1.2 为什么需要版本控制 个人开发过渡到团队协作。 需求 在项

    2024年02月05日
    浏览(43)
  • Chrome DevTools开发者工具调试指南

    Chrome DevTools是Chrome浏览器内置的一套开发者工具,提供了强大的调试和分析网页的功能。以下是使用Chrome DevTools进行调试的简要指南: 1:打开Chrome DevTools: 在Chrome浏览器中,右键点击网页上的任意位置,选择\\\"检查\\\"或\\\"审查元素\\\",或者使用快捷键Ctrl+Shift+I(Windows)/Cmd+Optio

    2024年02月06日
    浏览(58)
  • Nuxt项目整合Element UI(一文秒懂,快速上手)

    介绍 对于一个前端小白来说,使用一套已有的框架作为基础,可以达到事半功倍的效果,在这里我们选择Element UI。Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库(官方文档中的叙述),下面我们将开始在之前搭建好的nuxt项目中引入Element UI。 一

    2023年04月19日
    浏览(62)
  • 一文讲透TCP/IP协议 | 图解+秒懂+史上最全

    目录 🙋‍♂️ TCP/IP协议详解 🙋‍♂️ TCP/IP协议的分层模型 OSI模型的七层框架 TCP/IP协议与七层ISO模型的对应关系 (一)TCP/IP协议的应用层 (二)TCP/IP协议的传输层 (三)TCP/IP协议的网络层 (四)TCP/IP协议的链路层 🙋‍♂️ 图解 物理层:使用MAC解决设备的身份证问题

    2024年02月06日
    浏览(61)
  • C/C++【数据结构】一文秒懂二叉树

     个人主页:仍有未知等待探索_C语言疑难,数据结构,小项目-CSDN博客 专题分栏:数据结构_仍有未知等待探索的博客-CSDN博客 树形结构是一类非常重要的非线性结构。树形结构是节点之间有分支,并且具有层次关系的结构,它类似于自然界中的树。 就比如说:电脑中磁盘中的

    2024年02月05日
    浏览(46)
  • 快速上手linux | 一文秒懂Linux各种常用命令(下)

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 前俩篇我们给大家介绍完了,linux的常用文件操作和目录操作。而今天介绍的命令可就厉害了 既可以操作文件又可以操作目录 有 rm cp mv 等快来看看吧! 命令名称

    2024年02月04日
    浏览(47)
  • 【AI写作】怎样使用AI写作每天赚钱?—— 使用 AI 写作和每天产生被动收入的终极指南

    AI辅助写作:Rytr - Best AI Writer, Content Generator Writing Assistant https://poe.com/chatgpt  https://poe.com/claude  https://poe.com/ 目录

    2024年02月09日
    浏览(45)
  • 快速上手linux | 一文秒懂Linux各种常用目录命令(上)

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 首先我们要明白linux进入的命令行开头代码到底是什么意思: 我们来看下这张图片看完大家就懂了,详细列出了每一个字符的详细含义 前面我们知道了开头 local

    2024年02月04日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包