Linux 调试追踪: trace-cmd 和 kernelshark

1. 前言

限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。

2. 概述

本文演示 ARM64 嵌入式平台下 trace-cmd 和其前端 kernelshark 的使用。trace-cmd 是为便利 ftrace 的使用而设计的 ftrace 前端工具,而 kernelshark 又作为调用 trace-cmd 和可视化 trace-cmd 抓取数据的工具,ftrace、trace-cmd、kernelshark 三者的层次关系如下:

kernelshark (作为 trace-cmd 前端)
     ^
-----|------
     |
     V
 trace-cmd (作为 ftrace 的前端)
     ^
-----|-----
     V
  ftrace

3. trace-cmd

trace-cmd 是为便利 ftrace 的使用而设计的 ftrace 前端工具。

3.1 下载

我们把 libtraceeventlibtracefstrace-cmd 下载到同一目录 $HOME/trace_cmd_tool 下:

$ cd ~
$ mkdir trace_cmd_tool
$ cd trace_cmd_tool

$ git clone git://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
$ git clone git://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git
$ git clone git://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git

$ tree -L 1
.
├── libtraceevent
├── libtracefs
└── trace-cmd

下载完代码后,接下来编译、安装它们,假定将所有编译生成的相关库文件和程序安装到 $HOME/trace_cmd_tool/_install 目录下。

3.2 交叉编译

在编译过程中,假定交叉编译器为 aarch64-none-linux-gnu-gcc,读者请替换为自己使用的交叉编译器;另外,读者也需要将 $HOME 替换为自己的实际 home 目录。注意,要使用绝对路径,不要使用相对路径,否则会出现安装路径错误的问题,因为每个源码包的编译是多层次 Makefie 递归调用过程。

trace-cmd 依赖于 libtracefslibtraceevent,而 libtracefs 的编译依赖于 libtraceevent,所以需要它们的编译顺序如下:

1. libtraceevent
2. libtracefs
3. trace-cmd
  • 编译、安装 libtraceevent
$ cd libtraceevent
$ make CROSS_COMPILE=aarch64-none-linux-gnu-
$ make CROSS_COMPILE=aarch64-none-linux-gnu- DESTDIR=$HOME/trace_cmd_tool/_install install
$ cd -

最后,手工编辑文件 $HOME/trace_cmd_tool/_install/usr/local/lib/x86_64-linux-gnu/pkgconfig/libtraceevent.pc,将内容 prefix=/usr/local 修改为 $HOME/trace_cmd_tool/_install/usr/local

  • 交叉编译、安装 libtracefs
$ cd libtracefs
$ PKG_CONFIG_PATH=$HOME/trace_cmd_tool/_install/usr/local/lib/x86_64-linux-gnu/pkgconfig CC=aarch64-none-linux-gnu-gcc make CROSS_COMPILE=aarch64-none-linux-gnu-
$ PKG_CONFIG_PATH=$HOME/trace_cmd_tool/_install/usr/local/lib/x86_64-linux-gnu/pkgconfig make DESTDIR=$HOME/trace_cmd_tool/_install install
$ cd -

最后,手工编辑文件 $HOME/trace_cmd_tool/_install/usr/local/lib/x86_64-linux-gnu/pkgconfig/libtracefs.pc,将内容 prefix=/usr/local 修改为 $HOME/trace_cmd_tool/_install/usr/local

  • 交叉编译、安装 trace-cmd
$ cd trace-cmd
$ PKG_CONFIG_PATH=$HOME/trace_cmd_tool/_install/usr/local/lib/x86_64-linux-gnu/pkgconfig CC=aarch64-none-linux-gnu-gcc CROSS_COMPILE=aarch64-none-linux-gnu- make
$ PKG_CONFIG_PATH=$HOME/trace_cmd_tool/_install/usr/local/lib/x86_64-linux-gnu/pkgconfig prefix=$HOME/trace_cmd_tool/_install/usr/local etcdir=$HOME/trace_cmd_tool/_install/etc CC=arm-linux-gnueabihf-gcc CROSS_COMPILE=arm-linux-gnueabihf- make install

注意,如果发现文件的安装路径不对,可以手工修改 libtraceevent/Makefilelibtracefs/MakefileLP64 定义,如果是 ARM32 平台,将 LP64 定义为 0,而 ARM64 平台,将 LP64 定义为 1,如下:

# for ARM32
#P64 := 0
# for ARM64
P64 := 1
#LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1)

3.3 安装、运行

2.2 小节将编译生成的 trace-cmd 程序和其依赖的库文件,放到了 $HOME/trace_cmd_tool/_install/usr/local 目录下,其结构层次如下:

$ cd $HOME/trace_cmd_tool/_install/usr/local
$ tree
.
├── bin
│   └── trace-cmd
├── include
│   ├── traceevent
│   │   ├── event-parse.h
│   │   ├── event-utils.h
│   │   ├── kbuffer.h
│   │   └── trace-seq.h
│   └── tracefs
│       └── tracefs.h
└── lib
    ├── libtraceevent.a
    ├── libtraceevent.so -> libtraceevent.so.1
    ├── libtraceevent.so.1 -> libtraceevent.so.1.8.3
    ├── libtraceevent.so.1.8.3
    ├── libtracefs.a
    ├── libtracefs.so -> libtracefs.so.1
    ├── libtracefs.so.1 -> libtracefs.so.1.8.1
    ├── libtracefs.so.1.8.1
    ├── traceevent
    │   └── plugins
    │       ├── plugin_cfg80211.so
    │       ├── plugin_function.so
    │       ├── plugin_futex.so
    │       ├── plugin_hrtimer.so
    │       ├── plugin_jbd2.so
    │       ├── plugin_kmem.so
    │       ├── plugin_kvm.so
    │       ├── plugin_mac80211.so
    │       ├── plugin_sched_switch.so
    │       ├── plugin_scsi.so
    │       ├── plugin_tlb.so
    │       └── plugin_xen.so
    └── x86_64-linux-gnu
        └── pkgconfig
            ├── libtraceevent.pc
            └── libtracefs.pc

将目录 $HOME/trace_cmd_tool/_install/usr/local 下的所有文件(include 目录可以不用拷贝),拷贝到目标平台的对应目录下,即完成 trace-cmd 的安装。

运行来看一下:

# trace-cmd -h

trace-cmd version 3.3.0 (715e628ad9e3e820895115c0d3eb47a75a23c11d)

usage:
  trace-cmd [COMMAND] ...

  commands:
     record - record a trace into a trace.dat file
     set - set a ftrace configuration parameter
     start - start tracing without recording into a file
     extract - extract a trace from the kernel
     stop - stop the kernel from recording trace data
     restart - restart the kernel trace data recording
     show - show the contents of the kernel tracing buffer
     reset - disable all kernel tracing and clear the trace buffers
     clear - clear the trace buffers
     report - read out the trace stored in a trace.dat file
     stream - Start tracing and read the output directly
     profile - Start profiling and read the output directly
     hist - show a histogram of the trace.dat information
     stat - show the status of the running tracing (ftrace) system
     split - parse a trace.dat file into smaller file(s)
     options - list the plugin options available for trace-cmd report
     listen - listen on a network socket for trace clients
     agent - listen on a vsocket for trace clients
     setup-guest - create FIFOs for tracing guest VMs
     list - list the available events, plugins or options
     restore - restore a crashed record
     snapshot - take snapshot of running trace
     stack - output, enable or disable kernel stack tracing
     check-events - parse trace event formats
     dump - read out the meta data from a trace file
     attach - Attach a host and guest trace.dat file
     convert - convert trace file to different version
     sqlhist - Run a SQL like query to create histogram or synthetic events (see man tracefs_sql(3))

3.3.1 trace-cmd 示范:抓取系统调度信息

通过命令 trace-cmd record -e 'sched_wakeup*' -e sched_switch -e 'sched_migrate*' 抓取系统调度信息数据,记录到 trace.dat,按 Ctrl + C 停止抓取。

# trace-cmd record -e 'sched_wakeup*' -e sched_switch -e 'sched_migrate*'
Hit Ctrl^C to stop recording
^Clibtracecmd: Interrupted system call
  No compression algorithms are supported
CPU0 data recorded at offset=0xd5000
    20480 bytes in size
CPU1 data recorded at offset=0xda000
    8192 bytes in size
CPU2 data recorded at offset=0xdc000
    20480 bytes in size
CPU3 data recorded at offset=0xe1000
    4096 bytes in size

4. kernelshark

kernelshark 作为调用 trace-cmd 和可视化 trace-cmd 抓取数据 trace.dat 的工具。

  • 安装

嵌入式 ARM 嵌入式平台trace-cmd 抓取数据 trace.dat 后,我们不必在嵌入式 ARM 平台安装 kernelshark,因为嵌入式 ARM 平台的资源通常不足以运行 kernelshark,可以转而在 PC 机上安装 kernelshark,然后解析 trace-cmd 抓取的 ARM 嵌入式平台数据 trace.datUbuntu 下可以使用如下命令安装 kernelshark

$ sudo apt-get install kernelshark

注:如果安装的 kernelshark 存在问题,可以通过 git clone git://git.kernel.org/pub/scm/utils/trace-cmd/kernel-shark.git 下载源码进行编译。

  • 使用

通过命令 kernelshark trace.dat 得到可视化视图:

$ kernelshark trace.dat
version = 6

在这里插入图片描述

图片从左往右是一个时间轴(Time Line),可通过按住鼠标左右拖动来缩小、放大CPU x 的表示每个 CPU 上发生的调度事件,也可以看成是每个进程占用 CPU 的情况。还可以通过 Column 下拉列表来选择 Task 选择关心进程在不同 CPU 上的执行耗时情况。

笔者手头没有现成的 ARM 嵌入式平台抓取数据,使用的 Ubuntu PC 的抓取数据来进行演示。

5. 参考资料

[1] 交叉编译trace-cmd
[2] Using KernelShark to analyze the real-time scheduler

  • 11
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值