Linux对机器进行性能分析之CPU篇

前言

平常工作会涉及到一些 Linux 性能分析的问题,因此决定总结一下常用的一些性能分析手段,仅供参考。
说到性能分析,基本上就是 CPU、内存、磁盘 IO 以及网络这几个部分。
已经整理过很多次了但还有地方不熟练,多练习多总结对比!

性能分析之CPU篇

进行性能分析之前,首先得知道 CPU 有哪些信息,可以通过以下方法查看 CPU配置信息。
在这里插入图片描述

cpu基本信息

lscpu

在 Linux 下,类似 lsxxx 这样的命令都是用来查看基本信息的,如 ls 查看当前目录文件信息,lscpu 就用来查看 CPU 信息,类似还有 lspci 查看 PCI 信息。

[root@master ~]# lscpu
Architecture:          x86_64
架构:x86,64位

CPU op-mode(s):        32-bit, 64-bit
支持的模式:32位,64位

Byte Order:            Little Endian
字节排序的模式:小端对齐(即低位字节排放在内存的低地址端,高位字节排放在内存的高地址端)

CPU(s):                1
逻辑CPU数:1

On-line CPU(s) list:   0
在线的cpu数量:0, 有故障或者过热时,某些CPU会停止运行而掉线

Thread(s) per core:    1
每个核心线程:1

Core(s) per socket:    1
每个cpu插槽核数/每颗物理cpu核数:1

Socket(s):             1
cpu插槽数,即物理cpu的数量:1

NUMA node(s):          1
有几个NUMA节点:1

Vendor ID:             GenuineIntel
cpu厂商ID: GenuineIntel

CPU family:            6
厂商设定的CPU家族编号:6

Model:                 142
型号:142

Model name:            Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
型号名称:Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz

Stepping:              12
步进,可以理解为同一型号cpu的版本号:12

CPU MHz:               2304.003
cpu主频:2304.003

BogoMIPS:              4608.00
估算MIPS,   MIPS是每秒百万条指令: 4608.00

Hypervisor vendor:     VMware
虚拟化技术的提供商:VMware

Virtualization type:   full
cpu支持的虚拟化技术的类型:full

L1d cache:             32K
一级高速缓存 dcache 用来存储数据:32k

L1i cache:             32K
一级高速缓存 icache 用来存储指令:32k

L2 cache:              256K
二级缓存:256k

L3 cache:              8192K
三级缓存:8192k

NUMA node0 CPU(s):     0
cpu在同一个numa节点node0上的个数:0

Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid rdseed adx smap clflushopt xsaveopt xsavec arat spec_ctrl intel_stibp flush_l1d arch_capabilities
cpu支持的技术特征: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid rdseed adx smap clflushopt xsaveopt xsavec arat spec_ctrl intel_stibp flush_l1d arch_capabilities
  • 什么是NUMA(Non-Uniform MemoryAccess)?
    中文名:分布式体系结构 (非统一内存体系结构)
    与UMA不同,UMA是统一内存体系结构
    UMA中,多个CPU访问内存是没有区别的,成本和速度相同。
    而在NUMA中,可以看成每个CPU有自己的内存,被称为本地内存,
    CPU之间通过一种方式连结,使得CPU可以访问非管辖范围内的内存(非本地内存)。
    因为需要通过另一个通道获取,速度比访问本地内存要慢。
    好处是这种方式增加了扩展性。
    缺点是速度会受影响,对像mysql这类的数据库软件会有影响。

  • 什么是大小端模式?
    Byte Order: Little Endian
    小端模式:低位的字节存储在地址较小的位置
    大端模式:高位的字节存储在地址较小的位置

  • 查看本地操作系统发行的版本

      [root@master ~]# cat /etc/redhat-release 
      Red Hat Enterprise Linux Server release 7.6 (Maipo)
    

/proc/cpuinfo

/proc 目录是内核透传出来给用户态使用的,里面记录着很多信息文件,比如还有内存文件 meminfo 等。可以使用 cat /proc/cpuinfo 查看 CPU 信息。

[root@master ~]# cat /proc/cpuinfo
processor	: 0
系统中逻辑处理核的编号。对于单核处理器,则可认为是其CPU编号,对于多核处理器则可以是物理核、或者使用超线程技术虚拟的逻辑核

vendor_id	: GenuineIntel
cpu family	: 6
model		: 142
model name	: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
stepping	: 12
microcode	: 0xca
Microcode打补丁是在SRAM上进行的,掉电以后就需要重新打补丁了,也就是说每次重启都要重新打补丁。打补丁的方式也很简单,就是把Microcode放在某个内存中,写个MSR就行了。

cpu MHz		: 2304.001
cache size	: 8192 KB
CPU三级缓存大小:8192 KB

physical id	: 0
单个CPU的标号:0

siblings	: 1
单个CPU逻辑物理核数:1

core id		: 0
当前物理核在其所处CPU中的编号,这个编号不一定连续:0

cpu cores	: 1
该逻辑核所处CPU的物理核数:1

apicid		: 0
用来区分不同逻辑核的编号,系统中每个逻辑核的此编号必然不同,此编号不一定连续

initial apicid	: 0
fpu		: yes
是否具有浮点运算单元(Floating Point Unit):yes

fpu_exception	: yes
是否支持浮点计算异常:yes

cpuid level	: 22
执行cpuid指令前,eax寄存器中的值,根据不同的值cpuid指令会返回不同的内容

wp		: yes
表明当前CPU是否在内核态支持对用户空间的写保护(Write Protection):yes

flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid rdseed adx smap clflushopt xsaveopt xsavec arat spec_ctrl intel_stibp flush_l1d arch_capabilities
bogomips	: 4608.00
clflush size	: 64
cache_alignment	: 64
address sizes	: 43 bits physical, 48 bits virtual
power management:

这里显示的信息可以具体到每个逻辑核上,由于我只有一个核,所以只显示一组信息。

  • CPU,物理核,逻辑核,超线程

    CPU(Central Processing Unit): 中央处理单元,CPU不等于物理核,更不等于逻辑核。
    ==物理核(physical core/processor): == 可以看的到的,真实的cpu核,有独立的电路元件以及L1,L2缓存,可以独立地执行指令。
    逻辑核(logical core/processor,LCPU): 在同一个物理核内,逻辑层面的核。(比喻,像动画片一样,我们看到的“动画”,其实是一帧一帧静态的画面,24帧/s连起来就骗过了人类的眼睛,看起来像动起来一样。逻辑核也一样,物理核通过高速运算,让应用程序以为有两个cpu在运算)。
    超线程(Hyper-threading, HT): 超线程可以在一个逻辑核等待指令执行的间隔(等待从cache或内存中获取下一条指令),把时间片分配到另一个逻辑核。高速在这两个逻辑核之间切换,让应用程序感知不到这个间隔,误认为自己是独占了一个核。
    ==关系: == 一个CPU可以有多个物理核。如果开启了超线程,一个物理核可以分成n个逻辑核,n为超线程的数量。

dmidecode

dmidecode命令 可以让你在Linux系统下获取有关硬件方面的信息。dmidecode的作用是将DMI数据库中的信息解码,以可读的文本方式显示。由于DMI信息可以人为修改,因此里面的信息不一定是系统准确的信息。dmidecode遵循SMBIOS/DMI标准,其输出的信息包括BIOS、系统、主板、处理器、内存、缓存等等。

DMI(Desktop Management Interface,DMI)就是帮助收集电脑系统信息的管理系统,DMI信息的收集必须在严格遵照SMBIOS规范的前提下进行。SMBIOS(System Management BIOS)是主板或系统制造者以标准格式显示产品管理信息所需遵循的统一规范。SMBIOS和DMI是由行业指导机构Desktop Management Task Force(DMTF)起草的开放性的技术标准,其中DMI设计适用于任何的平台和操作系统。

DMI充当了管理工具和系统层之间接口的角色。它建立了标准的可管理系统更加方便了电脑厂商和用户对系统的了解。DMI的主要组成部分是Management Information Format(MIF)数据库。这个数据库包括了所有有关电脑系统和配件的信息。通过DMI,用户可以获取序列号、电脑厂商、串口信息以及其它系统配件信息。

命令 作用
dmidecode # 打印所有硬件信息
dmidecode -q # 打印所有硬件信息,比较简洁
dmidecode grep ‘Product Name’ # 以过滤的方式来查看指定的硬件信息
dmidecode --type bios # 查看BIOS相关的硬件信息
dmidecode --type system # 查看系统相关的硬件信息
dmidecode --type baseboard # 查看主板相关的硬件信息
dmidecode --type chassis # 查看机箱相关的硬件信息
dmidecode --type processor # 查看处理器相关的硬件信息
dmidecode --type memory # 查看内存相关的硬件信息

对于 CPU 信息,可以使用dmidecode -t processor 来查看。

[root@master ~]# dmidecode -t processor
Getting SMBIOS data from sysfs.
SMBIOS 2.7 present.

Handle 0x0004, DMI type 4, 42 bytes
Processor Information
	Socket Designation: CPU #000
	Type: Central Processor
	Family: Unknown
	Manufacturer: GenuineIntel
	ID: EC 06 08 00 FF FB 8B 0F
	Version: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
	Voltage: 3.3 V
	External Clock: Unknown
	Max Speed: 30000 MHz
	Current Speed: 2300 MHz
	Status: Populated, Enabled
	Upgrade: ZIF Socket
	L1 Cache Handle: 0x0094
	L2 Cache Handle: 0x0114
	L3 Cache Handle: Not Provided
	Serial Number: Not Specified
	Asset Tag: Not Specified
	Part Number: Not Specified
	Core Count: 1
	Core Enabled: 1
	Characteristics:
		64-bit capable
		Execute Protection

Handle 0x0004, DMI type 4, 42 bytes
Processor Information
	Socket Designation: CPU #001
	Type: Central Processor
	Family: Unknown
	Manufacturer: GenuineIntel
	ID: EC 06 00 00 FF FB 8B 0F
	Version: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
	Voltage: 3.3 V
	External Clock: Unknown
	Max Speed: 30000 MHz
	Current Speed: 2300 MHz
	Status: Populated, Disabled By BIOS
	Upgrade: ZIF Socket
	L1 Cache Handle: 0x0094
	L2 Cache Handle: 0x0114
	L3 Cache Handle: Not Provided
	Serial Number: Not Specified
	Asset Tag: Not Specified
	Part Number: Not Specified
	Core Count: 1
	Core Enabled: 1
	Characteristics:
		64-bit capable
		Execute Protection

cpu使用信息分析

知道了 CPU 的基本信息,我们就可以使用另外的命令来对 CPU 的使用情况分析
一通了。

top

Windows 的任务管理器,top 的作用和它是一样的。
在这里插入图片描述我们重点关注这么几个字段:
load average:三个数字分别表示最近 1 分钟,5 分钟和 15 分钟的负
责,数值越大负载越重。一般要求不超过核数,比如对于单核情况要
< 1。如果机器长期处于高于核数的情况,说明机器 CPU 消耗严重
了。
%Cpu(s):表示当前 CPU 的使用情况,如果要查看所有核(逻辑核)
的使用情况,可以按下数字 “1” 查看。这里有几个参数,表示如下:
在这里插入图片描述每个进程的使用情况:这里可以罗列每个进程的使用情况,包括内存和 CPU的,如果要看某个具体的进程,可以使用 top -p pid 查看。
和 top 一样的还有一个改进版的工具:htop,功能和 top 一样的,只不过比 top表现更炫酷,使用更方便,可以看下它的效果。
在这里插入图片描述

ps

可能很多人会忽略这个命令,觉得这不是查看进程状态信息的吗,其实非也,这个命令配合它的参数能显示很多功能。
比如 ps aux。如果配合 watch,可以达到跟 top 一样的效果,如:watch -n 1 “ps aux”
在这里插入图片描述

vmstat

这个命令基本能看出当前机器的运行状态和问题,非常强大。可以使用 vmstat n 后面跟一个数字,表示每隔 ns 显示系统的状态,信息包括 CPU、内存和 IO等

在这里插入图片描述第一行显示了系统自启动以来的平均值,第二行开始显示现在正在发生的情况,接下来的行会显示每5秒间隔发生了什么,每一列的含义在头部,
几个关键的字段:

  • procs:
    r这一列显示了多少进程在等待cpu,如果这个值很大,表示很多进程在排队等待执行,CPU 压力山大。
    b列显示多少进程正在不可中断的休眠(等待IO)。
  • memory:swapd列显示了多少块被换出了磁盘(页面交换),剩下的列显示了多少块是空闲的(未被使用),多少块正在被用作缓冲区,以及多少正在被用作操作系统的缓存。
  • swap:显示交换活动:每秒有多少块正在被换入(从磁盘)和换出(到磁盘)。
  • io:显示了多少块从块设备读取(bi)和写出(bo),通常反映了硬盘I/O。
  • system:显示每秒中断(in)和上下文切换(cs)的数量。
  • cpu:显示所有的cpu时间花费在各类操作的百分比,包括执行用户代码(非内核),执行系统代码(内核),空闲以及等待IO。

内存不足的表现: free memory急剧减少,回收buffer和cacher也无济于事,大量使用交换分区(swpd),页面交换(swap)频繁,读写磁盘数量(io)增多,缺页中断(in)增多,上下文切换(cs)次数增多,等待IO的进程数(b)增多,大量CPU时间用于等待IO(wa)。

这个工具强大之处在于它不仅可以分析 CPU,还可以分析内存、IO 等信息。

dstat

这个命令也很强大,能显示 CPU 使用情况,磁盘 IO 情况,网络发包情况和换页情况,而且输出是彩色的,可读性比较强,相对于 vmstat 更加详细和直观。使用时可以直接输入命令,也可以带相关参数。

在这里插入图片描述

pidstat

进程使用 CPU 情况分析

上面说的是系统级的分析,现在来看单个进程的 CPU 使用情况分析,以便于我们能对占用 CPU 过多的进程进行调试和分析,优化程序性能。
其实前面 top 和 ps 这样的命令就可以看每个进程的 CPU 使用情况,但我们需要更专业的命令。
这个命令默认统计系统信息,也包括 CPU、内存和 IO 等,我们常用 pidstat -u -p pid [times] 来显示 CPU 统计信息。如下统计 pid = 1782 的 CPU 信息。

	[root@master ~]# pidstat -u -p 1782 4
	Linux 3.10.0-957.el7.x86_64 (master) 	08/04/2020 	_x86_64_	(1 CPU)
	
	10:03:38 AM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
	10:03:42 AM     0      1782    0.00    0.00    0.00    0.00     0  kworker/u256:3

### strace
这个命令用来分析进程的系统调用情况,可以看进程都调用了哪些库和哪些系统调用,进而可以进一步优化程序。比如我们分析 ls 的系统调用情况,就可以用 strace ls:

[root@master ~]# strace ls
execve("/usr/bin/ls", ["ls"], [/* 48 vars */]) = 0
brk(NULL)                               = 0x1f60000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0997a51000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=81628, ...}) = 0
mmap(NULL, 81628, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f0997a3d000
close(3)                                = 0
open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320i\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=155784, ...}) = 0
mmap(NULL, 2255184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f099760a000
mprotect(0x7f099762e000, 2093056, PROT_NONE) = 0
mmap(0x7f099782d000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x23000) = 0x7f099782d000
mmap(0x7f099782f000, 6480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f099782f000
close(3)                                = 0
open("/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \26\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=20032, ...}) = 0
mmap(NULL, 2114112, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f0997405000
mprotect(0x7f0997409000, 2093056, PROT_NONE) = 0
mmap(0x7f0997608000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f0997608000
close(3)                                = 0
open("/lib64/libacl.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\37\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=37056, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0997a3c000
mmap(NULL, 2130560, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f09971fc000
mprotect(0x7f0997203000, 2097152, PROT_NONE) = 0
mmap(0x7f0997403000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7f0997403000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340$\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2151672, ...}) = 0
mmap(NULL, 3981792, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f0996e2f000
mprotect(0x7f0996ff1000, 2097152, PROT_NONE) = 0
mmap(0x7f09971f1000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c2000) = 0x7f09971f1000
mmap(0x7f09971f7000, 16864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f09971f7000
close(3)                                = 0
open("/lib64/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\25\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=402384, ...}) = 0
mmap(NULL, 2494984, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f0996bcd000
mprotect(0x7f0996c2d000, 2097152, PROT_NONE) = 0
mmap(0x7f0996e2d000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x60000) = 0x7f0996e2d000
close(3)                                = 0
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\r\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=19288, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0997a3b000
mmap(NULL, 2109712, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f09969c9000
mprotect(0x7f09969cb000, 2097152, PROT_NONE) = 0
mmap(0x7f0996bcb000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f0996bcb000
close(3)                                = 0
open("/lib64/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\23\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=19896, ...}) = 0
mmap(NULL, 2113904, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f09967c4000
mprotect(0x7f09967c8000, 2093056, PROT_NONE) = 0
mmap(0x7f09969c7000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f09969c7000
close(3)                                = 0
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260l\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=141968, ...}) = 0
mmap(NULL, 2208904, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f09965a8000
mprotect(0x7f09965bf000, 2093056, PROT_NONE) = 0
mmap(0x7f09967be000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16000) = 0x7f09967be000
mmap(0x7f09967c0000, 13448, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f09967c0000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0997a3a000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0997a38000
arch_prctl(ARCH_SET_FS, 0x7f0997a38840) = 0
mprotect(0x7f09971f1000, 16384, PROT_READ) = 0
mprotect(0x7f09967be000, 4096, PROT_READ) = 0
mprotect(0x7f09969c7000, 4096, PROT_READ) = 0
mprotect(0x7f0996bcb000, 4096, PROT_READ) = 0
mprotect(0x7f0996e2d000, 4096, PROT_READ) = 0
mprotect(0x7f0997403000, 4096, PROT_READ) = 0
mprotect(0x7f0997608000, 4096, PROT_READ) = 0
mprotect(0x7f099782d000, 4096, PROT_READ) = 0
mprotect(0x61a000, 4096, PROT_READ)     = 0
mprotect(0x7f0997a52000, 4096, PROT_READ) = 0
munmap(0x7f0997a3d000, 81628)           = 0
set_tid_address(0x7f0997a38b10)         = 11370
set_robust_list(0x7f0997a38b20, 24)     = 0
rt_sigaction(SIGRTMIN, {0x7f09965ae790, [], SA_RESTORER|SA_SIGINFO, 0x7f09965b75d0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x7f09965ae820, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x7f09965b75d0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
statfs("/sys/fs/selinux", 0x7ffed8a63760) = -1 ENOENT (No such file or directory)
statfs("/selinux", 0x7ffed8a63760)      = -1 ENOENT (No such file or directory)
brk(NULL)                               = 0x1f60000
brk(0x1f81000)                          = 0x1f81000
open("/proc/filesystems", O_RDONLY)     = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0997a50000
read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tr"..., 1024) = 356
stat("/etc/sysconfig/64bit_strstr_via_64bit_strstr_sse2_unaligned", 0x7ffed8a63330) = -1 ENOENT (No such file or directory)
read(3, "", 1024)                       = 0
close(3)                                = 0
munmap(0x7f0997a50000, 4096)            = 0
access("/etc/selinux/config", F_OK)     = 0
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=106075056, ...}) = 0
mmap(NULL, 106075056, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f099007e000
close(3)                                = 0
ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=24, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
getdents(3, /* 35 entries */, 32768)    = 1264
getdents(3, /* 0 entries */, 32768)     = 0
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0997a50000
write(1, "anaconda-ks.cfg\t\t       Pictures"..., 33anaconda-ks.cfg		       Pictures
) = 33
write(1, "core.10352\t\t       Public\n", 26core.10352		       Public
) = 26
write(1, "Desktop\t\t\t       python-babel-0."..., 53Desktop			       python-babel-0.9.6-8.el7.noarch.rpm
) = 53
write(1, "Documents\t\t       python-jinja2-"..., 55Documents		       python-jinja2-2.7.2-4.el7.noarch.rpm
) = 55
write(1, "Downloads\t\t       python-markups"..., 59Downloads		       python-markupsafe-0.11-10.el7.x86_64.rpm
) = 59
write(1, "initial-setup-ks.cfg\t       pyth"..., 71initial-setup-ks.cfg	       python-setproctitle-1.1.6-5.el7.x86_64.rpm
) = 71
write(1, "iqiyi_modify_max_bandwidth.sh  T"..., 41iqiyi_modify_max_bandwidth.sh  Templates
) = 41
write(1, "Music\t\t\t       Videos\n", 22Music			       Videos
) = 22
close(1)                                = 0
munmap(0x7f0997a50000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
[root@master ~]# 

可以看到,一个简单的 ls 命令,其实有不少系统调用的操作。

此外,还可以 attach(附着)到一个正在运行的进程上进行分析,比如我 attach 到 802 这个进程显示:
在这里插入图片描述根据这些输出信息,其实就能够很好地帮我们分析问题,从而定位到问题所在了。

后记

对比+练习。工具不再有多少而在于有多熟练!

猜你喜欢

转载自blog.csdn.net/Thorne_lu/article/details/107728009
今日推荐