Buildroot:Debugging, profiling and benchmark(3)
11 latencytop
使用latencytop需要打开内核CONFIG_LATENCYTOP:
Kernel hacking
->Latency measuring infrastructure
latencytop运行结果:
LatencyTOP version 0.5 (C) 2008 Intel Corporation Cause Maximum Percentage--统计系统延迟信息:延迟原因、最大延迟时间、每种延迟占总延迟百分比。 Userspace lock contention 0.4 msec 100.0 % Process tcf-agent (110) Total: 0.9 msec--特定进程延迟信息:进程名、总延迟时间、延迟原因、该原因最大延迟时间、该延迟占总延迟百分比。 Userspace lock contention 0.4 msec 100.0 % jbd2/vda-8 kworker/R-ext4- syslogd klogd udhcpc crond sshd tcf-agent--进程列表,可左右方向键选择。
12 lsof
lsof是一个强大的命令行工具,用于列出打开的文件描述符。在Unix和类Unix操作系统中,一切皆文件,所以lsof可以用来查看打开的文件、目录、网络文件系统、流管道、设备文件等。以下是lsof的一些常用用法和选项:
基本用法
- 查看所有打开的文件: lsof
- 查看特定用户打开的文件: lsof -u username
- 查看特定进程打开的文件: lsof -p PID
- 查看特定文件被哪些进程打开: lsof /path/to/file
网络相关用法
- 查看所有网络连接: lsof -i
- 查看TCP网络连接: lsof -i tcp
- 查看UDP网络连接: lsof -i udp
- 查看特定端口的网络连接: lsof -i :port
- 查看特定服务的网络连接: lsof -i @hostname
其他常用选项
- 显示进程信息: lsof -p PID
- 显示进程和文件的详细信息: lsof -p PID -d FD
- 显示所有进程打开的特定类型的文件: lsof +M /path/to/directory
- 显示所有打开标准输入(stdin)的进程: lsof /dev/stdin
- 显示所有打开特定程序的文件描述符: lsof -c program_name
组合选项
lsof的选项可以组合使用,以提供更具体的输出。例如,要查看特定用户的所有网络连接,可以使用:lsof -i -u username
注意事项
- lsof需要root权限才能查看系统中所有进程打开的文件。
- 在某些情况下,lsof可能无法显示由内核直接打开的文件,或者某些特殊类型的文件。
- lsof的输出可以非常大,因此通常需要结合管道(如grep)来过滤结果。
lsof -H输入如下:
1. COMMAND:进程的名称。
2. PID:进程的ID。
3. TID:线程的ID。在Linux中,TID(Thread ID)通常与PID相同,因为`lsof`在某些系统上可能不显示线程ID。
4. TASKCMD:命令行参数,显示启动进程的完整命令行。
5. USER:拥有该文件描述符的进程的用户。
6. FD:文件描述符,表示进程中文件的标识符,如0u(标准输入)、1u(标准输出)、2u(标准错误输出)等。`r`表示只读,`w`表示只写,`u`表示可读写。
7. TYPE:文件类型,如DIR(目录)、REG(常规文件)、CHR(字符设备)、BLK(块设备)、FIFO(管道/FIFO)、UNIX(Unix域套接字)等。
8. DEVICE:文件所在的设备,格式为`MAJOR,MINOR`。例如,`254,0`表示设备号为254的设备。
9. SIZE/OFF:文件的大小或偏移量。对于目录和某些类型的文件,这可能显示为`0B`或`0t0`,表示大小为0或偏移量为0。
10. NODE:文件在文件系统中的索引节点号。
11. NAME:文件的路径名。
lsof -H COMMAND PID TID TASKCMD USER FD TYPE DEVICE SIZE/OFF NODE NAME init 1 root cwd DIR 254,0 4.0K 2 / init 1 root rtd DIR 254,0 4.0K 2 / init 1 root txt REG 254,0 794.4K 18 /bin/busybox init 1 root mem REG 254,0 1.5M 190 /lib/libc.so.6 init 1 root mem REG 254,0 58.0K 199 /lib/libresolv.so.2 init 1 root mem REG 254,0 161.9K 1074 /usr/lib/libtirpc.so.3.0.0 init 1 root mem REG 254,0 190.1K 185 /lib/ld-linux-aarch64.so.1 init 1 root 0u CHR 5,1 0t0 81 /dev/console init 1 root 1u CHR 5,1 0t0 81 /dev/console init 1 root 2u CHR 5,1 0t0 81 /dev/console ... lsof 241 root cwd DIR 254,0 4.0K 289 /root lsof 241 root rtd DIR 254,0 4.0K 2 / lsof 241 root txt REG 254,0 251.4K 532 /usr/bin/lsof lsof 241 root mem REG 254,0 1.5M 190 /lib/libc.so.6 lsof 241 root mem REG 254,0 161.9K 1074 /usr/lib/libtirpc.so.3.0.0 lsof 241 root mem REG 254,0 190.1K 185 /lib/ld-linux-aarch64.so.1 lsof 241 root 0u CHR 5,1 0t0 13 /dev/console lsof 241 root 1u CHR 5,1 0t0 13 /dev/console lsof 241 root 2u CHR 5,1 0t0 13 /dev/console lsof 241 root 3r DIR 0,15 0B 1 /proc lsof 241 root 4r DIR 0,15 7B 1043 /proc/241/fd lsof 241 root 5w FIFO 0,11 0t0 1048 pipe lsof 241 root 6r FIFO 0,11 0t0 1049 pipe lsof 242 root cwd DIR 254,0 4.0K 289 /root lsof 242 root rtd DIR 254,0 4.0K 2 / lsof 242 root txt REG 254,0 251.4K 532 /usr/bin/lsof lsof 242 root mem REG 254,0 1.5M 190 /lib/libc.so.6 lsof 242 root mem REG 254,0 161.9K 1074 /usr/lib/libtirpc.so.3.0.0 lsof 242 root mem REG 254,0 190.1K 185 /lib/ld-linux-aarch64.so.1 lsof 242 root 0r FIFO 0,11 0t0 1048 pipe lsof 242 root 1w FIFO 0,11 0t0 1049 pipe
13 ltp-testsuite
LTP(Linux Test Project)是一个由SGI、OSDL和Bull发起,并由IBM、思科、富士通、SUSE、红帽、甲骨文等公司开发和维护的联合项目。该项目的目标是向开源社区提供测试,以验证Linux的可靠性、健壮性和稳定性。
14 ltrace
基本用法
- 跟踪一个命令的库函数调用: ltrace <command>
例如,跟踪`ls`命令的库函数调用: ltrace ls
- 将输出重定向到文件: ltrace -o output.txt <command>
例如,将`ls`命令的输出保存到`ls_ltrace.txt`文件中: ltrace -o ls_ltrace.txt ls
- 仅跟踪特定的库函数调用: ltrace -e <library_function> <command>
例如,仅跟踪`ls`命令的`malloc`和`free`函数调用: ltrace -e malloc,free ls
- 跟踪已经运行的进程: ltrace -p <pid>
例如,跟踪进程ID为1234的进程: ltrace -p 1234
- 打印每个库函数调用的执行时间: ltrace -tt <command>
例如,打印`ls`命令的每个库函数调用的时间戳: ltrace -tt ls
07:02:08.189355 __libc_start_main([ "ls" ] <unfinished ...> 07:02:08.201274 mallopt(0xffffffff, 8192, 0x7fe7effcd8, 0x555c135554) = 1 07:02:08.203932 mallopt(0xfffffffd, 0x7f00, 1, 0x7f8e176ad8) = 1 ...07:02:08.291628 exit(0 <unfinished ...> 07:02:08.292759 __cxa_finalize(0x555c1ef000, 0x555c134df0, 1, 568) = 1 07:02:08.295229 +++ exited (status 0) +++
- 统计库函数调用: ltrace -c <command>
例如,统计`ls`命令的库函数调用,并显示调用次数和执行时间: ltrace -c ls
% time seconds usecs/call calls function ------ ----------- ----------- --------- -------------------- 57.66 0.057093 57093 1 __libc_start_main 5.08 0.005034 719 7 strlen 4.56 0.004516 752 6 strcmp ... 0.71 0.000702 702 1 gnu_dev_minor 0.70 0.000696 696 1 gnu_dev_major 0.60 0.000593 593 1 exit_group ------ ----------- ----------- --------- -------------------- 100.00 0.099010 49 total
15 lttng-babeltrace、lttng-modules、lttng-tools
lttng-babeltrace、lttng-modules 和 lttng-tools 是 LTTng 项目中的三个主要组件,它们各自有不同的作用:
1. lttng-tools:
- lttng-tools 提供了控制跟踪的库和命令行接口。
- 它包括会话守护进程(lttng-sessiond)、消费者守护进程(lttng-consumerd)、中继守护进程(lttng-relayd)、跟踪控制库(liblttng-ctl)以及跟踪控制命令行工具(lttng)。
- 这些工具允许用户创建跟踪会话、启用和禁用跟踪事件规则、过滤事件以及启动和停止跟踪。
2. lttng-modules:
- lttng-modules 包含了用于跟踪 Linux 内核的内核模块。
- 这些模块包括探针模块,它们附加到 Linux 内核的特定子系统上,使用追踪点(tracepoints)作为仪器点。
- 还包括环形缓冲区模块,LTTng 内核跟踪器将数据写入环形缓冲区,消费者守护进程从这些缓冲区读取数据。
- lttng-modules 使得 LTTng 能够捕获内核级别的跟踪信息,对于调试和性能分析至关重要。
3. lttng-babeltrace:
- lttng-babeltrace 是一个项目,允许将追踪信息翻译成用户可读的日志,并提供读取追踪库 libbabeltrace。
- 它用于分析 LTTng 产生的跟踪数据,并将这些数据转换成可读的格式,便于用户分析和理解跟踪结果。
- babeltrace 是 LTTng 生态系统的一部分,它处理跟踪数据的读取和分析,使得用户可以更直观地查看跟踪结果。
这三个组件共同构成了 LTTng 跟踪框架,使得用户能够对 Linux 内核和用户空间应用程序进行详细的跟踪和分析。
16 mbw
mbw是一个测量内存带宽的工具,可以测试不同内存拷贝方法的性能。
memcpy、dumb和mcblock是三种不同的内存拷贝方法,它们在实现和性能上有所区别:
1. memcpy:
- memcpy是一个标准库函数,用于从源地址拷贝指定字节数的数据到目标地址。它是最常用的内存拷贝函数,因为它是经过优化的,可以利用现代CPU的SIMD指令集(如SSE、AVX)来加速拷贝过程。
- memcpy不会处理内存重叠的情况,如果源内存和目标内存有重叠,结果将是未定义的。
- 它的主要优点是高效和简单,但缺点是缺乏灵活性,无法在拷贝过程中进行其他操作。
2. dumb:
- dumb方法通常指的是一个简单的、逐字节拷贝的实现,类似于手动循环复制。这种方法通常不使用任何优化技术,如SIMD指令集,因此可能比memcpy慢。
- dumb方法的灵活性较高,因为它可以在拷贝过程中添加额外的逻辑,例如数据转换或过滤。
- 它的优点是灵活,可以在复制过程中进行其他操作,但缺点是效率较低,特别是在处理大量数据时。
3. mcblock:
- mcblock方法指的是以固定块大小进行内存拷贝的测试。这种方法通常涉及到将大块数据分成小块,然后逐块拷贝,这可以提高某些情况下的缓存效率。
- mcblock可能会使用一些优化技术,比如预取(prefetching)来提前加载数据到缓存中,以提高拷贝速度。
- 它的优点是可能比简单的逐字节拷贝更快,尤其是在处理大块数据时,但缺点是实现可能更复杂。
总结来说,memcpy是最优化的内存拷贝方法,适用于非重叠内存的高效拷贝;dumb方法提供了更大的灵活性,但效率较低;而mcblock则是一种可能通过块处理和预取优化的拷贝方法,适用于大块数据的拷贝。
mbw -n 100 10 Long uses 8 bytes. Allocating 2*1310720 elements = 20971520 bytes of memory. Using 262144 bytes as blocks for memcpy block copy test. Getting down to business... Doing 100 runs per test. 0 Method: MEMCPY Elapsed: 0.00692 MiB: 10.00000 Copy: 1446.132 MiB/s 1 Method: MEMCPY Elapsed: 0.00627 MiB: 10.00000 Copy: 1594.642 MiB/s ...
98 Method: MEMCPY Elapsed: 0.00558 MiB: 10.00000 Copy: 1791.152 MiB/s 99 Method: MEMCPY Elapsed: 0.00723 MiB: 10.00000 Copy: 1383.700 MiB/s AVG Method: MEMCPY Elapsed: 0.00665 MiB: 10.00000 Copy: 1504.212 MiB/s 0 Method: DUMB Elapsed: 0.00752 MiB: 10.00000 Copy: 1329.080 MiB/s 1 Method: DUMB Elapsed: 0.00662 MiB: 10.00000 Copy: 1509.662 MiB/s ...
98 Method: DUMB Elapsed: 0.00660 MiB: 10.00000 Copy: 1515.152 MiB/s 99 Method: DUMB Elapsed: 0.00746 MiB: 10.00000 Copy: 1339.944 MiB/s AVG Method: DUMB Elapsed: 0.00752 MiB: 10.00000 Copy: 1330.038 MiB/s 0 Method: MCBLOCK Elapsed: 0.00840 MiB: 10.00000 Copy: 1190.902 MiB/s 1 Method: MCBLOCK Elapsed: 0.00604 MiB: 10.00000 Copy: 1654.533 MiB/s ...
98 Method: MCBLOCK Elapsed: 0.00681 MiB: 10.00000 Copy: 1468.213 MiB/s 99 Method: MCBLOCK Elapsed: 0.00583 MiB: 10.00000 Copy: 1714.090 MiB/s AVG Method: MCBLOCK Elapsed: 0.00679 MiB: 10.00000 Copy: 1473.192 MiB/s
17 memstat
memstat是一个用于观测系统内存使用状况的工具,它通过遍历/proc下所有进程,然后解析内存使用情况。
memstat 的输出分为两部分:进程视角和文件视角。
进程视角:第一列为内存占用,随后的数字是使用这个共享库进程的 PID,最后是可执行文件的完整路径。
文件视角:第一列为内存占用,然后是库文件或可执行文件路径,最后是使用到的进程PID。
在memstat的输出中,括号中的大小通常表示的是共享库的实际内存占用和共享内存占用的总和。这里的两个数字分别代表:
1. 括号外的数字:表示该共享库或可执行文件在所有进程中的总内存占用量,包括了所有进程对该共享库的内存占用。
2. 括号内的数字:表示该共享库或可执行文件在所有进程中的共享内存占用量,即被多个进程共享的内存部分。
例如,如果输出显示为 784k( 760k),这意味着:
- 784k:该共享库在所有使用它的进程中的总内存占用为 784KB。
- 760k:其中,760KB 是被多个进程共享的内存部分。
这种表示方法有助于区分共享库的总内存占用和共享内存占用,从而更准确地了解内存使用情况。共享内存占用量较大意味着多个进程共享了相同的内存区域,这可以减少内存的总占用,提高内存使用效率。
memstat -w -n 352k: PID 1 (/bin/busybox) 352k: PID 56 (/bin/busybox) 352k: PID 60 (/bin/busybox) 352k: PID 100 (/bin/busybox) 352k: PID 105 (/bin/busybox) 352k: PID 106 (/bin/busybox) 340k: PID 113 (/usr/bin/memstat) 1032k( 936k): /bin/busybox 1 56 60 100 105 106 1 56 60 100 105 106 1 56 60 100 105 106 268k( 156k): /lib/ld-linux-riscv64-lp64d.so.1 1 56 60 100 105 106 113 1 56 60 100 105 106 113 1 56 60 100 105 106 113 1788k( 1648k): /lib/libc.so.6 1 56 60 100 105 106 113 1 56 60 100 105 106 113 1 56 60 100 105 106 113 96k( 48k): /lib/libresolv.so.2 1 56 60 100 105 106 1 56 60 100 105 106 1 56 60 100 105 106 20k( 12k): /usr/bin/memstat 113 -------- 5656k ( 2800k)
18 nmon
nmon(Nigel's Monitor)是一个由IBM提供的开源工具,用于监控Linux和AIX系统的资源消耗情况。更多参考《nmon_analyser: A free tool for producing AIX performance reports - IBM Developer》。
1 nmon的作用:
1. 实时监控:nmon可以在系统运行过程中实时捕捉系统资源的使用情况。
2. 数据记录:nmon能将监控数据输出到文件中,方便后续分析。
3. 图形化结果:通过nmon_analyzer工具,可以将数据文件转换成图形化结果,便于分析和理解。
2 nmon可以检测的内容:
1. CPU占用率:监控CPU的使用情况。
2. 内存使用情况:包括物理内存和虚拟内存的使用。
3. 磁盘I/O速度、传输和读写比率:监控磁盘的I/O性能。
4. 文件系统的使用率:检查文件系统的剩余空间。
5. 网络I/O速度、传输和读写比率、错误统计率与传输包的大小:监控网络接口的性能。
6. 消耗资源最多的进程:识别消耗最多资源的进程。
7. 计算机详细信息和资源:提供服务器的详细信息和资源使用情况。
8. 页面空间和页面I/O速度:监控与页面置换相关的性能指标。
9. 用户自定义的磁盘组:允许用户监控自定义的磁盘组。
10. 网络文件系统(NFS):监控NFS的性能和使用情况。
3 如何检测并解读nmon数据:
1. 运行nmon:在命令行中输入nmon启动工具,进入交互式界面。
2. 使用快捷键:在nmon的交互式界面中,可以使用快捷键来显示不同的系统资源统计数据,例如:
- c:查看CPU统计数据。
- m:查看内存统计数据。
- d:查看硬盘统计数据。
- n:查看网络统计数据。
- t:查看高耗进程。
- q:退出nmon。
3. 数据采集:使用命令行参数来采集数据,例如:
- -f:生成文件,文件名=主机名+当前时间.nmon。
- -s:设置采样间隔,例如-s 10表示每隔10秒采集一次数据。
- -c:设置采样次数,例如-c 60表示总共采集60次数据。
- -m:指定文件保存目录。
4. 解读性能数据:nmon的数据可以通过nmon_analyzer工具进行图形化分析,这有助于更直观地理解性能数据。例如,SYS_SUMM展示CPU和IO的总体使用情况,CPU_ALL展示CPU的总体使用情况,DISK_SUMM展示每秒磁盘读写和总读写大小等。
通过这些方法,nmon为用户提供了一个全面而强大的系统资源监控解决方案。
下载nmon-analyzer《nmon and njmon | Site / Nmon-Analyser》。
生成nmon数据:nmon -f -s 10 -c 60,然后用nmon_analyser解析:
解析结果:
19 netsniff-ng
netsniff-ng
是一个高性能的 Linux 网络分析工具包,它为网络开发者和系统管理员提供了强大的网络调试和分析功能。
sudo netsniff-ng Running! Hang up with ^C! < eno1 60 1734765792s.519130964ns #1 [ Eth MAC (70:b5:e8:59:d4:95 => a4:bb:6d:e2:35:df), Proto (0x0800, IPv4) ] [ Vendor (Unknown => Unknown) ] [ Eth trailer 0008600 ] [ IPv4 Addr (172.16.220.30 => 172.16.220.38), Proto (6), TTL (128), TOS (0), Ver (4), IHL (5), Tlen (40), ID (30679), Res (0), NoFrag (1), MoreFrag (0), FragOff (0), CSum (0x7292) is ok ] [ TCP Port (52374 => 22 (ssh)), SN (0xf4fa2532), AN (0xc68788f7), DataOff (5), Res (0), Flags (ACK), Window (8191), CSum (0x4916), UrgPtr (0) ] > eno1 134 1734765792s.528054367ns #2 [ Eth MAC (a4:bb:6d:e2:35:df => 70:b5:e8:59:d4:95), Proto (0x0800, IPv4) ] [ Vendor (Unknown => Unknown) ] [ IPv4 Addr (172.16.220.38 => 172.16.220.30), Proto (6), TTL (64), TOS (16), Ver (4), IHL (5), Tlen (120), ID (24592), Res (0), NoFrag (1), MoreFrag (0), FragOff (0), CSum (0xc9f9) is ok ] [ TCP Port (22 (ssh) => 52374), SN (0xc68788f7), AN (0xf4fa2532), DataOff (5), Res (0), Flags (PSH ACK), Window (543), CSum (0x10d1), UrgPtr (0) ] [ Chr ..Y}L.]n..&w.v..7......w.C..B\.e.Q...."S..(!.6NeL:.1:.............m...N&.8=^.... ] [ Hex 15 bc 59 7d 4c b0 5d 6e e8 d6 26 77 9c 76 04 d6 37 d2 f3 bc 88 fe 1d 77 19 43 e3 a7 42 5c df 65 0e 51 fb ae 93 9a 22 53 c4 fc 28 21 1e 36 4e 65 4c 3a 1c 31 3a 10 1d 0b d2 fe 00 01 9e a4 0b 85 c4 9f 6d ca b5 9d 4e 26 84 38 3d 5e 8e ee 86 a5 ] B eno1 60 1734765792s.553003528ns #3 [ Eth MAC (70:b5:e8:5f:60:3c => ff:ff:ff:ff:ff:ff), Proto (0x0806, ARP) ] [ Vendor (Unknown => Broadcast) ] [ ARP Format HA (1 => Ethernet), Format Proto (0x0800 => IPv4), HA Len (6), Proto Len (4), Opcode (1 => ARP request), Sender MAC (70:b5:e8:5f:60:3c), Sender IP (172.16.220.111), Target MAC (00:00:00:00:00: 00), Target IP (172.16.220.62) ] [ Chr .................. ] [ Hex 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ] < eno1 60 1734765792s.579443071ns #4 [ Eth MAC (70:b5:e8:59:d4:95 => a4:bb:6d:e2:35:df), Proto (0x0800, IPv4) ] [ Vendor (Unknown => Unknown) ] [ Eth trailer 000000 ] [ IPv4 Addr (172.16.220.30 => 172.16.220.38), Proto (6), TTL (128), TOS (0), Ver (4), IHL (5), Tlen (40), ID (30680), Res (0), NoFrag (1), MoreFrag (0), FragOff (0), CSum (0x7291) is ok ] [ TCP Port (52374 => 22 (ssh)), SN (0xf4fa2532), AN (0xc6878947), DataOff (5), Res (0), Flags (ACK), Window (8190), CSum (0x48c7), UrgPtr (0) ] > eno1 166 1734765792s.596046436ns #5 [ Eth MAC (a4:bb:6d:e2:35:df => 70:b5:e8:59:d4:95), Proto (0x0800, IPv4) ] [ Vendor (Unknown => Unknown) ] [ IPv4 Addr (172.16.220.38 => 172.16.220.30), Proto (6), TTL (64), TOS (16), Ver (4), IHL (5), Tlen (152), ID (24593), Res (0), NoFrag (1), MoreFrag (0), FragOff (0), CSum (0xc9d8) is ok ] [ TCP Port (22 (ssh) => 52374), SN (0xc6878947), AN (0xf4fa2532), DataOff (5), Res (0), Flags (PSH ACK),^C Window (543), CSum (0x10f1), UrgPtr (0) ] [ Chr <.D...P....2.R.....v.2.Xu..9....#.......1Rl..i...5...~j...SQB!..q.~..C.......+M....X..3.l.....(.F...1....R..E... ] [ Hex 3c cd 44 9f 8b d1 50 cc 8e fc b5 32 19 52 ef 97 88 eb e2 76 ea 32 b0 58 75 ac ee 39 e5 e2 a9 a8 23 a7 c0 bc d9 ea a8 cc 31 52 6c ae a8 69 db fb ce 35 eb 92 a8 7e 6a 0d 9c a4 53 51 42 21 da 81 71 00 7e d5 05 43 0d db 18 1a 9c a7 fb 2b 4d 9c b7 8f 8b 58 fd b5 33 d8 6c be 96 be 10 fa 28 1d 46 de a9 1d 31 a9 e5 86 a6 52 cf 0d 45 f2 b7 f6 ] 5 packets incoming (130 unread on exit) 135 packets passed filter 0 packets failed filter (out of space) 0.0000% packet droprate 0 sec, 275913 usec in total
20 pv
pv(Pipe Viewer)是一个在Linux系统中用于监控数据流进度的工具,特别适用于那些没有内置进度显示功能的命令。