文章目录
- 1. 前言
- 2. 概述
- 3. trace-cmd
- 3.1 下载
- 3.2 交叉编译
- 3.3 安装、运行
- 3.3.1 trace-cmd 示范:抓取系统调度信息
- 4. kernelshark
- 5. 参考资料
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 下载
我们把 libtraceevent
、libtracefs
、trace-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
依赖于 libtracefs
和 libtraceevent
,而 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/Makefile
和 libtracefs/Makefile
的 LP64
定义,如果是 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.dat
。Ubuntu
下可以使用如下命令安装 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