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

原创 嵌入式艺术 2024-01-23 07:14

1、Ftrace是什么

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

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

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

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

Tracing overview

2、Ftrace的实现原理

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

2.1 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:
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 函数追踪

image-20240110110558815

 

3.4.2 追踪图形显示

image-20240110110617669

 

3.4.3 动态过滤追踪

image-20240110110641149

 

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: 
 => mmc_rescan
 => process_one_work
 => worker_thread
 => kthread
 => ret_from_fork
 => 0

 

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

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

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

  • 按模块直接过滤
# 示例
Format: :mod:
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,并最终提供了自动化测试脚本,希望对大家有所帮助。


嵌入式艺术 分享一些高级嵌入式相关知识,包括:计算机基础、操作系统、Linux驱动、Linux内核、RT-thread等,除此之外,并且会组织一些简单的训练项目,一起成长。 我的创作理念:专注分享高质量的嵌入式文章,让大家读有所得!
评论
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-30 14:30 63浏览
  • 在现代科技浪潮中,精准定位技术已成为推动众多关键领域前进的核心力量。虹科PCAN-GPS FD 作为一款多功能可编程传感器模块,专为精确捕捉位置和方向而设计。该模块集成了先进的卫星接收器、磁场传感器、加速计和陀螺仪,能够通过 CAN/CAN FD 总线实时传输采样数据,并具备内部存储卡记录功能。本篇文章带你深入虹科PCAN-GPS FD的技术亮点、多场景应用实例,并展示其如何与PCAN-Explorer6软件结合,实现数据解析与可视化。虹科PCAN-GPS FD虹科PCAN-GPS FD的数据处
    虹科汽车智能互联 2024-11-29 14:35 149浏览
  • 《高速PCB设计经验规则应用实践》+PCB绘制学习与验证读书首先看目录,我感兴趣的是这一节;作者在书中列举了一条经典规则,然后进行详细分析,通过公式推导图表列举说明了传统的这一规则是受到电容加工特点影响的,在使用了MLCC陶瓷电容后这一条规则已经不再实用了。图书还列举了高速PCB设计需要的专业工具和仿真软件,当然由于篇幅所限,只是介绍了一点点设计步骤;我最感兴趣的部分还是元件布局的经验规则,在这里列举如下:在这里,演示一下,我根据书本知识进行电机驱动的布局:这也算知行合一吧。对于布局书中有一句:
    wuyu2009 2024-11-30 20:30 88浏览
  • 在电子技术快速发展的今天,KLV15002光耦固态继电器以高性能和强可靠性完美解决行业需求。该光继电器旨在提供无与伦比的电气隔离和无缝切换,是现代系统的终极选择。无论是在电信、工业自动化还是测试环境中,KLV15002光耦合器固态继电器都完美融合了效率和耐用性,可满足当今苛刻的应用需求。为什么选择KLV15002光耦合器固态继电器?不妥协的电压隔离从本质上讲,KLV15002优先考虑安全性。输入到输出隔离达到3750Vrms(后缀为V的型号为5000Vrms),确保即使在高压情况下,敏感的低功耗
    克里雅半导体科技 2024-11-29 16:15 119浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 57浏览
  • 光耦合器作为关键技术组件,在确保安全性、可靠性和效率方面发挥着不可或缺的作用。无论是混合动力和电动汽车(HEV),还是军事和航空航天系统,它们都以卓越的性能支持高要求的应用环境,成为现代复杂系统中的隐形功臣。在迈向更环保技术和先进系统的过程中,光耦合器的重要性愈加凸显。1.混合动力和电动汽车中的光耦合器电池管理:保护动力源在电动汽车中,电池管理系统(BMS)是最佳充电、放电和性能监控背后的大脑。光耦合器在这里充当守门人,将高压电池组与敏感的低压电路隔离开来。这不仅可以防止潜在的损坏,还可以提高乘
    腾恩科技-彭工 2024-11-29 16:12 117浏览
  • 国产光耦合器因其在电子系统中的重要作用而受到认可,可提供可靠的电气隔离并保护敏感电路免受高压干扰。然而,随着行业向5G和高频数据传输等高速应用迈进,对其性能和寿命的担忧已成为焦点。本文深入探讨了国产光耦合器在高频环境中面临的挑战,并探索了克服这些限制的创新方法。高频性能:一个持续关注的问题信号传输中的挑战国产光耦合器传统上利用LED和光电晶体管进行信号隔离。虽然这些组件对于标准应用有效,但在高频下面临挑战。随着工作频率的增加,信号延迟和数据保真度降低很常见,限制了它们在电信和高速计算等领域的有效
    腾恩科技-彭工 2024-11-29 16:11 106浏览
  • By Toradex胡珊逢简介嵌入式领域的部分应用对安全、可靠、实时性有切实的需求,在诸多实现该需求的方案中,QNX 是经行业验证的选择。在 QNX SDP 8.0 上 BlackBerry 推出了 QNX Everywhere 项目,个人用户可以出于非商业目的免费使用 QNX 操作系统。得益于 Toradex 和 QNX 的良好合作伙伴关系,用户能够在 Apalis iMX8QM 和 Verdin iMX8MP 模块上轻松测试和评估 QNX 8 系统。下面将基于 Apalis iMX8QM 介
    hai.qin_651820742 2024-11-29 15:29 150浏览
  • 戴上XR眼镜去“追龙”是种什么体验?2024年11月30日,由上海自然博物馆(上海科技馆分馆)与三湘印象联合出品、三湘印象旗下观印象艺术发展有限公司(下简称“观印象”)承制的《又见恐龙》XR嘉年华在上海自然博物馆重磅开幕。该体验项目将于12月1日正式对公众开放,持续至2025年3月30日。双向奔赴,恐龙IP撞上元宇宙不久前,上海市经济和信息化委员会等部门联合印发了《上海市超高清视听产业发展行动方案》,特别提到“支持博物馆、主题乐园等场所推动超高清视听技术应用,丰富线下文旅消费体验”。作为上海自然
    电子与消费 2024-11-30 22:03 71浏览
  • 国产光耦合器正以其创新性和多样性引领行业发展。凭借强大的研发能力,国内制造商推出了适应汽车、电信等领域独特需求的专业化光耦合器,为各行业的技术进步提供了重要支持。本文将重点探讨国产光耦合器的技术创新与产品多样性,以及它们在推动产业升级中的重要作用。国产光耦合器创新的作用满足现代需求的创新模式新设计正在满足不断变化的市场需求。例如,高速光耦合器满足了电信和数据处理系统中快速信号传输的需求。同时,栅极驱动光耦合器支持电动汽车(EV)和工业电机驱动器等大功率应用中的精确高效控制。先进材料和设计将碳化硅
    克里雅半导体科技 2024-11-29 16:18 157浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 59浏览
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-29 14:30 118浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 54浏览
  • 艾迈斯欧司朗全新“样片申请”小程序,逾160种LED、传感器、多芯片组合等产品样片一触即达。轻松3步完成申请,境内免费包邮到家!本期热荐性能显著提升的OSLON® Optimal,GF CSSRML.24ams OSRAM 基于最新芯片技术推出全新LED产品OSLON® Optimal系列,实现了显著的性能升级。该系列提供五种不同颜色的光源选项,包括Hyper Red(660 nm,PDN)、Red(640 nm)、Deep Blue(450 nm,PDN)、Far Red(730 nm)及Ho
    艾迈斯欧司朗 2024-11-29 16:55 155浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦