“Linux tracing, monitoring and debugging”的版本间的差异
(创建页面,内容为“== Article purpose == This article provides useful information to start using Linux<sup>®</sup> tracing, monitoring and debugging environments. Two entry points…”) |
|
(未显示同一用户的1个中间版本) | |
(没有差异)
|
2020年11月4日 (三) 18:04的最新版本
目录
- 1 Article purpose
- 2 Linux trace architecture overview
- 3 Linux tracing, monitoring and debugging tools
- 4 块跟踪器
- 5 简介
- 6 安装此工具到开发板上
- 7 开始使用
- 8 进阶操作
- 9 参考资源
- 10 Ftrace
- 11 简介
- 12 安装此工具到开发板上
- 13 开始使用
- 14 进阶操作
- 15 参考
- 16 简介
- 17 开始使用
- 18 进阶使用
- 19 参考
- 20 简介
- 21 Ltrace
- 22 简介
- 23 如何安装
- 24 开始使用
- 25 进阶使用
- 26 参考
- 27 Strace
- 28 Sysprof
- 29 Sysstat工具套件
Article purpose
This article provides useful information to start using Linux® tracing, monitoring and debugging environments.
Two entry points are proposed in this article:
- Linux tracing, monitoring and debugging tools, which gives an overview of some Linux® tools including usage and application domain. This chapter is useful when you already know the domain or the interface to search for.
- Trace and debug overview per Linux software frameworks, which points to articles explaining how to get trace and debug information about the Linux® software frameworks that are relevant for the STM32MPU Embedded Software. This chapter is useful when you know the Linux® framework to search for.
Linux trace architecture overview
The Linux® trace architecture can be organized into four levels as shown in the figure below (inspired by Brendan Gregg presentation[1]):
Back-end instrumentation
The back-end instrumentation provides tracing sources built in the Linux® kernel. They are split into three categories:
- tracepoints: kernel static tracing, statically placed at logical places in the kernel. It provides key event details as a "format" string.
- kprobes: kernel dynamic tracing. It allows to trace function calls, returns and line numbers.
- uprobes: dynamic user-level tracing.
Tracing framework
Also named tracers, they use tracing sources.
Tracing frameworks include kernel in-tree tracers such as ftrace and perf_events, and out-of-tree tracers such as SystemTap and sysdig.
Front-end tools
Front-end tools come on top of tracers and help to configure them. For example:
- trace-cmd or LTTng for ftrace
- perf or perf-Tools for perf_events
Add-on tools and viewer
Add-on tools are also on top of tracers. However, they are not embedded inside the Linux® kernel.
Viewer tools propose Visual interpretation of trace data. For example:
- kernelshark for ftrace/trace-cmd
- Trace Compass[2] for LTTng (and more)
- Flame Graph[3] for perf
Linux tracing, monitoring and debugging tools
Linux® provides many tools that are either dedicated to one function or multifunction (generic).
They cover both Linux® kernel and Linux® user space.
Domain mapping
The following mapping, done by Brendan Gregg [4], shows the different existing tools associated to the different Linux® frameworks.
错误: 图像不正确或者不存在
<securetransclude src="ProtectedTemplate:InternalInfo" params="To check if required to address, vmstat,free, dtrace and ebpf"></securetransclude>
Tool overview
The following table provides a brief description of the tool, as well as its availability depending on the software packages:
: this tool is either present (ready to use or to be activated), or can be integrated and activated on the software package.
: this tool is not present and cannot be integrated, or it is present but cannot be activated on the software package.
块跟踪器
文章目的
本文提供了开始使用Linux工具所需的基本信息:blktrace [1 ](块跟踪器)。
简介
- 下表简要介绍了该工具及其可用性,具体取决于软件包:
- 是:该工具已经存在(可以使用或激活),也可以在软件包中集成和激活。
- 没有:该工具不存在且无法集成,或者存在但无法在软件包中激活。
Tool | STM32MPU Embedded Software distribution | STM32MPU Embedded Software distribution for Android™ | ||||||
---|---|---|---|---|---|---|---|---|
Name | Category | Purpose | Starter Package | Developer Package | Distribution Package | Starter Package | Developer Package | Distribution Package |
工具 | ||
---|---|---|
名称 | 类别 | 目的 |
blktrace | 追踪工具 | blktrace [1 ]生成对块设备(SD卡,USB,eMMC ...) 上的I/O流量的跟踪 |
STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
没有 | 是 | 是 |
适用于 Android 的STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
没有 | 没有 | 是 |
- blktrace工具由三个主要组件组成:
- 一个内核
- 在用户空间上记录来自内核的 I/O 跟踪信息的实用程序
- 实用程序来分析和查看跟踪信息。
- blkparse [2 ]也与blktrace关联。它从blktrace实用程序获取原始输出,并将其转换为格式良好且易于阅读的格式。
在目标板上安装跟踪和调试工具
- 它包括将blktrace二进制文件放在rootfs中,并修改Linux内核配置。
- 为了使用blktrace,Linux内核配置必须使用Linux内核menuconfig工具激活CONFIG_BLK_DEV_ IO _TRACE:
Symbol: BLK_DEV_IO_TRACE
Location:
Kernel Hacking --->
[*] Tracers --->
[*] Support for tracing block I/O actions
使用STM32MPU嵌入式软件发行版
- 默认情况下,所有STM32MPU嵌入式软件包中都提供blktrace二进制文件:
Board $> which blktrace
/usr/bin/blktrace
- 通过openembedded-core软件包将其集成到weston镜像分发中: openembedded-core/meta/recipes-core/packagegroups/packagegroup-core-tools-profile.bb 。
RRECOMMENDS_${PN} = "\
${PERF} \
trace-cmd \
blktrace \
${PROFILE_TOOLS_X} \
${PROFILE_TOOLS_SYSTEMD} \
"
入门包
- 不适用,因为无法更新Linux内核配置。
开发人员软件包
- 要在Linux内核配置中启用CONFIG_BLK_DEV_IO_TRACE,请参考 Menuconfig 或如何配置内核。 本文提供了有关在Developer Package上下文中修改配置和重新编译Linux内核镜像的说明。
分发包
- 要在Linux内核配置中启用CONFIG_BLK_DEV_IO_TRACE,请参考 Menuconfig 或如何配置内核。 本文提供了有关在“分发程序包”上下文中修改配置和重新编译Linux内核镜像的说明。
使用适用于 Android 的STM32MPU嵌入式软件
- 该blktrace二进制是默认不可用的的全部Android STM32MPU嵌入式软件的软件包,所以必须加入。
入门包
- 不适用,因为无法更新Linux内核配置。
开发人员软件包
- 不适用,因为无法更新Linux内核配置。
分发包
- 要在Linux内核配置中启用CONFIG_BLK_DEV_IO_TRACE,请参阅如何为Android定制内核。 本文提供了有关在Android分发包中修改配置并重新编译Linux内核镜像的说明。
- blktrace源代码模块在中可用external/blktrace。
- 编译(确保正确设置了构建环境):
PC $> cd $ANDROID_BUILD_TOP
PC $> mma blktrace
- 检查blktrace二进制文件在系统镜像中是否可用:
PC $> ls out/target/product/<BoardId>/system/bin/blktrace
- 将二进制文件推送到远程目标文件系统:
# Remount first the target file system with write access
PC $> adb root; adb remount
PC $> adb sync
使用入门
- 从blktrace开始,跟踪已安装的块设备上的I/O流量(以块设备为例进行说明,该设备 /dev/mmcblk0p6 安装为 /usr/local):
Board $> mount | grep mmcblk
/dev/mmcblk0p5 on / type ext4 (rw,relatime,data=ordered)
/dev/mmcblk0p4 on /boot type ext4 (rw,relatime,data=ordered)
/dev/mmcblk0p6 on /usr/local type ext4 (rw,relatime,data=ordered)
- 在后台启动blktrace工具:
Board $> blktrace -d /dev/mmcblk0p6 &
- 读取 /usr/local 的内容(它生成对关联块设备的读取访问权限):
Board $> ls -la /usr/local
- 将 blktrace 活动放在前台,然后按组合键 Ctrl + C 停止它:
Board $> fg
blktrace -d /dev/mmcblk0p6
Board $> <Ctrl-C>
^C=== mmcblk0p6 ===
CPU 0: 98 events, 5 KiB data
CPU 1: 79 events, 4 KiB data
Total: 177 events (dropped 0), 9 KiB data
- 注意:以下信息与 Android 发行版相关,因为文件系统为只读,因此必须使用 ADB。
PC $> adb root; adb remount
PC $> adb shell
Board $> ...
- 有关blktrace使用的详细指导,请参考手册页[1 ]或帮助信息:
Board $> blktrace --help
Usage: blktrace
-d <dev> | --dev=<dev>
[ -r <debugfs path> | --relay=<debugfs path> ]
[ -o <file> | --output=<file>]
[ -D <dir> | --output-dir=<dir>
[ -w | --stopwatch=]
[ -a <action field> | --act-mask=<action field>]
[ -A <action mask> | --set-mask=<action mask>]
[ -b <size> | --buffer-size]
[ -n <number> | --num-sub-buffers=<number>]
[ -l | --listen]
[ -h <hostname> | --host=<hostname>]
[ -p <port number> | --port=<port number>]
[ -s | --no-sendfile]
[ -I <devs file> | --input-devs=<devs file>]
[ -v <version> | --version]
[ -V <version> | --version]
-d Use specified device. May also be given last after options
-r Path to mounted debugfs, defaults to /sys/kernel/debug
-o File(s) to send output to
-D Directory to prepend to output file names
-w Stop after defined time, in seconds
-a Only trace specified actions. See documentation
-A Give trace mask as a single value. See documentation
-b Sub buffer size in KiB (default 512)
-n Number of sub buffers (default 4)
-l Run in network listen mode (blktrace server)
-h Run in network client mode, connecting to the given host
-p Network port to use (default 8462)
-s Make the network client NOT use sendfile() to transfer data
-I Add devices found in <devs file>
-v Print program version info
-V Print program version info
- 要开始使用 blktrace,您还可以参考 Yocto Project Wiki 页面上的 blktrace [3],其中提供了更多详细信息以及示例。
深入学习
blkparse的用法
- 除了在控制台上为用户显示信息之外,blktrace还创建跟踪文件(每个CPU一个),可以使用blkparse查看该文件。这些文件存储在当前路径目录下。
Board $> blkparse mmcblk0p6
Input file mmcblk0p6.blktrace.0 added
Input file mmcblk0p6.blktrace.1 added
179,6 0 1 0.000000000 99 P N [jbd2/mmcblk0p5-]
179,6 0 0 0.000337792 0 m N cfq99SN insert_request
179,6 0 0 0.000344292 0 m N cfq99SN add_to_rr
179,6 0 0 0.000366250 0 m N cfq99SN insert_request
179,6 0 0 0.000374792 0 m N cfq99SN insert_request
179,6 0 0 0.000382458 0 m N cfq99SN insert_request
179,6 0 0 0.000390167 0 m N cfq99SN insert_request
179,6 0 2 0.000396625 99 U N [jbd2/mmcblk0p5-] 5
179,6 0 0 0.000452542 0 m N cfq workload slice:150000000
179,6 0 0 0.000460750 0 m N cfq99SN set_active wl_class:0 wl_type:1
179,6 0 0 0.000469083 0 m N cfq99SN dispatch_insert
179,6 0 0 0.000478500 0 m N cfq99SN dispatched a request
179,6 0 0 0.000484583 0 m N cfq99SN activate rq, drv=1
179,6 0 0 0.000747292 0 m N cfq99SN dispatch_insert
179,6 0 0 0.000755042 0 m N cfq99SN dispatched a request
179,6 0 0 0.000759708 0 m N cfq99SN activate rq, drv=2
179,6 0 0 0.004197583 0 m N cfq99SN complete rqnoidle 1
179,6 0 0 0.004206958 0 m N cfq99SN set_slice=120000000
179,6 0 0 0.004231917 0 m N cfq99SN dispatch_insert
179,6 0 0 0.004239208 0 m N cfq99SN dispatched a request
179,6 0 0 0.004243958 0 m N cfq99SN activate rq, drv=2
179,6 0 0 0.006287958 0 m N cfq99SN complete rqnoidle 1
179,6 0 0 0.006305208 0 m N cfq99SN dispatch_insert
179,6 0 0 0.006310542 0 m N cfq99SN dispatched a request
179,6 0 0 0.006315417 0 m N cfq99SN activate rq, drv=2
179,6 0 0 0.008340833 0 m N cfq99SN complete rqnoidle 1
179,6 0 0 0.008359000 0 m N cfq99SN dispatch_insert
179,6 0 0 0.008365083 0 m N cfq99SN dispatched a request
179,6 0 0 0.008370000 0 m N cfq99SN activate rq, drv=2
179,6 0 0 0.011504375 0 m N cfq99SN complete rqnoidle 1
179,6 0 0 0.014671667 0 m N cfq99SN insert_request
179,6 0 0 0.014727458 0 m N cfq99SN complete rqnoidle 1
179,6 0 0 0.014731250 0 m N cfq schedule dispatch
179,6 0 0 0.014808000 0 m N cfq99SN dispatch_insert
179,6 0 0 0.014813875 0 m N cfq99SN dispatched a request
179,6 0 0 0.014819958 0 m N cfq99SN activate rq, drv=1
179,6 0 0 0.017068708 0 m N cfq99SN complete rqnoidle 1
179,6 0 0 0.017078375 0 m N cfq schedule dispatch
179,0 0 3 5.759777419 193 A WS 1706892 + 2 <- (179,6) 32778
179,6 0 4 5.759784878 193 Q WS 1706892 + 2 [jbd2/mmcblk0p6-]
179,6 0 5 5.759849336 193 G WS 1706892 + 2 [jbd2/mmcblk0p6-]
179,6 0 6 5.759854253 193 P N [jbd2/mmcblk0p6-]
179,6 1 1 5.759855044 99 P N [jbd2/mmcblk0p5-]
179,0 0 7 5.759887628 193 A WS 1706894 + 2 <- (179,6) 32780
179,6 0 8 5.759893919 193 Q WS 1706894 + 2 [jbd2/mmcblk0p6-]
179,6 0 9 5.759947753 193 G WS 1706894 + 2 [jbd2/mmcblk0p6-]
179,6 1 0 5.759975503 0 m N cfq99SN insert_request
179,6 1 0 5.759990336 0 m N cfq99SN insert_request
179,6 1 2 5.759999253 99 U N [jbd2/mmcblk0p5-] 2
179,6 0 10 5.760024669 193 I WS 1706892 + 2 [jbd2/mmcblk0p6-]
179,6 0 0 5.760035461 0 m N cfq193SN insert_request
179,6 0 0 5.760041711 0 m N cfq193SN add_to_rr
179,6 0 0 5.760053169 0 m N cfq193SN preempt
179,6 0 0 5.760059253 0 m N cfq99SN slice expired t=1
179,6 0 0 5.760066503 0 m N cfq99SN resid=-5635859836
179,6 0 0 5.760081503 0 m N cfq99SN sl_used=120000000 disp=6 charge=120000000 iops=0 sect=12
179,6 0 11 5.760087294 193 I WS 1706894 + 2 [jbd2/mmcblk0p6-]
179,6 0 0 5.760091586 0 m N cfq193SN insert_request
179,6 0 12 5.760096294 193 U N [jbd2/mmcblk0p6-] 2
179,6 1 0 5.760111211 0 m N cfq workload slice:300000000
179,6 1 0 5.760118086 0 m N cfq193SN set_active wl_class:0 wl_type:1
179,6 1 0 5.760125669 0 m N cfq193SN dispatch_insert
179,6 1 0 5.760133128 0 m N cfq193SN dispatched a request
179,6 1 0 5.760137711 0 m N cfq193SN activate rq, drv=1
179,6 1 3 5.760145253 80 D WS 1706892 + 2 [mmcqd/0]
179,6 1 0 5.760393003 0 m N cfq193SN dispatch_insert
179,6 1 0 5.760399961 0 m N cfq193SN dispatched a request
179,6 1 0 5.760404128 0 m N cfq193SN activate rq, drv=2
179,6 1 4 5.760408211 80 D WS 1706894 + 2 [mmcqd/0]
179,6 1 5 5.764367836 80 C WS 1706892 + 2 [0]
179,6 1 0 5.764403128 0 m N cfq193SN complete rqnoidle 1
179,6 1 0 5.764412461 0 m N cfq193SN set_slice=120000000
179,6 1 0 5.764439169 0 m N cfq193SN slice expired t=0
179,6 1 0 5.764450253 0 m N cfq193SN sl_used=33750 disp=2 charge=33750 iops=0 sect=4
179,6 1 0 5.764456836 0 m N cfq193SN del_from_rr
179,6 1 0 5.764464711 0 m N cfq99SN set_active wl_class:0 wl_type:1
179,6 1 0 5.764470211 0 m N cfq99SN dispatch_insert
179,6 1 0 5.764475669 0 m N cfq99SN dispatched a request
179,6 1 0 5.764479378 0 m N cfq99SN activate rq, drv=2
179,6 1 6 5.767516794 80 C WS 1706894 + 2 [0]
179,6 1 0 5.767546961 0 m N cfq193SN complete rqnoidle 1
179,6 1 0 5.767564836 0 m N cfq99SN dispatch_insert
179,6 1 0 5.767571086 0 m N cfq99SN dispatched a request
179,6 1 0 5.767575628 0 m N cfq99SN activate rq, drv=2
179,0 0 13 5.767654378 193 A FWFS 1706896 + 2 <- (179,6) 32782
179,6 0 14 5.767662669 193 Q WS 1706896 + 2 [jbd2/mmcblk0p6-]
179,6 0 15 5.767726461 193 G WS 1706896 + 2 [jbd2/mmcblk0p6-]
179,6 0 16 5.767734169 193 I WS 1706896 + 2 [jbd2/mmcblk0p6-]
179,6 0 0 5.767744003 0 m N cfq193SN insert_request
179,6 0 0 5.767750253 0 m N cfq193SN add_to_rr
179,6 0 0 5.767760628 0 m N cfq193SN preempt
179,6 0 0 5.767764336 0 m N cfq99SN slice expired t=1
179,6 0 0 5.767770044 0 m N cfq99SN resid=120000000
179,6 0 0 5.767781378 0 m N cfq99SN sl_used=10000000 disp=2 charge=10000000 iops=0 sect=4
179,6 0 0 5.767784378 0 m N cfq99SN del_from_rr
179,6 1 0 5.772038836 0 m N cfq99SN complete rqnoidle 1
179,6 1 0 5.772064253 0 m N cfq193SN set_active wl_class:0 wl_type:1
179,6 1 0 5.772070878 0 m N cfq193SN dispatch_insert
179,6 1 0 5.772077044 0 m N cfq193SN dispatched a request
179,6 1 0 5.772081878 0 m N cfq193SN activate rq, drv=2
179,6 1 7 5.772085086 80 D WS 1706896 + 2 [mmcqd/0]
179,6 1 0 5.774473336 0 m N cfq99SN insert_request
179,6 1 0 5.774481419 0 m N cfq99SN add_to_rr
179,6 1 0 5.774490461 0 m N cfq99SN preempt
179,6 1 0 5.774496211 0 m N cfq193SN slice expired t=1
179,6 1 0 5.774502586 0 m N cfq193SN resid=120000000
179,6 1 0 5.774515044 0 m N cfq193SN sl_used=10000000 disp=1 charge=10000000 iops=0 sect=2
179,6 1 0 5.774519128 0 m N cfq193SN del_from_rr
179,6 1 0 5.774558711 0 m N cfq99SN complete rqnoidle 1
179,6 1 0 5.774577211 0 m N cfq99SN set_active wl_class:0 wl_type:1
179,6 1 0 5.774583919 0 m N cfq99SN dispatch_insert
179,6 1 0 5.774590253 0 m N cfq99SN dispatched a request
179,6 1 0 5.774595086 0 m N cfq99SN activate rq, drv=2
179,6 1 8 5.777926544 80 C WS 1706896 + 2 [0]
179,6 1 0 5.777956461 0 m N cfq193SN complete rqnoidle 1
179,6 1 0 5.782932794 0 m N cfq99SN complete rqnoidle 1
179,6 1 0 5.782943419 0 m N cfq99SN set_slice=120000000
179,6 1 0 5.782949919 0 m N cfq schedule dispatch
CPU0 (mmcblk0p6):
Reads Queued: 0, 0KiB Writes Queued: 3, 3KiB
Read Dispatches: 0, 0KiB Write Dispatches: 0, 0KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 0, 0KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
Read depth: 0 Write depth: 2
IO unplugs: 2 Timer unplugs: 0
CPU1 (mmcblk0p6):
Reads Queued: 0, 0KiB Writes Queued: 0, 0KiB
Read Dispatches: 0, 0KiB Write Dispatches: 3, 3KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 3, 3KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
Read depth: 0 Write depth: 2
IO unplugs: 1 Timer unplugs: 0
Total (mmcblk0p6):
Reads Queued: 0, 0KiB Writes Queued: 3, 3KiB
Read Dispatches: 0, 0KiB Write Dispatches: 3, 3KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 3, 3KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
IO unplugs: 3 Timer unplugs: 0
Throughput (R/W): 0KiB/s / 0KiB/s
Events (mmcblk0p6): 118 entries
Skips: 0 f
orward (0 - 0.0%)
- 注意:以下信息与 Android 发行版相关 blkparse 源代码模块在 external/blktrace 中可用
- 编译(确保正确设置了构建环境):
PC $> cd $ANDROID_BUILD_TOP
PC $> mma blkparse
- 检查blkparse二进制文件在系统镜像中是否可用:
PC $> ls out/target/product/<BoardId>/system/bin/blkparse
- 将二进制文件推送到远程目标文件系统:
# Remount first the target file system with write access
PC $> adb root; adb remount
PC $> adb sync
ftrace用法
- 一旦Linux内核配置 CONFIG_BLK_DEV_ IO _TRACE 是激活的,块层(BLK)动作可以通过使用被追踪 ftrace:
- 在这种情况下,只能为 ftrace 配置 blk 跟踪器,如以下命令的结果所示:
Board $> mount -t tracefs nodev /sys/kernel/tracing
Board $> cat /sys/kernel/tracing/available_tracers
blk nop
- 为了获得更多的 ftrace 跟踪器(例如"function”),必须通过分发程序包激活其他 Linux 内核配置选项,如 ftrace 文章中所述。
通过以 /usr/local 读取内容为例(挂载点为mcblk0p6):
Board $> echo 1 > /sys/block/mmcblk0/mmcblk0p6/trace/enable
Board $> echo blk > /sys/kernel/tracing/current_tracer
Board $> ls -la /usr/local
Board $> cat /sys/kernel/tracing/trace_pipe
jbd2/mmcblk0p5--97 [001] ...1 100.412943: 179,0 A WS 415902 + 2 <- (179,5) 278652
jbd2/mmcblk0p6--196 [000] ...1 100.412943: 179,0 A WS 1706892 + 2 <- (179,6) 32778
jbd2/mmcblk0p5--97 [001] ...1 100.412974: 179,0 Q WS 415902 + 2 [jbd2/mmcblk0p5-]
jbd2/mmcblk0p6--196 [000] ...1 100.412987: 179,0 Q WS 1706892 + 2 [jbd2/mmcblk0p6-]
jbd2/mmcblk0p5--97 [001] ...1 100.413012: 179,0 G WS 415902 + 2 [jbd2/mmcblk0p5-]
jbd2/mmcblk0p6--196 [000] ...1 100.413012: 179,0 G WS 1706892 + 2 [jbd2/mmcblk0p6-]
jbd2/mmcblk0p6--196 [000] ...1 100.413018: 179,0 P N [jbd2/mmcblk0p6-]
jbd2/mmcblk0p5--97 [001] ...1 100.413019: 179,0 P N [jbd2/mmcblk0p5-]
jbd2/mmcblk0p5--97 [001] ...1 100.413034: 179,0 A WS 415904 + 2 <- (179,5) 278654
jbd2/mmcblk0p6--196 [000] ...1 100.413034: 179,0 A WS 1706894 + 2 <- (179,6) 32780
jbd2/mmcblk0p5--97 [001] ...1 100.413040: 179,0 Q WS 415904 + 2 [jbd2/mmcblk0p5-]
jbd2/mmcblk0p6--196 [000] ...1 100.413040: 179,0 Q WS 1706894 + 2 [jbd2/mmcblk0p6-]
jbd2/mmcblk0p5--97 [001] ...1 100.413054: 179,0 G WS 415904 + 2 [jbd2/mmcblk0p5-]
jbd2/mmcblk0p6--196 [000] ...1 100.413056: 179,0 G WS 1706894 + 2 [jbd2/mmcblk0p6-]
jbd2/mmcblk0p6--196 [000] ...2 100.413071: 179,0 I WS 1706892 + 2 [jbd2/mmcblk0p6-]
jbd2/mmcblk0p6--196 [000] ...1 100.413092: 179,0 m N cfq196SN insert_request
jbd2/mmcblk0p6--196 [000] ...2 100.413104: 179,0 I WS 1706894 + 2 [jbd2/mmcblk0p6-]
jbd2/mmcblk0p6--196 [000] ...1 100.413111: 179,0 m N cfq196SN insert_request
jbd2/mmcblk0p6--196 [000] ...2 100.413118: 179,0 U N [jbd2/mmcblk0p6-] 2
jbd2/mmcblk0p5--97 [001] ...2 100.413135: 179,0 I WS 415902 + 2 [jbd2/mmcblk0p5-]
jbd2/mmcblk0p5--97 [001] ...1 100.413144: 179,0 m N cfq97SN insert_request
jbd2/mmcblk0p5--97 [001] ...1 100.413151: 179,0 m N cfq97SN add_to_rr
jbd2/mmcblk0p5--97 [001] ...1 100.413162: 179,0 m N cfq97SN preempt
jbd2/mmcblk0p5--97 [001] ...1 100.413168: 179,0 m N cfq196SN slice expired t=1
jbd2/mmcblk0p5--97 [001] ...1 100.413176: 179,0 m N cfq196SN resid=-32494149849
jbd2/mmcblk0p5--97 [001] ...1 100.413191: 179,0 m N cfq196SN sl_used=120000000 disp=1 charge=120000000 iops=0 sect=2
jbd2/mmcblk0p5--97 [001] ...2 100.413199: 179,0 I WS 415904 + 2 [jbd2/mmcblk0p5-]
jbd2/mmcblk0p5--97 [001] ...1 100.413205: 179,0 m N cfq97SN insert_request
jbd2/mmcblk0p5--97 [001] ...2 100.413211: 179,0 U N [jbd2/mmcblk0p5-] 2
mmcqd/0-80 [000] ...1 100.413224: 179,0 m N cfq workload slice:200000000
mmcqd/0-80 [000] ...1 100.413232: 179,0 m N cfq97SN set_active wl_class:0 wl_type:1
mmcqd/0-80 [000] ...1 100.413241: 179,0 m N cfq97SN dispatch_insert
mmcqd/0-80 [000] ...1 100.413250: 179,0 m N cfq97SN dispatched a request
mmcqd/0-80 [000] ...1 100.413256: 179,0 m N cfq97SN activate rq, drv=1
mmcqd/0-80 [000] ...2 100.413261: 179,0 D WS 415902 + 2 [mmcqd/0]
mmcqd/0-80 [000] ...1 100.413515: 179,0 m N cfq97SN dispatch_insert
mmcqd/0-80 [000] ...1 100.413524: 179,0 m N cfq97SN dispatched a request
mmcqd/0-80 [000] ...1 100.413530: 179,0 m N cfq97SN activate rq, drv=2
mmcqd/0-80 [000] ...2 100.413534: 179,0 D WS 415904 + 2 [mmcqd/0]
mmcqd/0-80 [000] ...1 100.417441: 179,0 C WS 415902 + 2 [0]
mmcqd/0-80 [000] ...1 100.417482: 179,0 m N cfq97SN complete rqnoidle 1
mmcqd/0-80 [000] ...1 100.417494: 179,0 m N cfq97SN set_slice=120000000
mmcqd/0-80 [000] ...1 100.417526: 179,0 m N cfq97SN slice expired t=0
mmcqd/0-80 [000] ...1 100.417539: 179,0 m N cfq97SN sl_used=40584 disp=2 charge=40584 iops=0 sect=4
mmcqd/0-80 [000] ...1 100.417545: 179,0 m N cfq97SN del_from_rr
mmcqd/0-80 [000] ...1 100.417555: 179,0 m N cfq196SN set_active wl_class:0 wl_type:1
mmcqd/0-80 [000] ...1 100.417561: 179,0 m N cfq196SN dispatch_insert
mmcqd/0-80 [000] ...1 100.417569: 179,0 m N cfq196SN dispatched a request
mmcqd/0-80 [000] ...1 100.417575: 179,0 m N cfq196SN activate rq, drv=2
mmcqd/0-80 [000] ...2 100.417579: 179,0 D WS 1706892 + 2 [mmcqd/0]
mmcqd/0-80 [000] ...1 100.419353: 179,0 C WS 415904 + 2 [0]
mmcqd/0-80 [000] ...1 100.419380: 179,0 m N cfq97SN complete rqnoidle 1
mmcqd/0-80 [000] ...1 100.419393: 179,0 m N cfq196SN dispatch_insert
mmcqd/0-80 [000] ...1 100.419400: 179,0 m N cfq196SN dispatched a request
mmcqd/0-80 [000] ...1 100.419405: 179,0 m N cfq196SN activate rq, drv=2
mmcqd/0-80 [000] ...2 100.419409: 179,0 D WS 1706894 + 2 [mmcqd/0]
jbd2/mmcblk0p5--97 [001] ...1 100.419431: 179,0 A FWFS 415906 + 2 <- (179,5) 278656
jbd2/mmcblk0p5--97 [001] ...1 100.419440: 179,0 Q WS 415906 + 2 [jbd2/mmcblk0p5-]
jbd2/mmcblk0p5--97 [001] ...1 100.419465: 179,0 G WS 415906 + 2 [jbd2/mmcblk0p5-]
jbd2/mmcblk0p5--97 [001] ...2 100.419475: 179,0 I WS 415906 + 2 [jbd2/mmcblk0p5-]
jbd2/mmcblk0p5--97 [001] ...1 100.419484: 179,0 m N cfq97SN insert_request
jbd2/mmcblk0p5--97 [001] ...1 100.419491: 179,0 m N cfq97SN add_to_rr
jbd2/mmcblk0p5--97 [001] ...1 100.419502: 179,0 m N cfq97SN preempt
jbd2/mmcblk0p5--97 [001] ...1 100.419507: 179,0 m N cfq196SN slice expired t=1
jbd2/mmcblk0p5--97 [001] ...1 100.419514: 179,0 m N cfq196SN resid=120000000
jbd2/mmcblk0p5--97 [001] ...1 100.419526: 179,0 m N cfq196SN sl_used=10000000 disp=2 charge=10000000 iops=0 sect=4
jbd2/mmcblk0p5--97 [001] ...1 100.419530: 179,0 m N cfq196SN del_from_rr
mmcqd/0-80 [000] ...1 100.424339: 179,0 C WS 1706892 + 2 [0]
mmcqd/0-80 [000] ...1 100.424367: 179,0 m N cfq196SN complete rqnoidle 1
mmcqd/0-80 [000] ...1 100.424388: 179,0 m N cfq97SN set_active wl_class:0 wl_type:1
mmcqd/0-80 [000] ...1 100.424396: 179,0 m N cfq97SN dispatch_insert
mmcqd/0-80 [000] ...1 100.424404: 179,0 m N cfq97SN dispatched a request
mmcqd/0-80 [000] ...1 100.424409: 179,0 m N cfq97SN activate rq, drv=2
mmcqd/0-80 [000] ...2 100.424413: 179,0 D WS 415906 + 2 [mmcqd/0]
mmcqd/0-80 [000] ...1 100.427349: 179,0 C WS 1706894 + 2 [0]
mmcqd/0-80 [000] ...1 100.427382: 179,0 m N cfq196SN complete rqnoidle 1
jbd2/mmcblk0p6--196 [000] ...1 100.427441: 179,0 A FWFS 1706896 + 2 <- (179,6) 32782
jbd2/mmcblk0p6--196 [000] ...1 100.427458: 179,0 Q WS 1706896 + 2 [jbd2/mmcblk0p6-]
jbd2/mmcblk0p6--196 [000] ...1 100.427482: 179,0 G WS 1706896 + 2 [jbd2/mmcblk0p6-]
jbd2/mmcblk0p6--196 [000] ...2 100.427492: 179,0 I WS 1706896 + 2 [jbd2/mmcblk0p6-]
jbd2/mmcblk0p6--196 [000] ...1 100.427499: 179,0 m N cfq196SN insert_request
jbd2/mmcblk0p6--196 [000] ...1 100.427505: 179,0 m N cfq196SN add_to_rr
jbd2/mmcblk0p6--196 [000] ...1 100.427516: 179,0 m N cfq196SN preempt
jbd2/mmcblk0p6--196 [000] ...1 100.427521: 179,0 m N cfq97SN slice expired t=1
jbd2/mmcblk0p6--196 [000] ...1 100.427528: 179,0 m N cfq97SN resid=120000000
jbd2/mmcblk0p6--196 [000] ...1 100.427545: 179,0 m N cfq97SN sl_used=10000000 disp=1 charge=10000000 iops=0 sect=2
jbd2/mmcblk0p6--196 [000] ...1 100.427550: 179,0 m N cfq97SN del_from_rr
mmcqd/0-80 [000] ...1 100.427598: 179,0 m N cfq196SN set_active wl_class:0 wl_type:1
mmcqd/0-80 [000] ...1 100.427605: 179,0 m N cfq196SN dispatch_insert
mmcqd/0-80 [000] ...1 100.427612: 179,0 m N cfq196SN dispatched a request
mmcqd/0-80 [000] ...1 100.427618: 179,0 m N cfq196SN activate rq, drv=2
mmcqd/0-80 [000] ...2 100.427622: 179,0 D WS 1706896 + 2 [mmcqd/0]
mmcqd/0-80 [000] ...1 100.431133: 179,0 C WS 415906 + 2 [0]
mmcqd/0-80 [000] ...1 100.431164: 179,0 m N cfq97SN complete rqnoidle 1
mmcqd/0-80 [000] ...1 100.434921: 179,0 C WS 1706896 + 2 [0]
mmcqd/0-80 [000] ...1 100.434951: 179,0 m N cfq196SN complete rqnoidle 1
mmcqd/0-80 [000] ...1 100.434962: 179,0 m N cfq196SN set_slice=120000000
mmcqd/0-80 [000] ...1 100.434969: 179,0 m N cfq schedule dispatch
kworker/u4:1-65 [001] ...1 101.612916: 179,0 A WM 137922 + 2 <- (179,5) 672
kworker/u4:1-65 [001] ...1 101.612949: 179,0 Q WM 137922 + 2 [kworker/u4:1]
kworker/u4:1-65 [001] ...1 101.613001: 179,0 G WM 137922 + 2 [kworker/u4:1]
kworker/u4:1-65 [001] ...1 101.613012: 179,0 P N [kworker/u4:1]
kworker/u4:1-65 [001] ...1 101.613071: 179,0 A WM 1674662 + 2 <- (179,6) 548
kworker/u4:1-65 [001] ...1 101.613077: 179,0 Q WM 1674662 + 2 [kworker/u4:1]
kworker/u4:1-65 [001] ...1 101.613093: 179,0 G WM 1674662 + 2 [kworker/u4:1]
kworker/u4:1-65 [001] ...2 101.613119: 179,0 I WM 137922 + 2 [kworker/u4:1]
kworker/u4:1-65 [001] ...1 101.613131: 179,0 m N cfq200A insert_request
kworker/u4:1-65 [001] ...1 101.613139: 179,0 m N cfq200A add_to_rr
kworker/u4:1-65 [001] ...1 101.613152: 179,0 m N cfq200A preempt
kworker/u4:1-65 [001] ...1 101.613157: 179,0 m N cfq196SN slice expired t=1
kworker/u4:1-65 [001] ...1 101.613164: 179,0 m N cfq196SN resid=-1058203000
kworker/u4:1-65 [001] ...1 101.613179: 179,0 m N cfq196SN sl_used=120000000 disp=1 charge=120000000 iops=0 sect=2
kworker/u4:1-65 [001] ...1 101.613185: 179,0 m N cfq196SN del_from_rr
kworker/u4:1-65 [001] ...2 101.613198: 179,0 I WM 1674662 + 2 [kworker/u4:1]
kworker/u4:1-65 [001] ...1 101.613206: 179,0 m N cfq200A insert_request
kworker/u4:1-65 [001] ...2 101.613214: 179,0 U N [kworker/u4:1] 2
mmcqd/0-80 [000] ...1 101.613238: 179,0 m N cfq workload slice:40000000
mmcqd/0-80 [000] ...1 101.613248: 179,0 m N cfq200A set_active wl_class:0 wl_type:0
mmcqd/0-80 [000] ...1 101.613258: 179,0 m N cfq200A dispatch_insert
mmcqd/0-80 [000] ...1 101.613267: 179,0 m N cfq200A dispatched a request
mmcqd/0-80 [000] ...1 101.613274: 179,0 m N cfq200A activate rq, drv=1
mmcqd/0-80 [000] ...2 101.613280: 179,0 D WM 1674662 + 2 [mmcqd/0]
mmcqd/0-80 [000] ...1 101.613511: 179,0 m N cfq200A dispatch_insert
mmcqd/0-80 [000] ...1 101.613520: 179,0 m N cfq200A dispatched a request
mmcqd/0-80 [000] ...1 101.613525: 179,0 m N cfq200A activate rq, drv=2
mmcqd/0-80 [000] ...2 101.613529: 179,0 D WM 137922 + 2 [mmcqd/0]
mmcqd/0-80 [000] ...1 101.618520: 179,0 C WM 1674662 + 2 [0]
mmcqd/0-80 [000] ...1 101.618576: 179,0 m N cfq200A complete rqnoidle 0
mmcqd/0-80 [000] ...1 101.618586: 179,0 m N cfq200A set_slice=40000000
mmcqd/0-80 [000] ...1 101.623185: 179,0 C WM 137922 + 2 [0]
mmcqd/0-80 [000] ...1 101.623215: 179,0 m N cfq200A complete rqnoidle 0
mmcqd/0-80 [000] ...1 101.623221: 179,0 m N cfq schedule dispatch
- 注意:以下信息与 Android 发行版相关,因为文件系统为只读,因此必须使用ADB。
PC $> adb root; adb remount
PC $> adb shell
Board $> ...
参考
- 1. https://linux.die.net/man/8/blktrace
- 2. https://linux.die.net/man/1/blkparse
- 3. https://wiki.yoctoproject.org/wiki/Tracing_and_Profiling#blktrace
- 有用的外部链接
文件链接 | 文件类型 | 描述 |
---|---|---|
blktrace 工具源代码,包括用户空间工具 | 资料来源 | blktrace来源git |
blktrace 演示 | 介绍 | Alan D. Brunelle的演讲 |
systemd core dump
Debugging tools
systemd core dump: generates core dump files on Linux
本文提供了开始使用Linux®命令工具ethtool所需的基本信息。
简介
ethtool允许查询或控制网络驱动程序和硬件设置,尤其是对于有线以太网设备。
安装此工具到开发板上
手动编译安装
使用buildroot
- ethtool已默认安装到开发板文件系统里。
Board $> which ethtool /usr/sbin/ethtool
使用yocto
- 需将此菜谱文件包含进需要构建的系统镜像内
RDEPENDS_packagegroup-framework-tools-network-base = "\ ethtool \ iproute2 \ "
开始使用
可以使用Linux IP命令行列出开发板上可用的以太网链接。
Board $> ip link | grep eth 3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 00:80:e1:42:43:65 brd ff:ff:ff:ff:ff:ff
- 获取有关eth0网络设备的信息:
Board $> ethtool eth0
Settings for eth0:
Supported ports: [ TP AUI BNC MII FIBRE ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Link partner advertised pause frame use: Symmetric
Link partner advertised auto-negotiation: Yes
Speed: 1000Mb/s
Duplex: Full
Port: MII
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: ug
Wake-on: d
Current message level: 0x0000003f (63)
drv probe link timer ifdown ifup
Link detected: yes
- 显示eth0设备以太网驱动程序设置
Board $> ethtool -i eth0
driver: st_gmac
version: Jan_2016
firmware-version:
expansion-rom-version:
bus-info:
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: yes
supports-priv-flags: no
- 显示eth0的网络统计信息
Board $> ethtool -S eth0
NIC statistics:
mmc_tx_octetcount_gb: 0
mmc_tx_framecount_gb: 0
mmc_tx_broadcastframe_g: 0
mmc_tx_multicastframe_g: 0
mmc_tx_64_octets_gb: 0
mmc_tx_65_to_127_octets_gb: 0
mmc_tx_128_to_255_octets_gb: 0
mmc_tx_256_to_511_octets_gb: 0
mmc_tx_512_to_1023_octets_gb: 0
mmc_tx_1024_to_max_octets_gb: 0
mmc_tx_unicast_gb: 0
mmc_tx_multicast_gb: 0
mmc_tx_broadcast_gb: 0
mmc_tx_underflow_error: 0
mmc_tx_singlecol_g: 0
mmc_tx_multicol_g: 0
mmc_tx_deferred: 0
mmc_tx_latecol: 0
mmc_tx_exesscol: 0
mmc_tx_carrier_error: 0
mmc_tx_octetcount_g: 0
mmc_tx_framecount_g: 1809
mmc_tx_excessdef: 0
mmc_tx_pause_frame: 0
mmc_tx_vlan_frame_g: 0
mmc_rx_framecount_gb: 0
mmc_rx_octetcount_gb: 0
mmc_rx_octetcount_g: 0
mmc_rx_broadcastframe_g: 0
mmc_rx_multicastframe_g: 0
mmc_rx_crc_error: 0
mmc_rx_align_error: 0
mmc_rx_run_error: 0
mmc_rx_jabber_error: 0
mmc_rx_undersize_g: 0
mmc_rx_oversize_g: 0
mmc_rx_64_octets_gb: 0
mmc_rx_65_to_127_octets_gb: 0
mmc_rx_128_to_255_octets_gb: 0
mmc_rx_256_to_511_octets_gb: 0
mmc_rx_512_to_1023_octets_gb: 0
mmc_rx_1024_to_max_octets_gb: 0
mmc_rx_unicast_g: 1514
mmc_rx_length_error: 0
mmc_rx_autofrangetype: 0
mmc_rx_pause_frames: 0
mmc_rx_fifo_overflow: 0
mmc_rx_vlan_frames_gb: 0
mmc_rx_watchdog_error: 0
mmc_rx_ipc_intr_mask: 0
mmc_rx_ipc_intr: 0
mmc_rx_ipv4_gd: 0
mmc_rx_ipv4_hderr: 0
mmc_rx_ipv4_nopay: 0
mmc_rx_ipv4_frag: 0
mmc_rx_ipv4_udsbl: 0
mmc_rx_ipv4_gd_octets: 0
mmc_rx_ipv4_hderr_octets: 0
mmc_rx_ipv4_nopay_octets: 0
mmc_rx_ipv4_frag_octets: 0
mmc_rx_ipv4_udsbl_octets: 0
mmc_rx_ipv6_gd_octets: 0
mmc_rx_ipv6_hderr_octets: 0
mmc_rx_ipv6_nopay_octets: 0
mmc_rx_ipv6_gd: 0
mmc_rx_ipv6_hderr: 0
mmc_rx_ipv6_nopay: 0
mmc_rx_udp_gd: 0
mmc_rx_udp_err: 0
mmc_rx_tcp_gd: 0
mmc_rx_tcp_err: 0
mmc_rx_icmp_gd: 0
mmc_rx_icmp_err: 0
mmc_rx_udp_gd_octets: 0
mmc_rx_udp_err_octets: 0
mmc_rx_tcp_gd_octets: 0
mmc_rx_tcp_err_octets: 0
mmc_rx_icmp_gd_octets: 0
mmc_rx_icmp_err_octets: 0
tx_underflow: 0
tx_carrier: 0
tx_losscarrier: 0
vlan_tag: 0
tx_deferred: 0
tx_vlan: 0
tx_jabber: 0
tx_frame_flushed: 0
tx_payload_error: 0
tx_ip_header_error: 0
rx_desc: 0
sa_filter_fail: 0
overflow_error: 0
ipc_csum_error: 0
rx_collision: 0
rx_crc_errors: 0
dribbling_bit: 0
rx_length: 0
rx_mii: 0
rx_multicast: 0
rx_gmac_overflow: 0
rx_watchdog: 0
da_rx_filter_fail: 0
sa_rx_filter_fail: 0
rx_missed_cntr: 0
rx_overflow_cntr: 0
rx_vlan: 0
tx_undeflow_irq: 0
tx_process_stopped_irq: 0
tx_jabber_irq: 0
rx_overflow_irq: 0
rx_buf_unav_irq: 0
rx_process_stopped_irq: 0
rx_watchdog_irq: 0
tx_early_irq: 0
fatal_bus_error_irq: 0
rx_early_irq: 0
threshold: 1
tx_pkt_n: 1809
rx_pkt_n: 12682
normal_irq_n: 11110
rx_normal_irq_n: 11082
napi_poll: 11118
tx_normal_irq_n: 28
tx_clean: 11641
tx_set_ic_bit: 28
irq_receive_pmt_irq_n: 0
mmc_tx_irq_n: 0
mmc_rx_irq_n: 0
mmc_rx_csum_offload_irq_n: 0
irq_tx_path_in_lpi_mode_n: 0
irq_tx_path_exit_lpi_mode_n: 0
irq_rx_path_in_lpi_mode_n: 0
irq_rx_path_exit_lpi_mode_n: 0
phy_eee_wakeup_error_n: 0
ip_hdr_err: 0
ip_payload_err: 0
ip_csum_bypassed: 544
ipv4_pkt_rcvd: 9189
ipv6_pkt_rcvd: 1948
no_ptp_rx_msg_type_ext: 12682
ptp_rx_msg_type_sync: 0
ptp_rx_msg_type_follow_up: 0
ptp_rx_msg_type_delay_req: 0
ptp_rx_msg_type_delay_resp: 0
ptp_rx_msg_type_pdelay_req: 0
ptp_rx_msg_type_pdelay_resp: 0
ptp_rx_msg_type_pdelay_follow_up: 0
ptp_rx_msg_type_announce: 0
ptp_rx_msg_type_management: 0
ptp_rx_msg_pkt_reserved_type: 0
ptp_frame_type: 0
ptp_ver: 0
timestamp_dropped: 0
av_pkt_rcvd: 0
av_tagged_pkt_rcvd: 0
vlan_tag_priority_val: 0
l3_filter_match: 0
l4_filter_match: 0
l3_l4_filter_no_match: 0
irq_pcs_ane_n: 0
irq_pcs_link_n: 0
irq_rgmii_n: 1
mtl_tx_status_fifo_full: 0
mtl_tx_fifo_not_empty: 0
mmtl_fifo_ctrl: 0
mtl_tx_fifo_read_ctrl_write: 0
mtl_tx_fifo_read_ctrl_wait: 0
mtl_tx_fifo_read_ctrl_read: 0
mtl_tx_fifo_read_ctrl_idle: 0
mac_tx_in_pause: 0
mac_tx_frame_ctrl_xfer: 0
mac_tx_frame_ctrl_idle: 0
mac_tx_frame_ctrl_wait: 0
mac_tx_frame_ctrl_pause: 0
mac_gmii_tx_proto_engine: 0
mtl_rx_fifo_fill_level_full: 0
mtl_rx_fifo_fill_above_thresh: 0
mtl_rx_fifo_fill_below_thresh: 0
mtl_rx_fifo_fill_level_empty: 0
mtl_rx_fifo_read_ctrl_flush: 0
mtl_rx_fifo_read_ctrl_read_data: 0
mtl_rx_fifo_read_ctrl_status: 0
mtl_rx_fifo_read_ctrl_idle: 0
mtl_rx_fifo_ctrl_active: 0
mac_rx_frame_ctrl_fifo: 0
mac_gmii_rx_proto_engine: 0
tx_tso_frames: 0
tx_tso_nfrags: 0
进阶操作
互联网上有许多有关ethtool的文档。
有关命令选项的更多详细信息,请参见ethtool手册页。
参考资源
- ethtool使用手册 https://linux.die.net/man/8/ethtool
链接地址 | 文件类型 | 描述 |
---|---|---|
https://en.wikipedia.org/wiki/Ethtool | 标准 | 维基百科文章 |
http://www.thegeekstuff.com/2010/10/ethtool-command | 用户指南 | thegeekstuff网站 |
Ftrace
文章目的
- 本文提供了开始使用Linux内核工具所需的基本信息:ftrace [1 ]。
简介
- 下表简要介绍了该工具及其可用性,具体取决于软件包:
- 是:该工具已经存在(可以使用或激活),也可以在软件包中集成和激活。
- 没有:该工具不存在且无法集成,或者存在但无法在软件包中激活。
工具 | ||
---|---|---|
名称 | 类别 | 目的 |
ftrace | 追踪工具 | ftrace [1 ](函数跟踪程序)是功能强大的内核跟踪实用程序,例如,它可以跟踪每个内核函数调用和内核事件,而无需在内核源代码中添加任何额外的代码 没有 没有 是 没有 没有 是 |
STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
没有 | 没有 | 是 |
适用于 Android 的STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
没有 | 没有 | 是 |
- 注意:在Linux内核4.1之前,所有ftrace跟踪控制文件都在debugfs文件系统中,该文件系统通常位于 /sys/kernel/debug/tracing 中。现在,它位于/ sys/kernel/tracing中,并且独立于debugfs。
- 为了向后兼容,在安装 debugfs 文件系统时,tracefs 文件系统会自动安装在: /sys/kernel/debug/tracing.。
- 位于tracefs文件系统中的所有文件也位于该debugfs文件系统目录中。
- 请注意,符号表中存在的所有函数都可用于ftrace。要知道符号列表中是否有可用的函数,可以使用命令 "nm vmlinux
在目标板上安装跟踪和调试工具
- ftrace是一项内核功能,在OpenSTLinux发行版中默认情况下未启用,因为这会影响Linux内核大小(vmlinux大约增加1.5%),并且还会对整体性能产生影响,因为其触发了跟踪内核事件和函数调用。
- 为了使用ftrace所需的“内核功能跟踪程序” ,Linux内核配置必须使用Linux内核menuconfig工具激活 CONFIG_FUNCTION_TRACER 和 CONFIG_FUNCTION_GRAPH_TRACER 配置:
Symbol: FUNCTION_TRACER
Location:
Kernel Hacking --->
Tracers -->
[*] Kernel Function Tracer
Symbol: FUNCTION_GRAPH_TRACER
Location:
Kernel Hacking --->
Tracers -->
[*] Kernel Function Tracer
[*] Kernel Function Graph Tracer
使用STM32MPU嵌入式软件发行版
开发人员软件包
- 不建议使用Developer Package启用ftrace内核配置,因为所有外部模块需要重新编译(例如GPU STM32MP1的gcnano驱动程序),而Developer Package则无法实现,因为它不需要提供所有资料来源。
- 这就是为什么将此设置为“开发人员包”不支持的原因。
分发包
- 启用所需的Linux内核配置
- 要在Linux内核配置中启用CONFIG_FUNCTION_TRACER和CONFIG_FUNCTION_GRAPH_TRACER,请参阅 Menuconfig或如何配置内核 一文,以获取有关在Distribution Package上下文中修改配置和重新编译Linux内核镜像的说明。
- 还必须重新编译不属于Linux内核源代码树的外部Linux内核模块(如果存在)。
- GPU STM32MP1的gcnano驱动程序示例:
PC $> bitbake gcnano-driver-stm32mp
- 重新构建完整的OpenSTLinux镜像,以便重新编译所有依赖项并具有正确的rootfs(包括外部Linux内核模块)
PC $> bitbake st-image-weston
- 注意:如前所述,启用ftrace配置时,未压缩的Linux内核镜像的大小会增加。
- 根据目标板的内存配置(在设备树中定义),内核镜像的增加可能与放置在其后的某些保留区域重叠。
- 在这种情况下,突出显示了编译错误。
- 如果此重叠影响很小(意味着某些功能不再起作用,但并不关键),则可以通过使用Linux内核Menuconfig工具(Menuconfig或如何配置内核)激活Linux内核配置CONFIG_SECTION_MISMATCH_WARN_ONLY来避免编译错误。)
Symbol: SECTION_MISMATCH_WARN_ONLY
Location:
Kernel Hacking --->
Compile-time checks and compiler options -->
[*] Make section mismatch errors non-fatal
使用适用于 Android 的 STM32MPU 嵌入式软件发行版
分发包
- 启用所需的Linux内核配置
- 要在Linux内核配置中启用CONFIG_FUNCTION_TRACER和CONFIG_FUNCTION_GRAPH_TRACER,请参阅如何为Android定制内核 一文,以获取有关修改配置的说明
- 在Android分发包中重新编译Linux内核镜像和模块。
PC $> build_kernel vmlinux -i
PC $> build_kernel modules -i
- 还必须重新编译不属于Linux内核源代码树的外部Linux内核模块(如果存在的话)。
GPU STM32MP1的gcnano驱动程序示例:
PC $> build_kernel gpu -i
- 重建完整的Android镜像,以便重新编译所有依赖关系并考虑Linux内核镜像和模块的新的预构建镜像:
PC $> make -j
- 注意:如前所述,启用ftrace配置时,未压缩的Linux内核镜像的大小会增加。
- 根据目标板的内存配置(在设备树中定义),内核镜像的增加可能会覆盖后面放置的一些保留区域。
- 在这种情况下,突出显示了编译错误。
- 如果此重叠影响很小(意味着某些功能不再起作用,但并不关键),则可以通过使用Linux内核Menuconfig工具激活Linux内核配置CONFIG_SECTION_MISMATCH_WARN_ONLY来绕过编译错误(如何为Android定制内核))
Symbol: SECTION_MISMATCH_WARN_ONLY
Location:
Kernel Hacking --->
Compile-time checks and compiler options -->
[*] Make section mismatch errors non-fatal
使用入门
在运行时使用ftrace
- 首先,你需要从目标启用/激活 ftrace 功能。
- 目标启动并登录后,安装 tracefs:
Board $> mount -t tracefs nodev /sys/kernel/tracing
- 注意:以下信息与 Android 发行版有关
- 需要启用root访问权限
- 使用ADB Shell可以使用ADB链接:
PC $> adb root
PC $> adb shell
Board $> ...
- 使用UART控制台shell:
Board $> su
Board $> ...
- 在那一步,所有的"ftrace”功能都发生在文件系统目录路径 /sys/kernel/tracing 中。
- 要找出可用的跟踪器,只需在跟踪目录中放置 available_tracers 文件即可:
Board $> cat /sys/kernel/tracing/available_tracers
function_graph function nop
- 内核构建配置可以添加更多的跟踪器。请参阅 深入学习 一节。
过滤器选项
- 注意:ftrace使用函数/ graph_function过滤器,而不是驱动程序过滤器。因此,跟踪* myDriver *函数不会从myDriver跟踪myHelper函数。
- 你可以使用以下命令获取可用的过滤器功能的列表:
Board $> cat /sys/kernel/tracing/available_filter_functions
功能跟踪器模式
- 开始跟踪会话
Board $> echo 1 > /sys/kernel/tracing/tracing_on
- 要启用函数跟踪器,只需将函数写入 current_tracer 文件。然后,你可以验证当前值:
Board $> echo function > /sys/kernel/tracing/current_tracer
Board $> cat /sys/kernel/tracing/current_tracer
function
Board $> cat /sys/kernel/tracing/trace | head -20
# tracer: function
#
# entries-in-buffer/entries-written: 144045/33695515 #P:2
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
date-3591 [001] ...3 3278.796042: memblock_is_map_memory <-pfn_valid
date-3591 [001] ...3 3278.796046: unlock_page <-filemap_map_pages
date-3591 [001] ...3 3278.796051: alloc_set_pte <-filemap_map_pages
date-3591 [001] ...3 3278.796053: add_mm_counter_fast <-alloc_set_pte
date-3591 [001] ...3 3278.796055: page_add_file_rmap <-alloc_set_pte
date-3591 [001] ...3 3278.796057: __sync_icache_dcache <-alloc_set_pte
date-3591 [001] ...3 3278.796059: pfn_valid <-__sync_icache_dcache
date-3591 [001] ...3 3278.796061: memblock_is_map_memory <-pfn_valid
date-3591 [001] ...3 3278.796064: unlock_page <-filemap_map_pages
- 要应用功能过滤器,你可以在 /sys/kernel/tracing/set_ftrace_filter 中设置值,然后检查跟踪的新内容:
# Here we take the example with all uart functions
Board $> echo "*uart*" > /sys/kernel/tracing/set_ftrace_filter
# Clean the existing trace
Board $> echo > /sys/kernel/tracing/trace
# Display new trace content (in that case, please do some actions in the console to get some traces)
Board $> cat /sys/kernel/tracing/trace | head -20
# tracer: function
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
sh-343 [000] .... 9313.041827: uart_ioctl <-tty_ioctl
sh-343 [000] .... 9313.041855: uart_ioctl <-tty_ioctl
sh-343 [000] .... 9313.041866: uart_chars_in_buffer <-tty_wait_until_sent
sh-343 [000] .... 9313.041870: uart_wait_until_sent <-tty_wait_until_sent
sh-343 [000] .... 9313.041875: uart_set_termios <-tty_set_termios
sh-343 [000] .... 9313.041968: uart_write_room <-tty_write_room
sh-343 [000] .... 9313.041974: uart_write <-n_tty_write
sh-343 [000] d..1 9313.041979: __uart_start <-uart_write
sh-343 [000] d..1 9313.041987: uart_write_wakeup <-stm32_transmit_chars
sh-343 [000] d.h2 9313.042007: uart_write_wakeup <-stm32_transmit_chars
sh-343 [000] d.h2 9313.042022: uart_write_wakeup <-stm32_transmit_chars
- Linux文档ftrace [2 ]中提供了有关过滤选项和配置的更多信息。
- 要清空跟踪,请参阅段落 "擦除跟踪”
- 要清除过滤器,以便再次记录所有功能:
Board $> echo > /sys/kernel/tracing/set_ftrace_filter
图形功能跟踪器模式
- 开始跟踪会话:
Board $> echo 1 > /sys/kernel/tracing/tracing_on
- 要启用功能跟踪器,只需将function_graph写入current_tracer文件。然后,你可以验证当前值:
Board $> echo function_graph > /sys/kernel/tracing/current_tracer
Board $> cat /sys/kernel/tracing/current_tracer
function_graph
Board $> cat /sys/kernel/tracing/trace | head -20
# tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
1) 1.015 us | _spin_lock_irqsave();
1) 0.476 us | internal_add_timer();
1) 0.423 us | wake_up_idle_cpu();
1) 0.461 us | _spin_unlock_irqrestore();
1) 4.770 us | }
1) 5.725 us | }
1) 0.450 us | mutex_unlock();
1) + 24.243 us | }
1) 0.483 us | _spin_lock_irq();
1) 0.517 us | _spin_unlock_irq();
1) | prepare_to_wait() {
1) 0.468 us | _spin_lock_irqsave();
1) 0.502 us | _spin_unlock_irqrestore();
1) 2.411 us | }
1) 0.449 us | kthread_should_stop();
1) | schedule() {
- 要应用图形函数过滤器,可以在 /sys/kernel/tracing/set_graph_function 中设置值,然后检查跟踪的新内容:
# Here we take the example with all uart functions
Board $> echo "*uart*" > /sys/kernel/tracing/set_graph_function
# Clean the existing trace
Board $> echo > /sys/kernel/tracing/trace
# Display the new trace content (in that case, please do some action in the console to get some traces)
Board $> cat /sys/kernel/tracing/trace | head -20
# tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
1) | uart_ioctl() {
1) 0.875 us | mutex_lock();
1) 0.792 us | mutex_unlock();
1) + 15.542 us | }
1) | uart_ioctl() {
1) 0.583 us | mutex_lock();
1) 0.584 us | mutex_unlock();
1) 9.792 us | }
1) | uart_chars_in_buffer() {
1) | _raw_spin_lock_irqsave() {
1) 0.667 us | preempt_count_add();
1) 5.458 us | }
1) | _raw_spin_unlock_irqrestore() {
1) 0.583 us | preempt_count_sub();
1) 5.000 us | }
1) + 19.459 us | }
1) 1.541 us | uart_wait_until_sent();
1) | uart_set_termios() {
1) 0.583 us | mutex_lock();
1) 0.583 us | mutex_unlock();
1) + 10.291 us | }
1) | uart_write_room() {
1) | _raw_spin_lock_irqsave() {
1) 0.666 us | preempt_count_add();
1) 5.333 us | }
1) | _raw_spin_unlock_irqrestore() {
1) 0.583 us | preempt_count_sub();
1) 5.000 us | }
1) + 19.625 us | }
1) | uart_write() {
1) | _raw_spin_lock_irqsave() {
1) 0.625 us | preempt_count_add();
1) 5.209 us | }
1) | __uart_start() {
1) | stm32_start_tx() {
1) | stm32_transmit_chars() {
- 有关ftrace [2 ]的Linux文档,有关过滤选项和配置的更多信息。
- 要清空跟踪,请参阅段落 "擦除跟踪”
- 要清除此特殊过滤器,以便再次记录所有功能:
Board $> echo > /sys/kernel/tracing/set_graph_function
缓冲区大小
- 为每个CPU分配一个缓冲区。为了进行跟踪分析,你可以更改此缓冲区的大小(增加或减少)。
- 可以读取每个CPU的给定大小值,或总计(值以千字节为单位):
# Per CPU
Board $> cat /sys/kernel/tracing/buffer_size_kb
1411
or
Board $> cat /sys/kernel/tracing/per_cpu/cpuX/buffer_size_kb
1411
# Total for all CPUs: combined size of all the trace buffers
Board $> cat /sys/kernel/tracing/buffer_total_size_kb
2822
- 要更改该值(请注意,跟踪缓冲区是在页面中分配的(内核用于分配的你存块,通常大小为4 KB))
# Same value for each CPU (here 1000*4096/1024=4000)
Board $> echo 4000 > /sys/kernel/tracing/buffer_size_kb
or
# Change buffer size value for a specific CPU X (here 1000*4096/1024=4000)
Board $> echo 4000 > /sys/kernel/tracing/per_cpu/cpuX/buffer_size_kb
在启动时使用ftrace
- 你可以从内核启动中使用ftrace,这对于调试启动问题非常有用。
- 为此,你必须使用内核命令行参数:
- - 如果要添加过滤器,则可选 ftrace以及ftrace_filter或ftrace_graph_filter。
使用STM32MPU嵌入式软件包
- 例如,要修改内核bootargs,可以通过以下方式进行:
- 从Linux内核控制台挂载引导分区,然后使用vi编辑器更新extlinux.conf文件(请参见手册页[3 ]或简介页[4 ])。例如:
Board $> mount /dev/mmcblk0p4 /boot
# As example for SDCard boot on STM32MP15 Evaluation board, otherwise /boot/<bootdevice>_<platform>-<boardId>_extlinux/extlinux.conf
Board $> vi /boot/mmc0_stm32mp157c-ev1_extlinux/extlinux.conf
- 通过添加ftrace参数来更新内核命令行:
- - 功能跟踪器模式
- 通过添加ftrace参数来更新内核命令行:
root=/dev/mmcblk0p5 rootwait rw console=ttyS3,115200 ftrace=function ftrace_filter=*uart*
- - function_graph追踪模式
root=/dev/mmcblk0p5 rootwait rw console=ttyS3,115200 ftrace=function_graph ftrace_graph_filter=*uart*
- 保存并退出文件更新,然后重新启动主板
- 或者
- 编辑来自microSD?卡的extlinux.conf文件(如果用作引导设备)
- 注意:需要管理员权限
- -将microSD卡插入主机PC
- -检查是否安装了引导分区(即 /media/$USER/bootfs)
- -编辑与你的设置相对应的extlinux文件(即 /media/$USER/bootfs/mmc0_stm32mp157c-ev1_extlinux/extlinux.conf)
- -按照所需的ftrace跟踪器配置修改命令行(请参见上文)
- -保存修改,然后将microSD卡插入目标
- -引导并检查内核命令行
使用适用于Android的STM32MPU嵌入式软件包
- 例如,要修改内核bootargs,可以通过以下方式来完成,这需要重建启动镜像:
- 编辑文件 device/stm/<STM32Series>/<BoardId>/Boardconfig.mk
- 通过在BOARD_KERNEL_CMDLINE变量中添加ftrace参数来更新内核命令行:
- - 功能跟踪器模式
...
# =========================================================== #
# Kernel command line #
# =========================================================== #
BOARD_KERNEL_CMDLINE := console=ttySTM0,115200 androidboot.console=/dev/ttySTM0 consoleblank=0 earlyprintk
BOARD_KERNEL_CMDLINE += skip_initramfs ro rootfstype=ext4 rootwait
BOARD_KERNEL_CMDLINE += init=/init firmware_class.path=/vendor/firmware
BOARD_KERNEL_CMDLINE += androidboot.hardware=stm
BOARD_KERNEL_CMDLINE += ftrace=function ftrace_filter=*uart*
...
- - function_graph追踪模式
...
# =========================================================== #
# Kernel command line #
# =========================================================== #
BOARD_KERNEL_CMDLINE := console=ttySTM0,115200 androidboot.console=/dev/ttySTM0 consoleblank=0 earlyprintk
BOARD_KERNEL_CMDLINE += skip_initramfs ro rootfstype=ext4 rootwait
BOARD_KERNEL_CMDLINE += init=/init firmware_class.path=/vendor/firmware
BOARD_KERNEL_CMDLINE += androidboot.hardware=stm
BOARD_KERNEL_CMDLINE += ftrace=function_graph ftrace_graph_filter=*uart*
...
- 重建并重新加载启动镜像
检查跟踪
- 引导后,要检查跟踪,必须先挂载tracefs:
Board $> mount -t tracefs nodev /sys/kernel/tracing
- 注意:以下信息与 Android 发行版有关
- 需要启用root访问权限
- 使用ADB Shell可以使用ADB链接:
PC $> adb root
PC $> adb shell
Board $> ...
- 使用UART控制台shell:
Board $> su
Board $> ...
- 然后查看跟踪内容(即函数跟踪):
Board $> cat /sys/kernel/tracing/trace | head -20
# tracer: function
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
systemd-1 [000] .... 1.087213: uart_register_driver <-usart_init
systemd-1 [000] .... 1.087847: uart_get_rs485_mode <-stm32_serial_probe
systemd-1 [000] .... 1.088436: uart_add_one_port <-stm32_serial_probe
systemd-1 [000] .... 1.098000: uart_parse_options <-stm32_console_setup
systemd-1 [000] .... 1.098007: uart_set_options <-stm32_console_setup
systemd-1 [000] .... 1.098014: uart_get_baud_rate <-stm32_set_termios
systemd-1 [000] d..1 1.098019: uart_update_timeout <-stm32_set_termios
systemd-1 [000] d..1 1.098090: uart_console_write <-stm32_console_write
systemd-1 [000] d..1 1.105231: uart_console_write <-stm32_console_write
systemd-1 [000] d..1 1.114697: uart_console_write <-stm32_console_write
systemd-1 [000] d..1 1.120300: uart_console_write <-stm32_console_write
捕获(从启动)oops到串行控制台
- 在启动时启用ftrace的一个有趣的应用程序是通过在内核命令行上放置以下参数来捕获导致不稳定的函数调用:
root=/dev/mmcblk0p5 rootwait rw console=ttyS3,115200 ftrace=function ftrace_dump_on_oops
- 当发生oops时,ftrace缓冲区将自动转储到控制台消息中。
删除痕迹
- 使用以下命令可以擦除ftrace的跟踪内容:
Board $> echo > /sys/kernel/tracing/trace
深入学习
为ftrace添加打印信息
- 除了打印Linux内核功能之外,还可以使用trace_printk函数使用ftrace跟踪特定的调试信息。
- 它可以像printk()一样使用,也可以在任何上下文中使用(中断代码,NMI代码和调度程序代码)。
- trace_printk不会输出到控制台,但会写入ftrace环形缓冲区,并且可以通过跟踪文件读取。
- 要使用trace_printk函数,必须在源代码中包含linux/ftrace.h:
...
#include <linux/ftrace.h>
...
- 然后使用trace_printk语法作为printk(请参见以下示例):
...
trace_printk("%s: %d uart_tx_stopped(port) %i\n", __FUNCTION__, __LINE__, uart_tx_stopped(port));
...
堆栈跟踪
- 从内核文档中提取了ftrace [2 ]。
- 由于内核具有固定大小的堆栈,因此重要的是不要在功能上浪费它。内核开发人员必须知道函数在堆栈上分配了什么。如果它们增加太大的大小,则系统可能处于堆栈溢出的危险中,并且会发生损坏,通常会导致系统死机。
- 有一些工具可以检查此情况,通常使用中断定期检查其使用情况。但是,如果你可以在每个函数调用中执行检查,这将非常有用。由于ftrace提供了一个函数跟踪程序,因此可以方便地在每次函数调用时检查堆栈大小。这是通过堆栈跟踪器启用的。
- Linux内核配置选项CONFIG_STACK_TRACER启用ftrace堆栈跟踪功能。
Symbol: STACK_TRACER
Location:
Kernel Hacking --->
Tracers -->
[*] Trace max stack
- 要启用它,请将 '1' 写入 /proc/sys/kernel/stack_tracer_enabled 中。
Board $> echo 1 > /proc/sys/kernel/stack_tracer_enabled
- 你还可以通过在内核命令行参数中添加"stacktrace”,在内核命令行中启用它以在启动过程中跟踪内核的堆栈大小。
root =/dev/mmcblk0p5 rootwait读写控制台= ttyS3,115200 stacktrace
- 启动后,要检查跟踪,你必须先安装 tracefs,然后显示跟踪内容:
Board $> mount -t tracefs nodev /sys/kernel/tracing
Board $> cat /sys/kernel/tracing/stack_max_size
2928
Board $> cat /sys/kernel/tracing/stack_trace
Depth Size Location (82 entries)
----- ---- --------
0) 4328 4 __rcu_read_unlock+0x14/0x68
1) 4324 180 select_task_rq_fair+0x8ac/0xb7c
2) 4144 64 try_to_wake_up+0x100/0x3fc
3) 4080 16 wake_up_process+0x20/0x24
4) 4064 24 swake_up_locked.part.0+0x20/0x38
5) 4040 24 swake_up+0x38/0x48
6) 4016 16 rcu_gp_kthread_wake+0x4c/0x50
7) 4000 24 rcu_report_qs_rsp+0x50/0x84
8) 3976 120 rcu_report_qs_rnp+0x258/0x2ec
9) 3856 80 rcu_process_callbacks+0x290/0x43c
10) 3776 96 __do_softirq+0x12c/0x3ec
11) 3680 16 irq_exit+0xd0/0x118
12) 3664 48 __handle_domain_irq+0x90/0xfc
13) 3616 40 gic_handle_irq+0x5c/0xa0
14) 3576 68 __irq_svc+0x6c/0xa8
15) 3508 28 unwind_get_byte+0x20/0x74
16) 3480 160 unwind_frame+0x1a8/0x6b0
17) 3320 32 walk_stackframe+0x34/0x40
18) 3288 56 __save_stack_trace+0xa4/0xa8
19) 3232 16 save_stack_trace+0x30/0x34
20) 3216 72 create_object+0x120/0x278
21) 3144 40 kmemleak_alloc+0x8c/0xd4
22) 3104 64 kmem_cache_alloc+0x184/0x2f0
23) 3040 64 __kernfs_new_node+0x58/0x15c
24) 2976 24 kernfs_new_node+0x2c/0x48
25) 2952 24 __kernfs_create_file+0x28/0xb8
26) 2928 56 sysfs_add_file_mode_ns+0xc4/0x1a0
27) 2872 24 sysfs_create_file_ns+0x4c/0x58
28) 2848 56 kobject_add_internal+0x174/0x358
29) 2792 40 kobject_add+0x50/0x98
30) 2752 32 irq_sysfs_add+0x44/0x60
31) 2720 72 __irq_alloc_descs+0x174/0x234
32) 2648 48 irq_domain_alloc_descs+0x64/0xe4
33) 2600 56 irq_create_mapping+0x108/0x1fc
34) 2544 56 irq_create_fwspec_mapping+0x140/0x318
35) 2488 88 irq_create_of_mapping+0x5c/0x64
36) 2400 168 of_irq_get+0x68/0x78
37) 2232 24 stpmu1_regulator_parse_dt+0x68/0x80
38) 2208 96 regulator_register+0x218/0x970
39) 2112 32 devm_regulator_register+0x54/0x84
40) 2080 136 stpmu1_regulator_probe+0x350/0x5f4
41) 1944 32 platform_drv_probe+0x60/0xbc
42) 1912 64 driver_probe_device+0x2f4/0x488
43) 1848 32 __device_attach_driver+0xac/0x14c
44) 1816 40 bus_for_each_drv+0x54/0xa4
45) 1776 40 __device_attach+0xc0/0x150
46) 1736 16 device_initial_probe+0x1c/0x20
47) 1720 32 bus_probe_device+0x94/0x9c
48) 1688 64 device_add+0x3c0/0x5d0
49) 1624 16 of_device_add+0x44/0x4c
50) 1608 40 of_platform_device_create_pdata+0x84/0xb4
51) 1568 104 of_platform_bus_create+0x160/0x2f8
52) 1464 56 of_platform_populate+0x9c/0x134
53) 1408 32 stpmu1_probe+0x6c/0xac
54) 1376 40 i2c_device_probe+0x290/0x2dc
55) 1336 64 driver_probe_device+0x2f4/0x488
56) 1272 32 __device_attach_driver+0xac/0x14c
57) 1240 40 bus_for_each_drv+0x54/0xa4
58) 1200 40 __device_attach+0xc0/0x150
59) 1160 16 device_initial_probe+0x1c/0x20
60) 1144 32 bus_probe_device+0x94/0x9c
61) 1112 64 device_add+0x3c0/0x5d0
62) 1048 24 device_register+0x24/0x28
63) 1024 48 i2c_new_device+0x14c/0x2f4
64) 976 96 of_i2c_register_device+0x134/0x1dc
65) 880 40 of_i2c_register_devices+0x8c/0x100
66) 840 48 i2c_register_adapter+0x184/0x404
67) 792 48 i2c_add_adapter+0xa4/0x138
68) 744 160 stm32f7_i2c_probe+0x954/0xd08
69) 584 32 platform_drv_probe+0x60/0xbc
70) 552 64 driver_probe_device+0x2f4/0x488
71) 488 32 __driver_attach+0x110/0x12c
72) 456 40 bus_for_each_dev+0x5c/0xac
73) 416 16 driver_attach+0x2c/0x30
74) 400 48 bus_add_driver+0x1d0/0x274
75) 352 24 driver_register+0x88/0x104
76) 328 16 __platform_driver_register+0x50/0x58
77) 312 16 stm32f7_i2c_driver_init+0x24/0x28
78) 296 112 do_one_initcall+0x54/0x178
79) 184 72 kernel_init_freeable+0x1dc/0x274
80) 112 24 kernel_init+0x18/0x124
81) 88 88 ret_from_fork+0x14/0x24
更多示踪剂
- 更多跟踪器可用于ftrace。请参阅Linux内核文档中的ftrace [2 ]。
跟踪器名称 | 描述 |
---|---|
blk | 块跟踪器。blktrace用户应用程序 使用的跟踪器 |
hwlat | 硬件延迟跟踪器。它用于检测硬件是否产生任何延迟 |
irqsoff | 跟踪禁用中断的区域,并以最长的最大延迟保存跟踪 |
preemptoff | 与irqsoff类似,但跟踪并记录禁用抢占的时间 |
preemptirqsoff | 与irqsoff和preemptoff类似,但是跟踪并记录禁用irqs和/或抢占的最大时间 |
wakeup | 跟踪并记录唤醒后优先级最高的任务安排所需的最大延迟 |
wakeup_rt | 跟踪并记录仅RT任务所需的最大延迟(就像当前的“唤醒”一样) |
wakeup_dl | 跟踪并记录唤醒SCHED_DEADLINE任务所需的最大延迟(如"wakeup”和"wakeup_rt”一样) |
mmiotrace | 一种特殊的跟踪器,用于跟踪二进制模块。它跟踪模块对硬件的所有调用 |
branch | 在跟踪内核中可能/不太可能发生的调用时可以配置此跟踪器 |
nop | 这是“空的”追踪器 |
辅助工具
- 尽管 debugfs 接口非常简单,但使用起来也很尴尬。建议使用一些工具来简化ftrace的用户体验。
- trace-cmd是一种命令行工具,可以与ftrace配合使用并与之交互,而不是将命令回显到特定文件中并从另一个文件读取结果。它提出了一个高级用户命令界面来简化ftrace的使用。
- 与trace-cmd相关联的kernelshark工具提出了一个跟踪查看器,可用于分析跟踪。
- LTTng是部分基于ftrace的Linux开源跟踪框架,该框架还通过命令行提出了高级用户界面。我们将主机PC端的Trace Compass与日志查看器关联。
参考
- 1. https://elinux.org/Ftrace
- 2. Documentation/trace/ftrace.rst
- 3. http://ex-vi.sourceforge.net/vi.html
- 4. http://ex-vi.sourceforge.net/viin/paper.html
- 有用的外部链接
文件链接 | 文件类型 | 描述 |
---|---|---|
ftrace(kernel.org文档) | 标准 | Linux内核来源的文档 |
使用Ftrace调试内核-第1部分 | 用户指南 | http://lwn.net |
使用Ftrace调试内核-第2部分 | 用户指南 | http://lwn.net |
使用TRACE_EVENT()宏(带有CREATE_TRACE_POINTS) | 训练 | http://lwn.net |
使用ftrace加载性能分析 | 用户指南 | Linaro |
GDB
Debugging tools
The GNU Project debugger, GDB[5], allows monitoring program execution, or what the program was doing at the moment it crashed.
*
**
* Cross compile gdb and openocd binaries are required and only available from Developer Package.
** It is recommended to use the Developer Package to run the gdb debug session, which provided all dependencies
{{#vardefine:link|Linux tracing, monitoring and debugging page for the v1 ecosystem releases (in archived wiki)}}The STM32MPU distribution for Android™ is not yet available in the v2 ecosystem releases: please refer to the {{#var:link}}. |
简介
ifconfig是用于网络接口配置的系统管理实用程序。
安装此工具到开发板上
ifconfig是默认安装的,可以与所有STM32MPU嵌入式软件包一起使用。
Board $> which ifconfig | xargs ls -la /sbin/ifconfig -> /bin/busybox.nosuid
开始使用
列出所有网络接口
Board $> ifconfig -a
列出可用的网络接口
Board $> ifconfig
eth0 Link encap:Ethernet HWaddr 00:80:E1:42:43:65
inet addr:10.48.1.144 Bcast:10.48.3.255 Mask:255.255.252.0
inet6 addr: fe80::280:e1ff:fe42:4365%lo/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:181274 errors:0 dropped:14553 overruns:0 frame:0
TX packets:28583 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:23082127 (22.0 MiB) TX bytes:6438412 (6.1 MiB)
Interrupt:66 Base address:0x4000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1%1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:202 errors:0 dropped:0 overruns:0 frame:0
TX packets:202 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:13454 (13.1 KiB) TX bytes:13454 (13.1 KiB)
禁用网络接口
- 例如,对eth0接口进行如下操作
Board $> ifconfig eth0 down
启用网络接口(如果不可用)
- 例如,对eth0进行如下操作
Board $> ifconfig eth0 up
为网络接口指定IP地址
- 请按以下步骤为eth0分配 192.168.1.12 地址
Board $> ifconfig eth0 192.168.1.12
进阶操作
有关命令选项的更多详细信息,请参见手册页 https://linux.die.net/man/8/ifconfig
简介
- ip命令用来 [6]显示/操纵网络接口的路由,设备,策略路由和隧道。
开始使用
- 检查网络接口
Board $> ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
link/can
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:80:e1:42:43:65 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.237/22 brd 192.168.3.255 scope global dynamic eth0
valid_lft 172057sec preferred_lft 172057sec
inet 192.168.0.4/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::280:e1ff:fe42:4365/64 scope link
valid_lft forever preferred_lft forever
4: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
- 为指定网络接口分配IP地址
Board $> ip addr add 192.168.1.53 dev eth0
- 删除IP地址
Board $> ip addr del 192.168.1.53 dev eth0
- 禁用接口
Board $> ip link set eth0 down
- 启用接口
Board $> ip link set eth0 up
- 检查路由表
Board $> ip route show default via 192.168.3.254 dev eth0 proto dhcp src 192.168.1.237 metric 1024 192.168.0.0/22 dev eth0 proto kernel scope link src 192.168.1.237 192.168.3.254 dev eth0 proto dhcp scope link src 192.168.1.237 metric 1024
- 增加静态路由
Board $> ip route add 192.168.2.0/16 via 192.168.1.1 dev eth0
- 移除静态路由
Board $> ip route del 192.168.2.0/16
- 设置默认网关
Board $> ip route add default via 192.168.1.1
进阶使用
- 一些用法示例可供参考[7]
参考
- ↑ http://www.brendangregg.com/linuxperf.html
- ↑ http://www.tracecompass.org
- ↑ http://www.brendangregg.com/flamegraphs.html
- ↑ http://www.brendangregg.com/linuxperf.html
- ↑ https://www.gnu.org/software/gdb
- ↑ 6.06.1 https://linux.die.net/man/8/ip
- ↑ https://www.linuxtechi.com/ip-command-examples-for-linux-users/
- 其它参考链接
文件链接 | 文件链接 | 描述 |
---|---|---|
http://www.tecmint.com/ip-command-examples | 标准 | tecmint的文档 |
https://tty1.net/blog/2010/ifconfig-ip-comparison_en.html | 标准 | 文献资料 |
简介
- kmemleak[1]提供了一种与跟踪垃圾收集器类似的方法来检测可能的内核内存泄漏,不同之处在于,不释放孤立对象,而仅通过/sys/kernel/debug/kmemleak报告。
警告:显示的标题“Trace-cmd和kernelshark跟踪查看器”重写了此前显示的标题“IP Linux命令行”。
Ltrace
文章目的
- 本文提供了开始使用Linux工具所需的基本信息:ltrace [1 ]。
简介
- 下表简要介绍了该工具及其可用性,具体取决于软件包:
- 是:该工具已经存在(可以使用或激活),也可以在软件包中集成和激活。
- 没有:该工具不存在且无法集成,或者存在但无法在软件包中激活。
工具 | ||
---|---|---|
名称 | 类别 | 目的 |
ltrace | 追踪工具 | ltrace [1 ]用于显示对用户空间应用程序进行的共享库的调用。ltrace是一个用户空间应用程序。它的用法与strace 非常相似。 |
STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
没有 | 没有 | 是 |
适用于 Android 的STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
没有 | 没有 | 没有 |
在目标板上安装跟踪和调试工具
使用STM32MPU嵌入式软件发行版
分发包
- 要将 ltrace 合入到你的分发包镜像版本中,请按照以下步骤进行操作:
- 添加ltrace软件包以构建镜像
PC $> cd <your_Distribution_Package_root_dir>
PC $> echo 'IMAGE_INSTALL_append += "ltrace"' >> layers/meta-st/meta-st-openstlinux/recipes-st/images/st-image-weston.bbappend
- 重建完整的镜像
PC $> bitbake <full_image_name> # Needed to include ltrace into the final image rootfs
- 在板上重新加载新镜像:请参见刷新生成的镜像
使用入门
- 要使用ltrace,有两种主要方式:
- 1、提供你要为其列出动态库调用的程序的名称作为参数,并在需要时为其提供参数作为参数运行:
Board $> ltrace <Program> [ARGS]
- 例如:
Board $> ltrace weston-simple-egl
__libc_start_main(0x11a90, 1, 0xbec45d04, 0x131f0 <unfinished ...>
memset(0xbec456f8, 0, 72, 0x11a90) = 0xbec456f8
memset(0xbec45754, 0, 68, 0xbec45740) = 0xbec45754
wl_display_connect(0, 250, 32, 0xbec45750) = 0x26150
wl_proxy_marshal_constructor(0x26150, 1, 0x24e90, 0) = 0x2a268
wl_proxy_add_listener(0x2a268, 0x132e0, 0xbec456f8, 0) = 0
wl_display_roundtrip(0x26150, 0x132e0, 0xbec456f8, 0 <unfinished ...>
strcmp(0x2a404, 0x133e8, 1, 0x2a404) = 0
wl_proxy_marshal_constructor_versioned(0x2a268, 0, 0x24ed8, 1) = 0x2b070
strcmp(0x2a49c, 0x133e8, 2, 0x2a49c) = 16
strcmp(0x2a49c, 0x133f8, 115, 0x635f6c77) = -3
...
- 2、给出要研究的过程的 <PID> 作为参数:
Board $> ltrace -p <PID>
- 注意:<PID>值可以由`pidof <process_name>`代替
- 例如:
Board $> weston-simple-egl & ltrace -p `pidof weston-simple-egl`
has EGL_EXT_buffer_age and EGL_EXT_swap_buffers_with_damage
glGetShaderiv(1, 0x8b81, 0xbee14260, 0) = 0
glCreateShader(0x8b31, 0x8b31, 256, 1) = 2
glShaderSource(2, 1, 0xbee1425c, 0) = 0x1a96f0
glCompileShader(2, 0, 154, 0xbee14260) = 1
glGetShaderiv(2, 0x8b81, 0xbee14260, 0) = 0
glCreateProgram(2, 2, 256, 1) = 3
glAttachShader(3, 1, -1, 1) = 0
glAttachShader(3, 2, 0x8b30, 1) = 0
glLinkProgram(3, 0x8dd9, 0x8b31, 1) = 0x285234
glGetProgramiv(3, 0x8b82, 0xbee14698, 0) = 0
glUseProgram(3, 3, 256, 1) = 1
glBindAttribLocation(3, 0, 0x13884, 1) = 1
glBindAttribLocation(3, 1, 0x13888, 0) = 1
glLinkProgram(3, 0x1388e, 0, 0x1b9090) = 1
...
Board $> killall weston-simple-egl
深入学习
- 可以设置其他选项。有关详细信息,请参见手册页[2 ]。
参考
- 有用的外部链接
文件链接 | 文件类型 | 描述 |
---|---|---|
ltrace linux.die.net | 标准 | linux.die.net |
ltrace wikipedia.org | 标准 | wikipedia.org |
ltrace教程 | 用户指南 | go4expert.com |
跟踪培训 | 训练 | ellexus.com |
简介
perf[2]是Linux用户空间工具,它可以获取系统性能数据
如何安装
手动编译安装
BuildRoot下安装
Yocto下安装
RRECOMMENDS_${PN} = "\
${PERF} \
trace-cmd \
blktrace \
${PROFILE_TOOLS_X} \
${PROFILE_TOOLS_SYSTEMD} \
"
...
PERF = "perf"
安卓系统下使用
- simpleperf[3]与perf等效,并且默认情况下已安装(/system/xbin/simpleperf),可以与所有适用于Android™的软件包一起使用
- 它支持较少的选项:
Board $> simpleperf --help
Usage: simpleperf [common options] subcommand [args_for_subcommand]
common options:
-h/--help Print this help information.
--log <severity> Set the minimum severity of logging. Possible severities
include verbose, debug, warning, info, error, fatal.
Default is info.
--version Print version of simpleperf.
subcommands:
debug-unwind Debug/test offline unwinding.
dump dump perf record file
help print help information for simpleperf
kmem collect kernel memory allocation information
list list available event types
record record sampling info in perf.data
report report sampling information in perf.data
report-sample report raw sample information in perf.data
stat gather performance counter information
开始使用
Board $> which perf /usr/bin/perf
Perf命令
usage: perf [--version] [--help] [OPTIONS] COMMAND [ARGS]
The most commonly used perf commands are:
annotate Reads perf.data (created by perf record) and displays annotated code
archive Creates archive with object files with build-ids found in perf.data file
bench General framework for benchmark suites
buildid-cache Manages build-id cache.
buildid-list Lists the buildids in a perf.data file
c2c Shared Data C2C/HITM Analyzer.
config Gets and sets variables in a configuration file.
data Data file related processing
diff Reads perf.data files and displays the differential profile
evlist Lists the event names in a perf.data file
ftrace simple wrapper for kernel's ftrace functionality
inject Filters to augment the events stream with additional information
kallsyms Searches running kernel for symbols
kmem Tool to trace/measure kernel memory properties
kvm Tool to trace/measure kvm guest os
list Lists all symbolic event types
lock Analyzes lock events
mem Profiles memory accesses
record Runs a command and records its profile into perf.data
report Reads perf.data (created by perf record) and displays the profile
sched Tool to trace/measure scheduler properties (latencies)
script Reads perf.data (created by perf record) and displays trace output
stat Runs a command and gathers performance counter statistics
test Runs sanity tests.
timechart Tool to visualize total system behavior during a workload
top System profiling tool.
probe Defines new dynamic tracepoints
See 'perf COMMAND -h' for more information on a specific command.
- perf top(Linux内核文档[4]):通过计算循环事件数来提供CPU负载;默认顺序是每个符号的采样数降序:
Board $> perf top
40.62% [kernel] [k] v7_dma_inv_range
18.65% [kernel] [k] _raw_spin_unlock_irqrestore
17.01% [kernel] [k] arch_cpu_idle
8.27% [kernel] [k] v7_dma_clean_range
5.00% [kernel] [k] rcu_idle_exit
1.70% [kernel] [k] cpu_startup_entry
0.52% [kernel] [k] trace_graph_return
0.48% [kernel] [k] finish_task_switch
0.48% libc-2.18.so [.] memcpy
0.47% [kernel] [k] trace_graph_entry
- 意味着CPU在功能v7_dma_inv_range中花费了40%的时间,在_raw_spin_unlock_irqrestore中花费了18.65%的时间。
- 有关更多信息和示例,请访问perf.wiki.kernel.org[5]。
- 也可以按指定的排序显示结果:
sage: perf top [<options>]
-s, --sort <key[,key2...]>
sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ... Please refer to the main page for the complete list.
- perf stat(linux kernel documentation[6]): 获取事件计数
Board $> perf stat hello_world_example
User space example: hello world from STMicroelectronics
10 9 8 7 6 5 4 3 2 1 0
User space example: goodbye from STMicroelectronics
Performance counter stats for 'hello_world_example':
4.328249 task-clock (msec) # 0.000 CPUs utilized
11 context-switches # 0.003 M/sec
0 cpu-migrations # 0.000 K/sec
38 page-faults # 0.009 M/sec
2710036 cycles # 0.626 GHz
640856 instructions # 0.24 insn per cycle
75644 branches # 17.477 M/sec
21764 branch-misses # 28.77% of all branches
11.109859338 seconds time elapsed
- 有关更多信息和示例,请参见perf.wiki.kernel.org[7]
- perf list (Linux kernel documentation[8]): 支持的符号事件类型.
Board $> perf list
branch-instructions OR branches [Hardware event]
branch-misses [Hardware event]
bus-cycles [Hardware event]
cache-misses [Hardware event]
cache-references [Hardware event]
cpu-cycles OR cycles [Hardware event]
instructions [Hardware event]
alignment-faults [Software event]
bpf-output [Software event]
context-switches OR cs [Software event]
cpu-clock [Software event]
cpu-migrations OR migrations [Software event]
dummy [Software event]
emulation-faults [Software event]
major-faults [Software event]
minor-faults [Software event]
page-faults OR faults [Software event]
task-clock [Software event]
L1-dcache-load-misses [Hardware cache event]
L1-dcache-loads [Hardware cache event]
L1-dcache-store-misses [Hardware cache event]
L1-dcache-stores [Hardware cache event]
L1-icache-load-misses [Hardware cache event]
L1-icache-loads [Hardware cache event]
LLC-load-misses [Hardware cache event]
LLC-loads [Hardware cache event]
LLC-store-misses [Hardware cache event]
LLC-stores [Hardware cache event]
branch-load-misses [Hardware cache event]
branch-loads [Hardware cache event]
dTLB-load-misses [Hardware cache event]
dTLB-store-misses [Hardware cache event]
iTLB-load-misses [Hardware cache event]
armv7_cortex_a7/br_immed_retired/ [Kernel PMU event]
armv7_cortex_a7/br_mis_pred/ [Kernel PMU event]
armv7_cortex_a7/br_pred/ [Kernel PMU event]
armv7_cortex_a7/br_return_retired/ [Kernel PMU event]
armv7_cortex_a7/bus_access/ [Kernel PMU event]
armv7_cortex_a7/bus_cycles/ [Kernel PMU event]
armv7_cortex_a7/cid_write_retired/ [Kernel PMU event]
armv7_cortex_a7/cpu_cycles/ [Kernel PMU event]
armv7_cortex_a7/exc_return/ [Kernel PMU event]
armv7_cortex_a7/exc_taken/ [Kernel PMU event]
armv7_cortex_a7/inst_retired/ [Kernel PMU event]
armv7_cortex_a7/inst_spec/ [Kernel PMU event]
armv7_cortex_a7/l1d_cache/ [Kernel PMU event]
armv7_cortex_a7/l1d_cache_refill/ [Kernel PMU event]
armv7_cortex_a7/l1d_cache_wb/ [Kernel PMU event]
armv7_cortex_a7/l1d_tlb_refill/ [Kernel PMU event]
armv7_cortex_a7/l1i_cache/ [Kernel PMU event]
armv7_cortex_a7/l1i_cache_refill/ [Kernel PMU event]
armv7_cortex_a7/l1i_tlb_refill/ [Kernel PMU event]
armv7_cortex_a7/l2d_cache/ [Kernel PMU event]
armv7_cortex_a7/l2d_cache_refill/ [Kernel PMU event]
armv7_cortex_a7/l2d_cache_wb/ [Kernel PMU event]
armv7_cortex_a7/ld_retired/ [Kernel PMU event]
armv7_cortex_a7/mem_access/ [Kernel PMU event]
armv7_cortex_a7/memory_error/ [Kernel PMU event]
armv7_cortex_a7/pc_write_retired/ [Kernel PMU event]
armv7_cortex_a7/st_retired/ [Kernel PMU event]
armv7_cortex_a7/sw_incr/ [Kernel PMU event]
armv7_cortex_a7/ttbr_write_retired/ [Kernel PMU event]
armv7_cortex_a7/unaligned_ldst_retired/ [Kernel PMU event]
rNNN [Raw hardware event descriptor]
cpu/t1=v1[,t2=v2,t3 ...]/modifier [Raw hardware event descriptor]
mem:<addr>[/len][:access] [Hardware breakpoint]
alarmtimer:alarmtimer_cancel [Tracepoint event]
alarmtimer:alarmtimer_fired [Tracepoint event]
alarmtimer:alarmtimer_start [Tracepoint event]
alarmtimer:alarmtimer_suspend [Tracepoint event]
asoc:snd_soc_bias_level_done [Tracepoint event]
asoc:snd_soc_bias_level_start [Tracepoint event]
asoc:snd_soc_dapm_connected [Tracepoint event]
asoc:snd_soc_dapm_done [Tracepoint event]
asoc:snd_soc_dapm_path [Tracepoint event]
asoc:snd_soc_dapm_start [Tracepoint event]
asoc:snd_soc_dapm_walk_done [Tracepoint event]
asoc:snd_soc_dapm_widget_event_done [Tracepoint event]
asoc:snd_soc_dapm_widget_event_start [Tracepoint event]
...
xhci-hcd:xhci_inc_enq [Tracepoint event]
xhci-hcd:xhci_queue_trb [Tracepoint event]
xhci-hcd:xhci_ring_alloc [Tracepoint event]
xhci-hcd:xhci_ring_expansion [Tracepoint event]
xhci-hcd:xhci_ring_free [Tracepoint event]
xhci-hcd:xhci_setup_addressable_virt_device [Tracepoint event]
xhci-hcd:xhci_setup_device [Tracepoint event]
xhci-hcd:xhci_setup_device_slot [Tracepoint event]
xhci-hcd:xhci_stop_device [Tracepoint event]
xhci-hcd:xhci_urb_dequeue [Tracepoint event]
xhci-hcd:xhci_urb_enqueue [Tracepoint event]
xhci-hcd:xhci_urb_giveback [Tracepoint event]
- perf record (Linux kernel documentation[9]): 记录事件以供以后报告
Board $> perf record hello_world_example
User space example: hello world from STMicroelectronics
10 9 8 7 6 5 4 3 2 1 0
User space example: goodbye from STMicroelectronics
[ perf record: Woken up 1 time to write data ]
[ perf record: Captured and wrote 0.004 MB perf.data (28 samples) ]
- 这可以过滤事件(由perf list命令提供)。有关更多信息,选项和示例,请参见perf.wiki.kernel.org[10]。
- 默认情况下,事件记录在perf.data文件中。如果要指定另一个输出文件名,则必须添加-o,--output <file>选项。
- perf report (Linux kernel documentation[11]): 按进程,功能等细分事件。.
Example after previous command "perf record hello_world_example"
Board $> perf report
Samples: 28 of event 'cycles:ppp', Event count (approx.):2737925
Overhead Command Shared Object Symbol
12.66% hello_world_exa ld-2.26.so [.] _dl_relocate_object
11.71% hello_world_exa [kernel.kallsyms] [k] filemap_map_pages
10.65% hello_world_exa [kernel.kallsyms] [k] n_tty_write
6.43% hello_world_exa [kernel.kallsyms] [k] percpu_counter_add_batch
6.43% hello_world_exa ld-2.26.so [.] sbrk
6.24% hello_world_exa [kernel.kallsyms] [k] cpu_v7_set_pte_ext
5.56% hello_world_exa [kernel.kallsyms] [k] alloc_set_pte
5.56% hello_world_exa libc-2.26.so [.] __sbrk
5.37% hello_world_exa [kernel.kallsyms] [k] __vma_link_file
5.32% hello_world_exa [kernel.kallsyms] [k] __fput
5.32% hello_world_exa [kernel.kallsyms] [k] ldsem_up_read
5.32% hello_world_exa [kernel.kallsyms] [k] unmap_page_range
5.32% hello_world_exa libc-2.26.so [.] printf
5.24% hello_world_exa [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore
2.23% hello_world_exa [kernel.kallsyms] [k] perf_event_mmap
0.48% hello_world_exa [kernel.kallsyms] [k] perf_output_begin
0.13% perf [kernel.kallsyms] [k] perf_event_exec
默认情况下,报告文件perf.data被读取为输入文件。如果要指定另一个输入文件名,则必须添加-i,--input <file> option。 有关更多信息和示例,请参见perf.wiki.kernel.org[12]。
- perf bench (Linux kernel documentation[13]): 运行不同的内核微基准测试:
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
futex: Futex stressing benchmarks
all: All benchmarks
Example of getting memcpy benchmark for 100MB:
Board $> perf bench mem memcpy --size 100MB
# Running 'mem/memcpy' benchmark:
# function 'default' (Default memcpy() provided by glibc)
# Copying 100MB bytes ...
1.426138 GB/sec
- 有关更多信息和示例,请参见perf.wiki.kernel.org[14]
进阶使用
作为Flame Graphs [14 ]的一部分,可以可视化来自perf的痕迹
- 作为Flame Graphs[15]的一部分, 用来可视化perf的trace数据分析.
- 火焰图是使用火焰图工具套件生成[16]
- 在主机端安装Flame Graph工具套件。
PC $> cd <your_local_path>
PC $> git clone https://github.com/brendangregg/FlameGraph.git
PC $> cd FlameGraph
- 从perf tool生成火焰图
- 生成性能记录时,必须添加-g选项。
生成火焰图并查看示例:
- 在板上执行perf record命令
Board $> perf record -a -g top
Board $> perf script > perf_top.out
- 复制perf_top.out到主机PC中(即在FlameGraph目录中)
- 使用stackcollapse-perf.pl脚本在主机PC端执行火焰图生成命令。
PC $> ./stackcollapse-perf.pl perf_top.out > out.top_folded
- 使用flamegraph.pl渲染SVG(可缩放矢量图形)文件。
PC $> ./flamegraph.pl out.top_folded > top.svg
- 例如使用网络浏览器查看SVG
PC $> firefox top.svg
参考
- ↑ http://www.procode.org/kmemleak/
- ↑ https://perf.wiki.kernel.org/index.php/Main_Page
- ↑ https://source.android.com/devices/tech/debug/eval_perf
- ↑ https://github.com/STMicroelectronics/linux/blob/v4.19-stm32mp/tools/perf/Documentation/perf-top.txt
- ↑ https://perf.wiki.kernel.org/index.php/Tutorial#Live_analysis_with_perf_top
- ↑ https://github.com/STMicroelectronics/linux/blob/v4.19-stm32mp/tools/perf/Documentation/perf-stat.txt
- ↑ https://perf.wiki.kernel.org/index.php/Tutorial#Counting_with_perf_stat
- ↑ https://github.com/STMicroelectronics/linux/blob/v4.19-stm32mp/tools/perf/Documentation/perf-list.txt
- ↑ https://github.com/STMicroelectronics/linux/blob/v4.19-stm32mp/tools/perf/Documentation/perf-record.txt
- ↑ https://perf.wiki.kernel.org/index.php/Tutorial#Sampling_with_perf_record
- ↑ https://github.com/STMicroelectronics/linux/blob/v4.19-stm32mp/tools/perf/Documentation/perf-record.txt
- ↑ https://perf.wiki.kernel.org/index.php/Tutorial#Sample_analysis_with_perf_report
- ↑ https://github.com/STMicroelectronics/linux/blob/v4.19-stm32mp/tools/perf/Documentation/perf-record.txt
- ↑ https://perf.wiki.kernel.org/index.php/Tutorial#Benchmarking_with_perf_bench
- ↑ http://www.brendangregg.com/flamegraphs.html
- ↑ https://github.com/brendangregg/FlameGraph
Strace
文章目的
- 本文提供了开始使用 Linux 工具(strace [1 ])所需的基本信息。
简介
- 下表简要介绍了该工具及其可用性,具体取决于软件包:
- 是:该工具已经存在(可以使用或激活),也可以在软件包中集成和激活。
- 没有:该工具不存在且无法集成,或者存在但无法在软件包中激活。
工具 | ||
---|---|---|
名称 | 类别 | 目的 |
Strace | 追踪工具 | strace [1 ]能够截获和记录一个进程调用的系统调用以及另一个进程接收的信号。 |
STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
是 | 是 | 是 |
适用于 Android 的STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
是 | 是 | 是 |
在目标板上安装跟踪和调试工具
使用 STM32MPU 嵌入式软件发行版
- strace 默认情况下已安装,可以与所有 STM32MPU 嵌入式软件包一起使用。
Board $> which strace
/usr/bin/strace
- strace 通过 meta-st 软件包集成到 weston 镜像分发中:meta-st/meta-st-openstlinux/recipes-st/packagegroups/packagegroup-framework-tools.bb 。
RDEPENDS_packagegroup-framework-tools-kernel-base = "\
can-utils \
i2c-tools \
strace \
usbutils \
\
evtest \
memtester \
mtd-utils \
v4l-utils \
"
使用适用于 Android 的 STM32MPU 嵌入式软件发行版
- strace 默认情况下已安装(/system/bin/strace),并准备与所有适用于 Android 的 STM32MPU 软件包一起使用。
Board $> which strace
/system/bin/strace
- 它通过 Android 基本的 makefile 集成在 Android 镜像分发中 build/make/target/product/base.mk:
# Packages included only for eng or userdebug builds, previously debug tagged
PRODUCT_PACKAGES_DEBUG := \
logpersist.start \
perfprofd \
sqlite3 \
strace
使用入门
- 要使用strace,有两种主要方法:
- 通过提供要列出其系统调用的程序的名称作为参数,并在需要时为其指定参数作为参数运行:
Board $> strace <Program> [Prog_Args]
- 通过给出要研究的过程的PID作为参数:
Board $> strace -p <PID>
- 一些有用的命令选项:
-a <num> : alignment num COLUMN for printing syscall results
-r : print relative timestamp
-t : print absolute timestamp
-T : print time spent in each syscall
- 还可以设置其他选项。有关详细信息,请参阅手册页[2 ]。
深入学习
示例
- 例如,可以通过 gst-play 获得系统调用来播放多媒体文件:
Board $> strace -rT -a 100 gst-play-1.0 /usr/local/demo/media/ST2297_visionv3.webm
0.000000 execve("/usr/bin/gst-play-1.0", ["gst-play-1.0", "[...]"...], 0xbeb10c00 /* 24 vars */) = 0 <0.001485>
0.002800 brk(NULL) = 0x28000 <0.000069>
0.000717 uname({sysname="Linux", nodename="stm32mp1", ...}) = 0 <0.000069>
0.000591 mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6fa2000 <0.000093>
0.000673 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) <0.000109>
0.000734 openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 <0.000115>
0.000669 fstat64(3, {st_mode=S_IFREG|0644, st_size=24533, ...}) = 0 <0.000069>
0.000619 mmap2(NULL, 24533, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6f9c000 <0.000091>
0.000599 close(3) = 0 <0.000065>
0.000668 openat(AT_FDCWD, "/usr/lib/libgstpbutils-1.0.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000114>
0.000646 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\300\234\0\0004\0\0\0"..., 512) = 512 <0.000083>
0.000611 fstat64(3, {st_mode=S_IFREG|0755, st_size=195640, ...}) = 0 <0.000080>
0.000712 mmap2(NULL, 260004, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6f34000 <0.000088>
0.000596 mprotect(0xb6f62000, 61440, PROT_NONE) = 0 <0.000098>
0.000609 mmap2(0xb6f71000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2d000) = 0xb6f71000 <0.000147>
0.000811 close(3) = 0 <0.000070>
0.000706 openat(AT_FDCWD, "/usr/lib/libgstvideo-1.0.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000138>
0.000754 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0P\317\0\0004\0\0\0"..., 512) = 512 <0.000079>
0.000612 fstat64(3, {st_mode=S_IFREG|0755, st_size=486440, ...}) = 0 <0.000070>
0.000618 mmap2(NULL, 552344, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6ead000 <0.000087>
0.000601 mprotect(0xb6f1c000, 61440, PROT_NONE) = 0 <0.000092>
0.000610 mmap2(0xb6f2b000, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6e000) = 0xb6f2b000 <0.000132>
0.000709 close(3) = 0 <0.000067>
0.000712 openat(AT_FDCWD, "/usr/lib/libgstaudio-1.0.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000121>
0.000673 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\0\236\0\0004\0\0\0"..., 512) = 512 <0.000078>
0.000606 fstat64(3, {st_mode=S_IFREG|0755, st_size=375816, ...}) = 0 <0.000067>
0.000623 mmap2(NULL, 440684, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6e41000 <0.000150>
0.000692 mprotect(0xb6e9b000, 61440, PROT_NONE) = 0 <0.000096>
0.000606 mmap2(0xb6eaa000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x59000) = 0xb6eaa000 <0.000130>
0.000722 close(3) = 0 <0.000071>
0.000700 openat(AT_FDCWD, "/usr/lib/libgsttag-1.0.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000135>
0.000755 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\370d\0\0004\0\0\0"..., 512) = 512 <0.000080>
0.000613 fstat64(3, {st_mode=S_IFREG|0755, st_size=215824, ...}) = 0 <0.000068>
0.000617 mmap2(NULL, 280136, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6dfc000 <0.000087>
0.000597 mprotect(0xb6e2f000, 65536, PROT_NONE) = 0 <0.000090>
0.000617 mmap2(0xb6e3f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x33000) = 0xb6e3f000 <0.000121>
0.000702 close(3) = 0 <0.000070>
0.009092 openat(AT_FDCWD, "/usr/lib/libgstreamer-1.0.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000146>
0.010000 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\270\371\1\0004\0\0\0"..., 512) = 512 <0.000088>
0.010392 fstat64(3, {st_mode=S_IFREG|0755, st_size=1116268, ...}) = 0 <0.000072>
0.010210 mmap2(NULL, 1184392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6cda000 <0.000107>
0.010879 mprotect(0xb6de7000, 61440, PROT_NONE) = 0 <0.000106>
0.010048 mmap2(0xb6df6000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x10c000) = 0xb6df6000 <0.000186>
0.011926 mmap2(0xb6dfb000, 648, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb6dfb000 <0.000141>
0.011239 close(3) = 0 <0.000073>
0.010260 openat(AT_FDCWD, "/usr/lib/libgobject-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000147>
0.009916 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\250\212\0\0004\0\0\0"..., 512) = 512 <0.000095>
0.010372 fstat64(3, {st_mode=S_IFREG|0755, st_size=294000, ...}) = 0 <0.000075>
0.010086 mmap2(NULL, 359636, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6c82000 <0.000102>
0.010916 mprotect(0xb6cc9000, 61440, PROT_NONE) = 0 <0.000103>
0.010033 mmap2(0xb6cd8000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x46000) = 0xb6cd8000 <0.000143>
0.011876 close(3) = 0 <0.000074>
0.010153 openat(AT_FDCWD, "/usr/lib/libglib-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000146>
0.009983 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0XX\1\0004\0\0\0"..., 512) = 512 <0.000088>
0.010209 fstat64(3, {st_mode=S_IFREG|0755, st_size=990348, ...}) = 0 <0.000075>
0.010215 mmap2(NULL, 1056232, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6b80000 <0.000103>
0.010881 mprotect(0xb6c71000, 61440, PROT_NONE) = 0 <0.000100>
0.010032 mmap2(0xb6c80000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xf0000) = 0xb6c80000 <0.000150>
0.011792 close(3) = 0 <0.000073>
0.010218 openat(AT_FDCWD, "/lib/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 <0.000140>
0.010000 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\220E\0\0004\0\0\0"..., 512) = 512 <0.000084>
0.010212 fstat64(3, {st_mode=S_IFREG|0755, st_size=452028, ...}) = 0 <0.000073>
0.010207 mmap2(NULL, 516216, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6b01000 <0.000101>
0.010877 mprotect(0xb6b6f000, 61440, PROT_NONE) = 0 <0.000110>
0.010035 mmap2(0xb6b7e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6d000) = 0xb6b7e000 <0.000152>
0.011806 close(3) = 0 <0.000075>
0.010130 openat(AT_FDCWD, "/lib/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000134>
0.010086 read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\214H\0\0004\0\0\0"..., 512) = 512 <0.000085>
0.010211 fstat64(3, {st_mode=S_IFREG|0755, st_size=92656, ...}) = 0 <0.000074>
0.010208 mmap2(NULL, 164424, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6ad8000 <0.000100>
0.010813 mprotect(0xb6aee000, 61440, PROT_NONE) = 0 <0.000108>
0.010205 mmap2(0xb6afd000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0xb6afd000 <0.000172>
0.011742 mmap2(0xb6aff000, 4680, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb6aff000 <0.000137>
0.011249 close(3) = 0 <0.000072>
0.010170 openat(AT_FDCWD, "/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 <0.000149>
0.009988 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\34l\1\0004\0\0\0"..., 512) = 512 <0.000088>
0.010219 fstat64(3, {st_mode=S_IFREG|0755, st_size=1218336, ...}) = 0 <0.000075>
0.010198 mmap2(NULL, 1287556, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb699d000 <0.000105>
0.010876 mprotect(0xb6ac3000, 61440, PROT_NONE) = 0 <0.000132>
0.010123 mmap2(0xb6ad2000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x125000) = 0xb6ad2000 <0.000177>
0.011925 mmap2(0xb6ad5000, 9604, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb6ad5000 <0.000141>
0.011252 close(3) = 0 <0.000077>
0.010267 openat(AT_FDCWD, "/usr/lib/liborc-0.4.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000150>
0.009799 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0`u\0\0004\0\0\0"..., 512) = 512 <0.000090>
0.010386 fstat64(3, {st_mode=S_IFREG|0755, st_size=402508, ...}) = 0 <0.000073>
0.010032 mmap2(NULL, 466900, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb692b000 <0.000098>
0.010893 mprotect(0xb698a000, 61440, PROT_NONE) = 0 <0.000103>
0.010193 mmap2(0xb6999000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5e000) = 0xb6999000 <0.000141>
0.011890 close(3) = 0 <0.000073>
0.010150 openat(AT_FDCWD, "/lib/libz.so.1", O_RDONLY|O_CLOEXEC) = 3 <0.000149>
0.009972 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\300\32\0\0004\0\0\0"..., 512) = 512 <0.000090>
0.010203 fstat64(3, {st_mode=S_IFREG|0755, st_size=79468, ...}) = 0 <0.000074>
0.010227 mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6f9a000 <0.000105>
0.010939 mmap2(NULL, 143584, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6907000 <0.000098>
0.010737 mprotect(0xb691a000, 61440, PROT_NONE) = 0 <0.000104>
0.010209 mmap2(0xb6929000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12000) = 0xb6929000 <0.000152>
0.011788 close(3) = 0 <0.000075>
0.010144 openat(AT_FDCWD, "/usr/lib/libgstbase-1.0.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000149>
0.009981 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\20\244\0\0004\0\0\0"..., 512) = 512 <0.000083>
0.010217 fstat64(3, {st_mode=S_IFREG|0755, st_size=375700, ...}) = 0 <0.000073>
0.010125 mmap2(NULL, 440032, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb689b000 <0.000104>
0.010882 mprotect(0xb68f6000, 61440, PROT_NONE) = 0 <0.000110>
0.010198 mmap2(0xb6905000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5a000) = 0xb6905000 <0.000149>
0.011807 close(3) = 0 <0.000075>
0.010290 openat(AT_FDCWD, "/usr/lib/libgmodule-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3 <0.000143>
0.009822 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\230\f\0\0004\0\0\0"..., 512) = 512 <0.000081>
0.010205 fstat64(3, {st_mode=S_IFREG|0755, st_size=13764, ...}) = 0 <0.000074>
0.010219 mmap2(NULL, 78056, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6887000 <0.000099>
0.010891 mprotect(0xb6889000, 65536, PROT_NONE) = 0 <0.000106>
0.010105 mmap2(0xb6899000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0xb6899000 <0.000229>
0.011760 close(3) = 0 <0.000076>
0.009988 openat(AT_FDCWD, "/lib/librt.so.1", O_RDONLY|O_CLOEXEC) = 3 <0.000160>
0.010017 read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0@\27\0\0004\0\0\0"..., 512) = 512 <0.000092>
0.010371 fstat64(3, {st_mode=S_IFREG|0755, st_size=26520, ...}) = 0 <0.000076>
0.010039 mmap2(NULL, 90640, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6870000 <0.000113>
0.010881 mprotect(0xb6876000, 61440, PROT_NONE) = 0 <0.000116>
0.010223 mmap2(0xb6885000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5000) = 0xb6885000 <0.000169>
0.011617 close(3) = 0 <0.000073>
0.010093 openat(AT_FDCWD, "/lib/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 <0.000151>
0.010016 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0l\t\0\0004\0\0\0"..., 512) = 512 <0.000088>
0.010390 fstat64(3, {st_mode=S_IFREG|0755, st_size=9688, ...}) = 0 <0.000075>
0.010039 mmap2(NULL, 73916, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb685d000 <0.000123>
0.010884 mprotect(0xb685f000, 61440, PROT_NONE) = 0 <0.000108>
0.010192 mmap2(0xb686e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0xb686e000 <0.000152>
0.011636 close(3) = 0 <0.000073>
0.010119 openat(AT_FDCWD, "/usr/lib/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3 <0.000151>
0.010004 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\10\16\0\0004\0\0\0"..., 512) = 512 <0.000091>
0.010378 fstat64(3, {st_mode=S_IFREG|0755, st_size=263672, ...}) = 0 <0.000075>
0.010090 mmap2(NULL, 327900, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb680c000 <0.000107>
0.010920 mprotect(0xb684c000, 61440, PROT_NONE) = 0 <0.000104>
0.010024 mmap2(0xb685b000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3f000) = 0xb685b000 <0.000146>
0.011805 close(3) = 0 <0.000074>
0.010104 openat(AT_FDCWD, "/usr/lib/libffi.so.6", O_RDONLY|O_CLOEXEC) = 3 <0.000143>
0.010024 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\\\23\0\0004\0\0\0"..., 512) = 512 <0.000086>
0.010382 fstat64(3, {st_mode=S_IFREG|0755, st_size=26232, ...}) = 0 <0.000073>
0.010051 mmap2(NULL, 90920, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb67f5000 <0.000105>
0.010872 mprotect(0xb67fb000, 61440, PROT_NONE) = 0 <0.000102>
0.010200 mmap2(0xb680a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5000) = 0xb680a000 <0.000148>
0.011641 close(3) = 0 <0.000075>
0.010292 openat(AT_FDCWD, "/lib/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3 <0.000137>
0.009911 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\340\320\0\0004\0\0\0"..., 512) = 512 <0.000086>
0.010385 fstat64(3, {st_mode=S_IFREG|0644, st_size=116300, ...}) = 0 <0.000074>
0.010041 mmap2(NULL, 180524, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb67c8000 <0.000104>
0.010880 mprotect(0xb67e4000, 61440, PROT_NONE) = 0 <0.000118>
0.010201 mmap2(0xb67f3000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0xb67f3000 <0.000148>
0.011796 close(3) = 0 <0.000086>
0.010379 mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6f98000 <0.000101>
0.010683 set_tls(0xb6f98b20, 0xb6f99218, 0xb6fa5000, 0xb6f98b20, 0xb6fa5000) = 0 <0.000072>
0.010361 mprotect(0xb6ad2000, 8192, PROT_READ) = 0 <0.000142>
0.009734 mprotect(0xb67f3000, 4096, PROT_READ) = 0 <0.000106>
0.010069 mprotect(0xb680a000, 4096, PROT_READ) = 0 <0.000097>
0.010222 mprotect(0xb685b000, 4096, PROT_READ) = 0 <0.000093>
0.010220 mprotect(0xb686e000, 4096, PROT_READ) = 0 <0.000103>
0.010384 mprotect(0xb6afd000, 4096, PROT_READ) = 0 <0.000112>
0.010054 mprotect(0xb6885000, 4096, PROT_READ) = 0 <0.000103>
0.009813 mprotect(0xb6c80000, 4096, PROT_READ) = 0 <0.000100>
0.010081 mprotect(0xb6899000, 4096, PROT_READ) = 0 <0.000098>
0.010369 mprotect(0xb6cd8000, 4096, PROT_READ) = 0 <0.000126>
0.009958 mprotect(0xb6b7e000, 4096, PROT_READ) = 0 <0.000106>
0.010580 mprotect(0xb6df6000, 12288, PROT_READ) = 0 <0.000124>
0.009648 mprotect(0xb6905000, 4096, PROT_READ) = 0 <0.000105>
0.010043 mprotect(0xb6929000, 4096, PROT_READ) = 0 <0.000104>
0.010156 mprotect(0xb6999000, 4096, PROT_READ) = 0 <0.000107>
0.010271 mprotect(0xb6e3f000, 4096, PROT_READ) = 0 <0.000105>
0.010043 mprotect(0xb6eaa000, 8192, PROT_READ) = 0 <0.000106>
0.010246 mprotect(0xb6f2b000, 32768, PROT_READ) = 0 <0.000132>
0.010042 mprotect(0xb6f71000, 8192, PROT_READ) = 0 <0.000108>
0.009957 mprotect(0x26000, 4096, PROT_READ) = 0 <0.000105>
0.010137 mprotect(0xb6fa4000, 4096, PROT_READ) = 0 <0.000107>
0.010023 munmap(0xb6f9c000, 24533) = 0 <0.000165>
0.010125 set_tid_address(0xb6f986c8) = 865 <0.000069>
0.010190 set_robust_list(0xb6f986d0, 12) = 0 <0.000066>
0.010395 rt_sigaction(SIGRTMIN, {sa_handler=0xb6adc24c, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0xb69c8a60}, NULL, 8) = 0 <0.000084>
0.013419 rt_sigaction(SIGRT_1, {sa_handler=0xb6adc308, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0xb69c8a60}, NULL, 8) = 0 <0.000074>
0.014382 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 <0.000067>
0.010288 ugetrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0 <0.000071>
0.011172 brk(NULL) = 0x28000 <0.000079>
0.009511 brk(0x49000) = 0x49000 <0.000099>
0.012309 futex(0xb6c81cac, FUTEX_WAKE_PRIVATE, 2147483647) = 0 <0.000087>
0.008552 futex(0xb6c81cac, FUTEX_WAKE_PRIVATE, 2147483647) = 0 <0.000075>
0.011329 uname({sysname="Linux", nodename="stm32mp1", ...}) = 0 <0.000079>
0.009512 futex(0xb6c81cac, FUTEX_WAKE_PRIVATE, 2147483647) = 0 <0.000084>
0.009496 futex(0xb6c81cac, FUTEX_WAKE_PRIVATE, 2147483647) = 0 <0.000076>
0.010059 futex(0xb6c81cac, FUTEX_WAKE_PRIVATE, 2147483647) = 0 <0.000090>
...
0.000866 poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}, {fd=5, events=POLLIN}], 3, 95) = 0 (Timeout) <0.103064>
0.103921 getpid() = 865 <0.000090>
0.001614 getpid() = 865 <0.000104>
0.001243 futex(0xb50715f0, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000108>
) = 29 <0.000213> 290:00:01.7/0:00:04.0
0.000921 poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}, {fd=5, events=POLLIN}], 3, 94) = 0 (Timeout) <0.102831>
0.103744 getpid() = 865 <0.000117>
0.000806 futex(0xb50715f0, FUTEX_WAKE_PRIVATE, 1) = 1 <0.000129>
0.000953 getpid() = 865 <0.000101>
) = 29 <0.000230> 290:00:01.8/0:00:04.0
0.000919 poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}, {fd=5, events=POLLIN}], 3, 94) = 0 (Timeout) <0.103294>
0.104092 getpid() = 865 <0.000085>
0.000768 getpid() = 865 <0.000076>
) ) = ? ERESTART_RESTARTBLOCK (Interrupted by signal) <0.028771>
strace: Process 865 detached
参考
- 有用的外部链接
文件链接 | 文件类型 | 描述 |
---|---|---|
strace linux.die.net | 标准 | linux.die.net |
strace wikipedia.org | 标准 | wikipedia.org |
如何使用 strace] | 用户指南 | go4expert.com |
strace 示例 | 训练 | thegeekstuff.com |
Sysprof
文章目的
- 本文提供了开始使用Linux内核工具sysprof [1 ]所需的基本信息。
简介
- 下表简要介绍了该工具及其可用性,具体取决于软件包:
- 是:该工具已经存在(可以使用或激活),也可以在软件包中集成和激活。
- 没有:该工具不存在且无法集成,或者存在但无法在软件包中激活。
工具 | ||
---|---|---|
名称 | 类别 | 目的 |
sysprof | 监控工具 | sysprof [1 ]是Linux的统计,系统范围的探查器。它有助于找到程序花费大部分时间的功能。 |
STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
是 | 是 | 是 |
适用于 Android 的STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
没有 | 没有 | 没有 |
在目标板上安装跟踪和调试工具
使用STM32MPU嵌入式软件发行版
- sysprof 默认情况下已安装,可以与其他所有的 STM32MPU 嵌入式软件包一起使用。
Board $> which sysprof
/usr/bin/sysprof
- sysprof 通过 openembedded-core 软件包集成到 weston 镜像分发中:openembedded-core/meta/recipes-core/packagegroups/packagegroup-core-tools-profile.bb。
PROFILE_TOOLS_X = "${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'sysprof', , d)}"
...
RRECOMMENDS_${PN} = "\
${PERF} \
trace-cmd \
blktrace \
${PROFILE_TOOLS_X} \
${PROFILE_TOOLS_SYSTEMD} \
"
使用入门
- 注意: sysprof 支持屏幕的分辨率不能低于700x1200,所以在 STM32MP15 上不起作用
- 在板上启动 sysprof:
Board $> sysprof
- Sysprof 建议通过开发板连接到额外的显示器的方式显示用户界面。插入鼠标(和可选的键盘)这样使用工具界面可能更方便。
- 800px
- 记录
- 单击左上方的"录制”按钮即可启动录制。通过单击左上方的"停止”按钮(代替“录音”按钮)来停止录制。
- 然后,将会得到类似下面的报告结果:
- 800px
深入学习
- 用户可以使用几个选项来过滤报告内容,然后专注研究结果:
- 可以浏览"Functions"列表,"Descendants"列表。
- 可以选择指定时间段的 CPU 图形。
- 可以保存轨迹,进行屏幕截图等等
- 800px
参考
- 有用的外部链接
文件连结 | 文件类型 | 描述 |
---|---|---|
来自GNOME的Sysprof | 标准 | 维基页面 |
使用Sysprof进行性能分析 | 用户手册 | Linux.com |
警告:显示的标题“Sysstat工具套件”重写了此前显示的标题“Trace-cmd和kernelshark跟踪查看器”。
Sysstat工具套件
文章目的
- 本文提供了开始使用sysstat [1 ]工具套件所需的基本信息,该工具套件提供了一系列Linux工具:
- 主要工具:iostat,mpstat和pidstat
- 其他工具:sar,sadf
简介
- 下表简要介绍了该工具及其可用性,具体取决于软件包:
- 是:该工具已经存在(可以使用或激活),也可以在软件包中集成和激活。
- 没有:该工具不存在且无法集成,或者存在但无法在软件包中激活。
工具 | ||
---|---|---|
名称 | 类别 | 目的 |
系统状态 | 监控工具 | 所述SYSSTAT [1 ]工具套件中含有用来监视系统的性能和使用活动。它包含许多商业Unix发行版共有的各种实用程序,以及可以进行计划的工具(通过诸如cron这样的计划程序)来收集和历史化性能和活动数据的工具:
|
STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
是 | 是 | 是 |
适用于 Android 的STM32MPU嵌入式软件发行版 | ||
入门资料包 | 开发者资料包 | 发行版资料包 |
没有 | 没有 | 没有 |
在目标板上安装跟踪和调试工具
使用STM32MPU嵌入式软件发行版
- 该 SYSSTAT 工具在默认情况下位于(/usr/bin/),并准备安装到所有 STM32MPU OpenSTLinux 包中使用。
- 通过meta-st软件包将其集成到weston镜像分发中meta-st/meta-st-openstlinux/recipes-st/packagegroups/packagegroup-framework-tools.bb。
RDEPENDS_packagegroup-framework-tools-core = "\
grep \
...
e2fsprogs \
e2fsprogs-resize2fs \
sysstat \
minicom \
...
"
使用入门
使用 iostat
- iostat 命令用于通过观察设备活动的时间(相对于其平均传输速率)来监视系统输入/输出设备负载。 iostat命令生成报告,这些报告可用于更改系统配置,以更好地平衡物理磁盘之间的输入/输出负载(来源:官方网站[2])。
- /proc必须挂载文件系统后,iostat 才能工作。STM32MPU 嵌入式软件就是这种情况。
- 命令行选项。有关详细信息,请参见手册页[2 ]。
Board $> iostat --help
Usage: iostat [ options ] [ <interval> [ <count> ] ]
Options are:
[ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -s ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]
[ -j { ID | LABEL | PATH | UUID | ... } ] [ --human ] [ -o JSON ]
[ [ -H ] -g <group_name> ] [ -p [ <device> [,...] | ALL ] ]
[ <device> [...] | ALL ]
- 显示所有 CPU 和设备启动报告以来的单个历史记录的基本命令:
Board $> iostat
Linux 4.14.48 (stm32mp1) 06/18/18 _armv7l_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.11 0.00 0.60 0.05 0.00 99.25
Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
mmcblk0 0.59 5.44 0.85 58539 9128
mmcblk1 0.03 0.31 0.00 3320 0
mmcblk1boot1 0.00 0.01 0.00 104 0
mmcblk1boot0 0.00 0.01 0.00 104 0
- 注意:通过添加 <interval> 和 <count> 参数,你可以在给定的时间间隔内进行定期刷新:
Board $> iostat <interval> <count>
- 用于显示系统使用的块设备及其所有分区的统计信息的命令:
Board $> iostat -N -p ALL
Linux 4.14.48 (stm32mp1) 06/18/18 _armv7l_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.11 0.00 0.61 0.05 0.00 99.23
Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
ram0 0.00 0.00 0.00 0 0
ram1 0.00 0.00 0.00 0 0
ram2 0.00 0.00 0.00 0 0
ram3 0.00 0.00 0.00 0 0
ram4 0.00 0.00 0.00 0 0
ram5 0.00 0.00 0.00 0 0
ram6 0.00 0.00 0.00 0 0
ram7 0.00 0.00 0.00 0 0
ram8 0.00 0.00 0.00 0 0
ram9 0.00 0.00 0.00 0 0
ram10 0.00 0.00 0.00 0 0
ram11 0.00 0.00 0.00 0 0
ram12 0.00 0.00 0.00 0 0
ram13 0.00 0.00 0.00 0 0
ram14 0.00 0.00 0.00 0 0
ram15 0.00 0.00 0.00 0 0
loop0 0.00 0.00 0.00 0 0
loop1 0.00 0.00 0.00 0 0
loop2 0.00 0.00 0.00 0 0
loop3 0.00 0.00 0.00 0 0
loop4 0.00 0.00 0.00 0 0
loop5 0.00 0.00 0.00 0 0
loop6 0.00 0.00 0.00 0 0
loop7 0.00 0.00 0.00 0 0
mtdblock0 0.00 0.00 0.00 0 0
mtdblock1 0.00 0.00 0.00 0 0
mtdblock2 0.00 0.00 0.00 0 0
mtdblock3 0.00 0.00 0.00 0 0
mtdblock4 0.00 0.00 0.00 0 0
mtdblock5 0.00 0.00 0.00 0 0
mtdblock6 0.00 0.00 0.00 0 0
mtdblock7 0.00 0.00 0.00 0 0
mmcblk0 0.66 6.02 0.94 58539 9128
mmcblk0p1 0.00 0.04 0.00 344 0
mmcblk0p2 0.00 0.02 0.00 220 0
mmcblk0p3 0.00 0.01 0.00 72 0
mmcblk0p4 0.03 0.21 0.00 2065 1
mmcblk0p5 0.60 5.46 0.94 53175 9126
mmcblk0p6 0.02 0.21 0.00 2087 1
mmcblk1 0.04 0.34 0.00 3320 0
mmcblk1p1 0.00 0.01 0.00 64 0
mmcblk1p2 0.00 0.00 0.00 44 0
mmcblk1p3 0.00 0.00 0.00 44 0
mmcblk1p4 0.01 0.11 0.00 1032 0
mmcblk1p5 0.01 0.11 0.00 1032 0
mmcblk1boot1 0.00 0.01 0.00 104 0
mmcblk1boot0 0.00 0.01 0.00 104 0
使用mpstat
- mpstat命令将每个可用处理器的标准输出活动写入,其中处理器 0 是第一个活动(来源:官方网站[3])。
- 命令行选项。有关详细信息,请参见手册页[3 ]。
Board $> mpstat --help
Usage: mpstat [ options ] [ <interval> [ <count> ] ]
Options are:
[ -A ] [ -n ] [ -u ] [ -V ] [ -I { SUM | CPU | SCPU | ALL } ]
[ -N { <node_list> | ALL } ] [ -o JSON ] [ -P { <cpu_list> | ON | ALL } ]
- 基本命令以一秒钟的间隔显示所有处理器的三个全局统计信息报告:
Board $> mpstat 1 3
Linux 4.14.48 (stm32mp1) 06/18/18 _armv7l_ (2 CPU)
15:45:26 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
15:45:27 all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
15:45:28 all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
15:45:29 all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
- 其他命令以一秒钟的间隔显示所有处理器的三个统计信息的详细报告:
Board $> mpstat -P ALL 1 3
Linux 4.14.48 (stm32mp1) 06/18/18 _armv7l_ (2 CPU)
15:48:32 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
15:48:33 all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
15:48:33 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
15:48:33 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
15:48:33 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
15:48:34 all 0.00 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 99.50
15:48:34 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
15:48:34 1 0.00 0.00 0.99 0.00 0.00 0.00 0.00 0.00 0.00 99.01
15:48:34 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
15:48:35 all 0.00 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 99.50
15:48:35 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
15:48:35 1 0.00 0.00 0.99 0.00 0.00 0.00 0.00 0.00 0.00 99.01
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 0.00 0.00 0.33 0.00 0.00 0.00 0.00 0.00 0.00 99.67
Average: 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
Average: 1 0.00 0.00 0.66 0.00 0.00 0.00 0.00 0.00 0.00 99.34
使用pidstat
- pidstat 命令用于监视当前由 Linux 内核管理的各个任务(来源:官方网站[4])。
- 命令行选项。有关详细信息,请参见手册页[4 ]。
Board $> pidstat --help
Usage: pidstat [ options ] [ <interval> [ <count> ] ]
Options are:
[ -d ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [ <username> ] ]
[ -u ] [ -V ] [ -v ] [ -w ] [ -C <command> ] [ -G <process_name> ] [ --human ]
[ -p { <pid> [,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]
- 显示所有任务的 CPU 统计信息的基本命令:
Board $> pidstat
Linux 4.14.48 (stm32mp1) 06/18/18 _armv7l_ (2 CPU)
15:58:48 UID PID %usr %system %guest %wait %CPU CPU Command
15:58:48 0 1 0.03 0.12 0.00 0.05 0.14 0 systemd
15:58:48 0 2 0.00 0.00 0.00 0.00 0.00 1 kthreadd
15:58:48 0 7 0.00 0.01 0.00 0.01 0.01 0 ksoftirqd/0
15:58:48 0 8 0.04 0.00 0.00 0.02 0.04 1 rcu_preempt
15:58:48 0 15 0.00 0.01 0.00 0.00 0.01 1 ksoftirqd/1
15:58:48 0 18 0.00 0.00 0.00 0.00 0.00 1 kdevtmpfs
15:58:48 0 19 0.00 0.00 0.00 0.00 0.00 0 kworker/0:1
15:58:48 0 72 0.00 0.00 0.00 0.00 0.00 0 irq/82-mfx
15:58:48 0 77 0.00 0.06 0.00 0.01 0.06 1 mmcqd/0
15:58:48 0 83 0.00 0.00 0.00 0.00 0.00 0 mmcqd/1
15:58:48 0 85 0.00 0.00 0.00 0.00 0.00 0 mmcqd/1boot0
15:58:48 0 86 0.00 0.00 0.00 0.00 0.00 0 mmcqd/1boot1
15:58:48 0 91 0.00 0.63 0.00 0.00 0.63 0 kmemleak
15:58:48 0 93 0.00 0.00 0.00 0.00 0.00 0 kworker/0:3
15:58:48 0 95 0.00 0.01 0.00 0.00 0.01 1 irq/73-5a001000
15:58:48 0 98 0.00 0.00 0.00 0.00 0.00 0 kworker/0:1H
15:58:48 0 99 0.00 0.00 0.00 0.00 0.00 1 kworker/1:1H
15:58:48 0 100 0.00 0.00 0.00 0.00 0.00 0 jbd2/mmcblk0p5-
15:58:48 0 150 0.01 0.02 0.00 0.02 0.02 0 systemd-journal
15:58:48 0 189 0.01 0.01 0.00 0.03 0.01 1 systemd-udevd
15:58:48 0 201 0.00 0.00 0.00 0.00 0.00 0 kworker/u4:2
15:58:48 993 203 0.01 0.09 0.00 0.00 0.11 1 systemd-timesyn
15:58:48 998 273 0.09 0.04 0.00 0.02 0.14 0 avahi-daemon
15:58:48 0 276 0.00 0.00 0.00 0.00 0.00 1 systemd-logind
15:58:48 0 277 0.00 0.00 0.00 0.00 0.00 1 klogd
15:58:48 996 279 0.00 0.00 0.00 0.00 0.00 0 dbus-daemon
15:58:48 0 301 0.00 0.00 0.00 0.00 0.00 1 syslogd
15:58:48 992 312 0.00 0.00 0.00 0.00 0.00 1 systemd-network
15:58:48 0 314 0.00 0.00 0.00 0.00 0.00 0 weston-launch
15:58:48 0 319 0.01 0.01 0.00 0.00 0.01 1 weston
15:58:48 991 324 0.00 0.00 0.00 0.00 0.00 0 systemd-resolve
15:58:48 0 327 0.03 0.03 0.00 0.00 0.05 0 tcf-agent
15:58:48 0 332 0.00 0.00 0.00 0.00 0.00 1 login
15:58:48 0 333 0.00 0.00 0.00 0.00 0.00 0 agetty
15:58:48 997 334 0.00 0.00 0.00 0.00 0.00 1 named
15:58:48 0 340 0.00 0.00 0.00 0.00 0.00 0 weston-keyboard
15:58:48 0 342 0.01 0.00 0.00 0.00 0.01 0 weston-desktop-
15:58:48 0 345 0.00 0.01 0.00 0.00 0.01 1 systemd
15:58:48 0 350 0.00 0.00 0.00 0.00 0.00 0 sh
15:58:48 0 374 0.02 0.00 0.00 0.00 0.02 1 kworker/1:1
15:58:48 0 420 0.00 0.00 0.00 0.00 0.00 1 kworker/1:0
15:58:48 0 423 0.00 0.00 0.00 0.00 0.00 1 kworker/1:2
15:58:48 0 424 0.00 0.00 0.00 0.00 0.00 1 pidstat
- 基本命令,以一秒为间隔显示系统中每个活动任务的 3 个 CPU 统计信息报告:
Board $> pidstat 1 3
Linux 4.14.48 (stm32mp1) 06/18/18 _armv7l_ (2 CPU)
15:59:56 UID PID %usr %system %guest %wait %CPU CPU Command
15:59:57 0 426 3.67 4.59 0.00 0.00 8.26 1 pidstat
15:59:57 UID PID %usr %system %guest %wait %CPU CPU Command
15:59:58 0 426 0.99 6.93 0.00 0.00 7.92 1 pidstat
15:59:58 UID PID %usr %system %guest %wait %CPU CPU Command
15:59:59 0 15 0.00 0.99 0.00 0.00 0.99 1 ksoftirqd/1
15:59:59 0 426 1.98 5.94 0.00 0.99 7.92 1 pidstat
Average: UID PID %usr %system %guest %wait %CPU CPU Command
Average: 0 15 0.00 0.32 0.00 0.00 0.32 - ksoftirqd/1
Average: 0 426 2.25 5.79 0.00 0.32 8.04 - pidstat
- 基本命令,用于报告具有所有关联线程的特定进程的统计信息:
Board $> pidstat -t -p `pidof weston-launch`
Linux 4.14.48 (stm32mp1) 06/18/18 _armv7l_ (2 CPU)
16:00:59 UID TGID TID %usr %system %guest %wait %CPU CPU Command
16:00:59 0 314 - 0.00 0.00 0.00 0.00 0.00 0 weston-launch
16:00:59 0 - 314 0.00 0.00 0.00 0.00 0.00 0 |__weston-launch
使用sar
- sar 命令收集,报告或保存系统活动信息(来源:官方网站[5])。
- 命令行选项。有关详细信息,请参见手册页[5 ]。
Board $> sar --help
Usage: sar [ options ] [ <interval> [ <count> ] ]
Options are:
[ -A ] [ -B ] [ -b ] [ -C ] [ -D ] [ -d ] [ -F [ MOUNT ] ] [ -H ] [ -h ]
[ -p ] [ -q ] [ -r [ ALL ] ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ]
[ -v ] [ -W ] [ -w ] [ -y ] [ --human ] [ --sadc ]
[ -I { <int_list> | SUM | ALL } ] [ -P { <cpu_list> | ALL } ]
[ -m { <keyword> [,...] | ALL } ] [ -n { <keyword> [,...] | ALL } ]
[ -j { ID | LABEL | PATH | UUID | ... } ]
[ -f [ <filename> ] | -o [ <filename> ] | -[0-9]+ ]
[ -i <interval> ] [ -s [ <hh:mm[:ss]> ] ] [ -e [ <hh:mm[:ss]> ] ]
- 活动报告的主要使用选项:
sar选项 | 描述 |
---|---|
-u | 所有CPU的CPU利用率 |
-P | 单个CPU或核心的 CPU利用率 |
-r | 内存利用率统计 |
-S | 交换空间利用率的统计信息 |
-b | I/O和传输率统计 |
-F | 当前已挂载文件系统的统计信息 |
-d | 单个块设备I/O的活动 |
-w | 任务创建和系统切换活动 |
-q | 有关任务运行队列和平均负载的信息 |
-n | 网络活动统计 |
-B | 报告分页统计 |
交互模式
- 两种使用 sar 的模式:
- 交互模式(在此处详细介绍):sar由用户使用控制台上的命令行启动
- 非交互模式(在详细走得更远章):SAR由脚本启动((/usr/lib/sa/sa1,这是SYSSTAT工具套件的一部分),可以通过调度守护比如 cron 来管理[6 ]
- 一旦存在 [<interval> [<count>]] 参数,便会使用交互模式,否则将使用非交互模式。在交互模式下,通过考虑这些值可立即执行命令。
- 例如,要获得所有 CPU 的 CPU 利用率情况,每3秒5次统计一次:
Board $> sar -u 3 5
Linux 4.14.48 (stm32mp1) 06/18/18 _armv7l_ (2 CPU)
12:30:20 CPU %user %nice %system %iowait %steal %idle
12:30:23 all 0.00 0.00 0.50 0.00 0.00 99.50
12:30:26 all 0.00 0.00 0.50 0.00 0.00 99.50
12:30:29 all 0.17 0.00 0.17 0.00 0.00 99.67
12:30:32 all 0.66 0.00 2.49 0.00 0.00 96.84
12:30:35 all 0.33 0.00 3.16 0.00 0.00 96.51
Average: all 0.23 0.00 1.36 0.00 0.00 98.41
- -o <filename> 可用于以二进制格式将信息存储到文件中,稍后可使用 sadf 进行读取。
使用sadf
- SADF命令用于显示由所述SAR命令创建的数据文件的内容(来源:官方网站[7 ]):SAR中使用交互模式 -o 选项在非交互式模式中创建,或文件的 /var/log/sa/ 目录。
- 命令行选项。有关详细信息,请参见手册页[7 ]。
Board $> sadf --help
Usage: sadf [ options ] [ <interval> [ <count> ] ] [ <datafile> | -[0-9]+ ]
Options are:
[ -C ] [ -c | -d | -g | -j | -p | -r | -x ] [ -H ] [ -h ] [ -T | -t | -U ] [ -V ]
[ -O <opts> [,...] ] [ -P { <cpu> [,...] | ALL } ]
[ -s [ <hh:mm[:ss]> ] ] [ -e [ <hh:mm[:ss]> ] ]
[ -- <sar_options> ]
- 活动报告的主要使用格式:
sadf选项 | 描述 |
---|---|
-d | 以一种关系数据库系统可以轻松提取的格式打印数据文件的内容。输出由以分号(即MSExcel)分隔的字段组成 |
-G | 从v11.3.1起,以SVG(可缩放矢量图形)格式打印数据文件的内容。使用以下语法: Board $> sadf -g sar_datafile [-<sar_options>]> output.svg 请注意提供正确的sar_options,即,在检查你存利用率时,必须在命令中给出“--r”。 |
-j | 以JSON(JavaScript Object Notation)格式打印数据文件的内容 |
-t | 以数据文件创建者的原始本地时间而不是UTC(世界标准时间)显示时间戳 |
-X | 以XML格式打印数据文件的内容 |
深入学习
使用 sar 非交互模式
- 在非交互方式下,调度程序守护程序用于计划活动记录。
- 推荐的环境是使用cron [6 ]守护程序以及安装该工具套件时出现的 syssta t脚本 /usr/lib/sa/sa1 。有关详细信息,请参见sa1网页[8 ]。
-
cron默认情况下未安装,并且是要集成的 cronie yocto 软件包的一部分:
- 使用 STM32MPU 嵌入式软件发行版的发行包(st-image-weston):
PC $> echo 'IMAGE_INSTALL_append += "cronie"' >> meta-st/meta-st-openstlinux/recipes-st/images/st-image-weston.bbappend
- 然后重建 st-image-weston 镜像。
格式化要在 MS-Excel 中导入的数据
- 使用 sar 命令获取所有 CPU 的使用率,将数据格式化为半列文本,然后使用 MS-Excel 绘制图形的示例:
- 记录CPU使用情况数据(每3秒间隔10次迭代)
Board $> sar -u 3 10 -o test
Linux 4.14.48 (stm32mp1) 06/18/18 _armv7l_ (2 CPU)
13:03:26 CPU %user %nice %system %iowait %steal %idle
13:03:29 all 4.82 0.00 3.16 0.66 0.00 91.36
13:03:32 all 3.82 0.00 3.49 0.00 0.00 92.69
13:03:35 all 18.77 0.00 7.81 5.81 0.00 67.61
13:03:38 all 11.96 0.00 4.98 0.00 0.00 83.06
13:03:41 all 36.21 0.00 8.97 0.00 0.00 54.82
13:03:44 all 1.50 0.00 1.66 0.83 0.00 96.01
13:03:47 all 1.00 0.00 1.83 1.33 0.00 95.85
13:03:50 all 9.63 0.00 4.82 0.00 0.00 85.55
13:03:53 all 3.49 0.00 5.32 0.00 0.00 91.20
13:03:56 all 4.15 0.00 4.98 4.65 0.00 86.21
Average: all 9.53 0.00 4.70 1.33 0.00 84.44
- 测试文件也会创建(二进制格式)。
- 从测试文件创建可读的报告格式,即半列格式,可以将其导入 MSExcel 图形:
Board $> sadf -d test > test.cvs
Board $> cat test.cvs
# hostname;interval;timestamp;CPU;%user;%nice;%system;%iowait;%steal;%idle
stm32mp1;3;2018-06-18 13:03:29 UTC;-1;4.82;0.00;3.16;0.66;0.00;91.36
stm32mp1;3;2018-06-18 13:03:32 UTC;-1;3.82;0.00;3.49;0.00;0.00;92.69
stm32mp1;3;2018-06-18 13:03:35 UTC;-1;18.77;0.00;7.81;5.81;0.00;67.61
stm32mp1;3;2018-06-18 13:03:38 UTC;-1;11.96;0.00;4.98;0.00;0.00;83.06
stm32mp1;3;2018-06-18 13:03:41 UTC;-1;36.21;0.00;8.97;0.00;0.00;54.82
stm32mp1;3;2018-06-18 13:03:44 UTC;-1;1.50;0.00;1.66;0.83;0.00;96.01
stm32mp1;3;2018-06-18 13:03:47 UTC;-1;1.00;0.00;1.83;1.33;0.00;95.85
stm32mp1;3;2018-06-18 13:03:50 UTC;-1;9.63;0.00;4.82;0.00;0.00;85.55
stm32mp1;3;2018-06-18 13:03:53 UTC;-1;3.49;0.00;5.32;0.00;0.00;91.20
stm32mp1;3;2018-06-18 13:03:56 UTC;-1;4.15;0.00;4.98;4.65;0.00;86.21
参考
- 1. http://sebastien.godard.pagesperso-orange.fr/
- 2. http://sebastien.godard.pagesperso-orange.fr/man_iostat.html
- 3. http://sebastien.godard.pagesperso-orange.fr/man_mpstat.html
- 4. http://sebastien.godard.pagesperso-orange.fr/man_pidstat.html
- 5. http://sebastien.godard.pagesperso-orange.fr/man_sar.html
- 6. https://en.wikipedia.org/wiki/Cron
- 7. http://sebastien.godard.pagesperso-orange.fr/man_sadf.html
- 8. http://sebastien.godard.pagesperso-orange.fr/man_sa1.html
文件链接 | 文件类型 | 描述 |
---|---|---|
sysstat文档 | 标准 | Sebastien GODARD的官方网页 |
sysstat教程 | 用户指南 | Sebastien GODARD的官方网页 |
sysstat的git | 资料来源 | Sysstat github |
警告:显示的标题“top命令”重写了此前显示的标题“Sysstat工具套件”。
Trace and debug overview per Linux software frameworks
The picture below allows accessing to different Linux software frameworks which provide specific trace and debug information in their "How to trace and debug the framework" dedicated chapter.
错误: 图像不正确或者不存在
Documentation and web articles
A lot of articles on the web mention Linux® kernel tracing and profiling. The following links provide a good introduction to these topics:
- Linux Performance Analysis - New Tools and Old Secrets: description of the Linux® technology and of the different tools available.
- Yocto project: Tracing and profiling: How to enable tracing and profiling tools using Yocto
- Brendan Gregg Linux performance page
More general Linux performance information are available in nice slideshare presentation (Brendan Gregg), on the Brendan Gregg official web site or in LinuxCon2014 article. |
Reference list: