泰晓科技 -- 聚焦 Linux - 追本溯源,见微知著!
网站地址:https://tinylab.org

泰晓RISC-V实验箱,转战RISC-V,开箱即用
请稍侯

Ftrace 前端工具 trace cmd 介绍

Liu Lichao 创作于 2021/03/10

By 法海 of TinyLab.org Feb 06, 2021

前言

本文为 ftrace 系列文章第三篇,介绍 ftrace 前端工具 trace-cmd 基本用法。

前两篇文章中,我们知道了 ftrace 是什么,以及如何使用。ftrace 最有用的功能是窥探内核函数调用栈及调用关系。

除非是内嵌在应用程序中的 ftrace,其它的各种 ftrace 功能均可以通过 trace-cmd 实现。

本文以实例的形式,展示 trace-cmd 的功能。

function tracer

还以 dev_attr_show 为例,查看其调用栈的 trace-cmd 命令为:

# trace-cmd record -p function -l dev_attr_show --func-stack

提取 trace 结果的命令为:

# trace-cmd report
CPU 1 is empty
CPU 2 is empty
CPU 3 is empty
cpus=4
             top-29940 [000] 10255.306256: function:             dev_attr_show
             top-29940 [000] 10255.306262: kernel_stack:         <stack trace>
=> dev_attr_show (ffffffff914fad85)
=> sysfs_kf_seq_show (ffffffff911881b1)
=> kernfs_seq_show (ffffffff911864f7)
=> seq_read (ffffffff91109eca)
=> kernfs_fop_read (ffffffff91186cc1)
=> __vfs_read (ffffffff910df17b)
=> vfs_read (ffffffff910df22e)
=> ksys_read (ffffffff910df3c7)
=> __x64_sys_read (ffffffff910df41a)
=> do_syscall_64 (ffffffff90e04417)
=> entry_SYSCALL_64_after_hwframe (ffffffff91a0008c)
=> 19000a
=> __accumulate_pelt_segments (ffffffff90ef8720)
=> 0
=> 29ccd625bfa
=> 29ccd625cb7
=> 1b4b00000019
=> 19000a
=> __update_load_avg_se (ffffffff90ef8a10)

是不是很像 perf?先通过 record 子命令将结果记录到 trace.dat,再通过 report 命令进行结果提取。

命令解释:

  • -p:指定当前的 tracer,类似 echo function > current_tracer,可以是支持的 tracer 中的任意一个

  • -l:指定跟踪的函数,可以设置多个,类似 echo function_name > set_ftrace_filter

  • --func-stack:记录被跟踪函数的调用栈

没用到的相似参数:

  • -n:指定不跟踪的函数
    • 比如:trace-cmd record -p function -l 'dev*' -n dev_attr_show
    • 设置跟踪所有 dev 开头的函数,但是不跟踪 dev_attr_show
  • -g:指定 function_graph tracer 跟踪的 函数,类似 echo function_name > set_graph_function

  • -O:设置 options,比如设置 options/func_stack_trace 可以用 -O func_stack_trace,在 optoin 名称前加上 no 就是将 option 清 0

  • -P:设置跟踪的进程

注意,function_graph tracer 同时支持 -l/-g 参数,但是两者是有区别的,他们区别的本质还是 set_ftrace_filterset_graph_function 的区别。

  • -l 表示被跟踪的函数是叶子函数,不会跟踪其内部的调用子函数。
  • -g 表示会跟踪函数内部调用的子函数。如果不好理解,可以挑个函数去试试。

trace event

命令示例:

  • 跟踪 sched_switch :trace-cmd record -e sched:sched_switch
  • 跟踪某个 event 的同时记录调用栈:trace-cmd record -e xxx -T

实例:

  • 跟踪 sched_swtich events
# trace-cmd record -e sched_switch
  • 查看 sched_switch 消息格式
# cat /sys/kernel/debug/tracing/events/sched/sched_switch/format
  • report 结果的时候基于消息格式进行过滤
# trace-cmd report -F "sched_switch: prev_comm == 'kworker/3:0'"
cpus=4
     kworker/3:0-29594 [003] 12770.809817: sched_switch:         kworker/3:0:29594 [120] W ==> swapper/3:0 [120]
     kworker/3:0-29594 [003] 12770.938444: sched_switch:         kworker/3:0:29594 [120] W ==> swapper/3:0 [120]
     kworker/3:0-29594 [003] 12771.418656: sched_switch:         kworker/3:0:29594 [120] W ==> swapper/3:0 [120]
     kworker/3:0-29594 [003] 12771.450292: sched_switch:         kworker/3:0:29594 [120] W ==> swapper/3:0 [120]
  • 抓取过程中过滤使用 -f,注意,-f 过滤参数中没有 event 名称
# trace-cmd record -e sched_switch -f "prev_comm == 'kworker/3:0'"


Read Album:

Read Related:

Read Latest: