top命令

来自百问网嵌入式Linux wiki

目录

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:

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:

Yes: this tool is either present (ready to use or to be activated), or can be integrated and activated on the software package.

No: 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
YesNoYesNoNoNo 本文提供了开始使用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手册页。

参考资源

链接地址 文件类型 描述
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_filterftrace_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参数来更新内核命令行:
- 功能跟踪器模式
	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与日志查看器关联。

参考

  • 有用的外部链接
文件链接 文件类型 描述
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.
No* YesNo** NoNoNo * 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

Warning.png

{{#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

参考

  1. https://linux.die.net/man/8/ifconfig
  2. https://tty1.net/blog/2010/ifconfig-ip-comparison_en.html

警告:显示的标题“IP Linux命令行”重写了此前显示的标题“块跟踪器”。

本文提供了开始使用Linux内核工具ip [6]所需的基本信息。

简介

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]

简介

kmemleak[1]提供了一种与跟踪垃圾收集器类似的方法来检测可能的内核内存泄漏,不同之处在于,不释放孤立对象,而仅通过/sys/kernel/debug/kmemleak报告。

警告:显示的标题“Trace-cmd和kernelshark跟踪查看器”重写了此前显示的标题“IP Linux命令行”。


Ltrace

文章目的

本文提供了开始使用Linux工具所需的基本信息:ltrace [1 ]。

简介

下表简要介绍了该工具及其可用性,具体取决于软件包:
  • 是:该工具已经存在(可以使用或激活),也可以在软件包中集成和激活。
  • 没有:该工具不存在且无法集成,或者存在但无法在软件包中激活。
工具
名称 类别 目的
ltrace 追踪工具 ltrace [1 ]用于显示对用户空间应用程序进行的共享库的调用。ltrace是一个用户空间应用程序。它的用法与strace 非常相似。
STM32MPU嵌入式软件发行版
入门资料包 开发者资料包 发行版资料包
没有 没有
适用于 Android 的STM32MPU嵌入式软件发行版
入门资料包 开发者资料包 发行版资料包
没有 没有 没有


在目标板上安装跟踪和调试工具

使用STM32MPU嵌入式软件发行版

模板:Redtex

分发包

要将 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 ]。

参考

1. https://www.ltrace.org/
2. http://man7.org/linux/man-pages/man1/ltrace.1.html
  • 有用的外部链接
文件链接 文件类型 描述
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数据分析.

Perf 002.png

火焰图是使用火焰图工具套件生成[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


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

参考

1. https://strace.io/
2. http://man7.org/linux/man-pages/man1/strace.1.html
  • 有用的外部链接
文件链接 文件类型 描述
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

参考

http://www.sysprof.com/
  • 有用的外部链接
文件连结 文件类型 描述
来自GNOME的Sysprof 标准 维基页面
使用Sysprof进行性能分析 用户手册 Linux.com

警告:显示的标题“Sysstat工具套件”重写了此前显示的标题“Trace-cmd和kernelshark跟踪查看器”。


Sysstat工具套件

文章目的

本文提供了开始使用sysstat [1 ]工具套件所需的基本信息,该工具套件提供了一系列Linux工具:
  • 主要工具:iostat,mpstat和pidstat
  • 其他工具:sar,sadf

简介

下表简要介绍了该工具及其可用性,具体取决于软件包:
  • 是:该工具已经存在(可以使用或激活),也可以在软件包中集成和激活。
  • 没有:该工具不存在且无法集成,或者存在但无法在软件包中激活。
工具
名称 类别 目的
系统状态 监控工具 所述SYSSTAT [1 ]工具套件中含有用来监视系统的性能和使用活动。它包含许多商业Unix发行版共有的各种实用程序,以及可以进行计划的工具(通过诸如cron这样的计划程序)来收集和历史化性能和活动数据的工具:
  • iostat:报告块设备和分区的 CPU统计信息以及输入/输出统计信息。
  • mpstat:报告单个或组合的处理器相关统计信息。
  • pidstat:报告Linux任务(进程)的统计信息:I/O, CPU,你存等。
  • sar:收集,报告和保存系统活动信息( CPU,你存,磁盘,中断,网络接口, TTY,内核表等)
  • sadf:以多种格式(CSV,XML,JSON等)显示sar收集的数据。此命令还可以用于与其他程序交换数据,或绘制图形来说明sar使用SVG(可缩放矢量图形)格式收集的各种活动。
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
800px

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:

Info.png 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: