在阅读本文前,建议先了解一下Ftrace是什么?有什么作用?
这里我之前写过一篇文章:【深入内核】linux ftrace详解
使能ftrace的方法
设置ftrace相关开关
这里介绍三种方式,三者选其一即可
通过BOARD_KERNEL_CMDLINE设置
参考change: https://gerrit.odm.mioffice.cn/c/device/xiaomi/mivendor/+/951786
通过设备树中的bootargs设置
通过fastboot指令设置
此方案只适用于适配了 fastboot oem bootargs 指令的项目
fastboot oem bootargs set "trace_event=timer:*,workqueue:*,irq:*,sched:*,mdss:*,power:*,regulator:*,msm_low_power:*" # 这个指令有可能失败,因为在适配fastboot oem bootargs指令时限制了字符的长度,可以自己修改一下这个限制
fastboot oem bootargs append "ftrace_dump_on_oops=2"
fastboot oem bootargs append "ftrace=function"
fastboot oem bootargs append "trace_buf_size=48M"
fastboot oem bootargs append "trace_clock=local"
打开内核trace相关的defconfig
确保如下的defconfig被正确设置,按需选择打开
CONFIG_TRACING=y # 整个内核跟踪子系统的总开关,必须启用
CONFIG_FTRACE=y # 使能Ftrace,GKI一般默认打开,如果没有打开,请设置
CONFIG_TRACE_IRQFLAGS_SUPPORT=y # IRQ ftrace相关时打开
CONFIG_TRACE_CLOCK=y # 一般默认打开
CONFIG_RING_BUFFER=y # 一般默认打开
CONFIG_EVENT_TRACING=y # 一般默认打开
CONFIG_CONTEXT_SWITCH_TRACER=y # 一般默认打开
# 下面是ftrace追踪器的选项,按需选择
CONFIG_IRQSOFF_TRACER=y # 记录 中断被禁止 (IRQs disabled) 的最大时间长度以及导致该延时的函数调用链。
CONFIG_FUNCTION_TRACER=y # function的tracer,主要用于记录函数调用情况
# CONFIG_FUNCTION_GRAPH_TRACER is not set # 按需打开,function的tracer的增强版
# CONFIG_STACK_TRACER is not set # 追踪可能导致内核栈溢出的函数调用链
# CONFIG_PREEMPT_TRACER is not set # 记录 抢占被禁止 (preemption disabled) 的最大时间长度以及导致该延时的函数调用链。
# CONFIG_SCHED_TRACER is not set # 追踪进程调度事件,记录进程的唤醒(wakeup)、切换(switch)、在CPU上的运行时长等信息。
# CONFIG_HWLAT_TRACER is not set # 专门检测由 硬件 (如 SMM, 管理引擎, 固件) 引入的延迟
# CONFIG_OSNOISE_TRACER is not set # 测量操作系统自身引入的噪声 (noise) 对应用程序造成的干扰延迟
# CONFIG_TIMERLAT_TRACER is not set # 测量从定时器中断触发 (IRQ) 到用户空间任务被调度运行 (thread) 之间的延迟
# CONFIG_ENABLE_DEFAULT_TRACERS=y # 自动开启一组被认为对大多数用户有用的“默认”追踪器
# CONFIG_TRACER_SNAPSHOT is not set # 为 ftrace 的环形缓冲区 (ring buffer) 提供“快照”功能
CONFIG_CONTEXT_SWITCH_TRACER=y
备注1:宏还有很多未列出,请按照实际情况去变更
备注2:关于跟踪器tracer的选择,一般情况下选择function即可,但是按照实际实际情况去变更。
备注3:这些tracer的defconfig宏打开,并不意味着用户就使用,只是标明当前系统支持这些tracer。
比如:使用cat /sys/kernel/debug/tracing/available_tracers
读出来的可支持的tracer就是这些defconfig控制的
备注4:真正测试前需要调哪个tracer是通过设置内核节点( )来控制,或者通过kernel cmdline中的
ftrace=function
来控制
在第1.1中的案例就是使用的是function的tracer
普通情况下的开启ftrace功能
选择一种tracer
echo function > /sys/kernel/debug/tracing/current_tracer
设置过滤函数(可选)
echo ip_rcv > /sys/kernel/debug/tracing/set_grapgh_function # 可以设置多个
使能trace event
# 比如 echo 1 > /sys/kernel/tracing/events/timer/timer_expire_entry/enable echo 1 > /sys/kernel/tracing/events/timer/timer_expire_exit/enable echo 1 > /sys/kernel/tracing/events/timer/hrtimer_cancel/enable
这个trace_event可以通过指令获取:cat /sys/kernel/debug/tracing/event
开始跟踪
echo 1 > /sys/kernel/tracing/tracing_on
高通的trace debug配置脚本(更推荐)
init.qti.kernel.debug-xxxx.sh
init.kernel.post_boot.sh
init.qti.kernel.early_debug-xxxx.sh
这部分参考change:https://gerrit.odm.mioffice.cn/c/platform/vendor/qcom-proprietary/kernel-scripts/+/941654
这部分主要是让机器在开机后自动运行设置trace的使能,以及trace_event的使能
因为需要配置的trace event如果很多,通过1.2的方式很麻烦,所以更推荐这种方式
确认ftrace被使能的方法
cat /sys/kernel/debug/tracing/available_tracers
check 是否有注册function的tracer
cat /sys/kernel/debug/tracing/trace
check 当前的tracer是否为function
cat /sys/kernel/debug/tracing/tracing_on
check 当前的tracer是否使能,应该为1
cat /proc/cmdline
check 添加的ftrace cmdline是否已添加,such as:
trace_event=timer:*,workqueue:*,irq:*,sched:*,mdss:*,power:*,regulator:*,msm_low_power:*, trace_buf_size=48M
查看ftrace日志
直接读取
如果需要动态测试,查看ftrace日志,可以通过下面的节点输出日志
cat /sys/kernel/debug/tracing/trace
# tracer: function
#
# entries-in-buffer/entries-written: 3/3 #P:4
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
kworker/0-0 [000] d..1 12345.678901: sched_switch: prev_comm=kworker/0:0 prev_pid=100 prev_prio=120 ==> next_comm=surfaceflinger next_pid=200 next_prio=110
从fulldump中导出ftrace
使用linux ramdump parser解析时增加额外的参数,--dump-ftrace --ftrace-args=all
,解析后再输出目录下存在如下的文件
待解析完后,即可在输出目录下得到ftrace日志
参考资料
KBA-230613194033_REV_11_Ftrace_summary.pdf
这是一篇高通出的 ftrace KBA,介绍了如何启用 ftrace、ftrace 黄金示例、如何添加一个实例 ftrace、minidump ftrace、如何解析 ftrace 以及 ftrace tips...