文章目录
- 一、proc文件系统
- 1.1 /proc/[pid]
- 1.1.1 /proc/[pid]/arch_status
- 1.1.2 /proc/[pid]/attr
- 1.1.2.1 /proc/[pid]/attr/current
- 1.1.2.2 /proc/[pid]/attr/exec
- 1.1.2.3 /proc/[pid]/attr/fscreate
- 1.1.2.4 /proc/[pid]/attr/keycreate
- 1.1.2.5 /proc/[pid]/attr/prev
- 1.1.2.6 /proc/[pid]/attr/sockcreate
- 1.1.3 /proc/[pid]/autogroup
- 1.1.4 /proc/[pid]/auxv
- 1.1.5 /proc/[pid]/cgroup
- 1.1.6 /proc/[pid]/clear_refs
- 1.1.7 /proc/[pid]/cmdline
- 1.1.8 /proc/[pid]/comm
- 1.1.9 /proc/[pid]/coredump_filter
- 1.1.10 /proc/[pid]/cpu_resctrl_groups
- 1.1.11 /proc/[pid]/cpuset
- 1.1.12 /proc/[pid]/cwd -> /
- 1.1.13 /proc/[pid]/environ
- 1.1.14 /proc/[pid]/exe
- 1.1.15 /proc/[pid]/fd
- 1.1.16 /proc/[pid]/fdinfo
- 1.1.17 /proc/[pid]/gid_map
- 1.1.18 /proc/[pid]/io
- 1.1.19 /proc/[pid]/limits
- 1.1.20 /proc/[pid]/loginuid
- 1.1.21 /proc/[pid]/map_files
- 1.1.22 /proc/[pid]/maps
- 1.1.23 /proc/[pid]/mem
- 1.1.24 /proc/[pid]/mountinfo
- 1.1.25 /proc/[pid]/mounts
- 1.1.26 /proc/[pid]/mountstats
- 1.1.27 /proc/[pid]/net
- 1.1.28 /proc/[pid]/ns
- 1.1.29 /proc/[pid]/numa_maps
- 1.1.30 /proc/[pid]/oom_adj
- 1.1.31 /proc/[pid]/oom_score
- 1.1.32 /proc/[pid]/oom_score_adj
- 1.1.33 /proc/[pid]/pagemap
- 1.1.34 /proc/[pid]/patch_state
- 1.1.35 /proc/[pid]/personality
- 1.1.36 /proc/[pid]/projid_map
- 1.1.37 /proc/[pid]/root
- 1.1.38 /proc/[pid]/sched
- 1.1.39 /proc/[pid]/schedstat
- 1.1.40 /proc/[pid]/sessionid
- 1.1.41 /proc/[pid]/setgroups
- 1.1.42 /proc/[pid]/smaps
- 1.1.43 /proc/[pid]/smaps_rollup
- 1.1.44 /proc/[pid]/stack
- 1.1.45 /proc/[pid]/stat
- 1.1.46 /proc/[pid]/statm
- 1.1.47 /proc/[pid]/status
- 1.1.48 /proc/[pid]/syscall
- 1.1.49 /proc/[pid]/task
- 1.1.50 /proc/[pid]/timens_offsets
- 1.1.51 /proc/[pid]/timers
- 1.1.52 /proc/[pid]/timerslack_ns
- 1.1.53 /proc/[pid]/uid_map
- 1.1.54 /proc/[pid]/wchan
- 1.2 acpi/
- 1.3 asound/
- 1.4 bootconfig
- 1.5 buddyinfo
- 1.6 bus/
- 1.7 cgroups
- 1.8 cmdline
- 1.9 consoles
- 1.10 cpuinfo
- 1.11 crypto
- 1.12 devices
- 1.13 diskstats
- 1.14 dma
- 1.15 driver/
- 1.16 dynamic_debug/
- 1.17 execdomains
- 1.18 fb
- 1.19 filesystems
- 1.20 fs/
- 1.21 interrupts
- 1.22 iomem
- 1.23 ioports
- 1.24 irq/
- 1.25 kallsyms
- 1.26 kcore
- 1.27 keys
- 1.28 key-users
- 1.29 kmsg
- 1.30 kpagecgroup
- 1.31 kpagecount
- 1.32 kpageflags
- 1.33 loadavg
- 1.34 locks
- 1.35 mdstat
- 1.36 meminfo
- 1.37 misc
- 1.38 modules
- 1.39 mounts
- 1.40 mpt/
- 1.41 mtrr
- 1.42 net -> self/net/
- 1.43 pagetypeinfo
- 1.44 partitions
- 1.45 pressure/
- 1.46 schedstat
- 1.47 scsi/
- 1.48 self
- 1.49 slabinfo
- 1.50 softirqs
- 1.51 stat
- 1.52 swaps
- 1.53 sys/
- 1.54 sysrq-trigger
- 1.55 sysvipc/
- 1.56 thread-self
- 1.57 timer_list
- 1.58 tty/
- 1.59 uptime
- 1.60 version
- 1.61 version_signature
- 1.62 vmallocinfo
- 1.63 vmstat
- 1.64 zoneinfo
一、proc文件系统
proc全称是process information pseudo-filesystem,翻译过来就是进程信息伪文件系统。
proc文件系统是一个伪文件系统,它提供了一个到内核数据结构的接口,一般挂载在/proc。proc文件系统中的大多数文件都是只读的,但有些文件是可写的,允许修改内核变量。
在Ubuntu20.04,内核版本是5.15.0-56。我们可以看到proc文件系统下的文件和目录如下图所示:
我们首先看到的是很多的数字,这些数字就是我们系统的每一个进程的信息,数字目录下面的文件的含义是一样的。我们就把这些数字归类为pid。
每个/proc/[pid]目录中的文件通常属于进程的有效用户和有效组ID。但是,作为一种安全措施,如果进程的“dumpable”属性为,则所有权将设置为root:root
请设置为1以外的值。
1.1 /proc/[pid]
每个正在运行的进程都有一个数值子目录;子目录以进程ID命名。每个/proc/[pid]子目录都包含下面描述的伪文件和目录:
1.1.1 /proc/[pid]/arch_status
空文件
1.1.2 /proc/[pid]/attr
此目录中的文件为安全模块提供了API。这个目录的内容是可以被读取和写入的文件,以便设置与安全相关的属性。添加这个目录是为了支持SELinux,但目的是让API足够通用,以支持其他安全模块。只有在内核配置了CONFIG_SECURITY时,才会出现这个目录。
1.1.2.1 /proc/[pid]/attr/current
该文件的内容表示进程的当前安全属性。在SELinux中,这个文件用于获取进程的安全上下文。安全模块可以选择通过写入该节点来支持“设置”操作。
1.1.2.2 /proc/[pid]/attr/exec
该文件表示在执行execve时分配给进程的属性。
在SELinux中,这是支持角色/域转换所需要的,而execve是进行这种转换的首选点,因为它在新的安全标签中提供了对流程初始化和状态继承的更好控制。在SELinux中,这个属性在execve上被重置,以便新程序对它可能进行的任何execve调用都恢复到默认行为。在SELinux中,进程只能设置自己的/proc/[pid]/attr/exec属性。
1.1.2.3 /proc/[pid]/attr/fscreate
该文件表示要分配给后续调用open(2)、mkdir(2)、symlink(2)和mknod(2)所创建的文件的属性。
SELinux使用这个文件来支持在安全状态下创建文件(使用前面提到的系统调用),这样在创建和设置属性之间就不会有不适当访问的风险。在SELinux中,该属性在execve上被重置,以便新程序对它可能进行的任何文件创建调用恢复默认行为,但该属性将在程序内的多个文件创建调用中保持,除非显式重置。在SELinux中,进程只能设置自己的/proc/[pid]/attr/fscreate属性。
1.1.2.4 /proc/[pid]/attr/keycreate
如果进程将安全上下文写入该文件,则随后创建的所有密钥(add_key(2))都将使用该上下文进行标记。
1.1.2.5 /proc/[pid]/attr/prev
该文件包含最后一次执行(2)之前进程的安全上下文;即/proc/[pid]/attr/current的上一个值。
1.1.2.6 /proc/[pid]/attr/sockcreate
如果进程将安全上下文写入此文件,则随后创建的所有套接字都将使用此上下文进行标记。
1.1.3 /proc/[pid]/autogroup
root@ubuntu:/proc/1# cat /proc/1/autogroup
/autogroup-2 nice 0
内核提供了一种被称为autogrouping的特性来为多进程和CPU密集型负载(如Linux内核中的大量并行进程)提升交互式桌面性能。当通过setsid(2) (setsid会将一个进程脱离父进程)创建一个新的会话时会创建一个新的autogroup,这种情况可能发生在一个新的终端窗口启动时。使用fork(2)创建的进程会继承父辈的autogroup成员。因此,一个会话中的所有进程都属于同一个autogroup。当最后一个进程结束后,autogroup会被自动销毁。一个autogroup中的所有成员都属于同一个内核调度器"任务组"。CFS调度器使用了在任务组间均衡分配CPU时钟周期的算法。可以使用下面例子进行展示提升交互式桌面性能的好处。autogroup的nice值的意义与进程的nice值意义相同,区别是前者为将autogroup作为一个整体,并基于相对其他autogroups设置的nice值来分配CPU时钟周期。对于一个autogroup内的进程,其CPU时钟周期为autogroup(相对于其他autogroups)的nice值和进程的nice值(相对于其他进程)的产物(即首先根据autogroup的nice值计算该autogroup所占用的CPU,然后根据进程的nice值计算该进程所占用的(属于其autogroup的)CPU)。
这里可以查看进程所属的autogroup和该autogroup的nioce值。
1.1.4 /proc/[pid]/auxv
root@ubuntu:/proc/1# hexdump auxv
0000000 0021 0000 0000 0000 6000 efd4 7ffe 0000
0000010 0033 0000 0000 0000 06f0 0000 0000 0000
0000020 0010 0000 0000 0000 fbff 0f8b 0000 0000
0000030 0006 0000 0000 0000 1000 0000 0000 0000
0000040 0011 0000 0000 0000 0064 0000 0000 0000
0000050 0003 0000 0000 0000 8040 cd96 563b 0000
0000060 0004 0000 0000 0000 0038 0000 0000 0000
0000070 0005 0000 0000 0000 000d 0000 0000 0000
0000080 0007 0000 0000 0000 c000 fd72 7fe5 0000
0000090 0008 0000 0000 0000 0000 0000 0000 0000
00000a0 0009 0000 0000 0000 5a50 cd9a 563b 0000
00000b0 000b 0000 0000 0000 0000 0000 0000 0000
00000c0 000c 0000 0000 0000 0000 0000 0000 0000
00000d0 000d 0000 0000 0000 0000 0000 0000 0000
00000e0 000e 0000 0000 0000 0000 0000 0000 0000
00000f0 0017 0000 0000 0000 0000 0000 0000 0000
0000100 0019 0000 0000 0000 7859 efd0 7ffe 0000
0000110 001a 0000 0000 0000 0002 0000 0000 0000
0000120 001f 0000 0000 0000 7fed efd0 7ffe 0000
0000130 000f 0000 0000 0000 7869 efd0 7ffe 0000
0000140 0000 0000 0000 0000 0000 0000 0000 0000
0000150
这个文件包含了在进程执行时,传递给进程的ELF的解释器的信息。这个文件的格式是一个无符号的long类型的ID加上每个entry的一个无符号的long类型,这最后的一个entry包含了两个零。
1.1.5 /proc/[pid]/cgroup
root@ubuntu:/proc/1# cat cgroup
13:pids:/init.scope
12:rdma:/
11:net_cls,net_prio:/
10:memory:/init.scope
9:freezer:/
8:perf_event:/
7:misc:/
6:hugetlb:/
5:cpu,cpuacct:/
4:devices:/init.scope
3:blkio:/
2:cpuset:/
1:name=systemd:/init.scope
0::/init.scope
可以获取一个进程属于哪些控制组的信息。
1.1.6 /proc/[pid]/clear_refs
这是一个只能写的文件,只能由进程的所有者写。写入的值和含义如下表所示:
值 | 含义 |
---|---|
1 | 重置与进程相关的所有页的PG_Referenced和access /YOUNG位。 |
2 | 重置与进程关联的所有匿名页的PG_Referenced和access /YOUNG位。 |
3 | 重置与进程关联的所有文件映射页的PG_Referenced和accessible /YOUNG位。 |
4 | 清除与该进程关联的所有页面的软脏位。 |
5 | 将峰值驻留集大小(“高水位标记”)重置为进程当前驻留集大小值。 |
6 | 无效 |
1.1.7 /proc/[pid]/cmdline
root@ubuntu:/proc/1# cat cmdline
/sbin/initautonoprompt
root@ubuntu:/proc/1#
这个只读文件保存进程的完整命令行,除非进程是僵尸进程。在后一种情况下,这个文件中什么都没有,也就是说,对这个文件的读取将返回0个字符。命令行参数在这个文件中显示为一组由空字节(‘\0’)分隔的字符串,最后一个字符串后面还有一个空字节。
1.1.8 /proc/[pid]/comm
root@ubuntu:/proc/1# cat comm
systemd
该文件公开进程的comm值,即与进程关联的命令名。同一个进程中的不同线程可能有不同的comm值,可以通过/proc/[pid]/task/[tid]/comm访问。一个线程可以修改它的comm值,或者同一线程组中的任何其他线程的comm值,通过写入文件/proc/self/task/[tid]/comm。长度超过一定长度的字符的字符串将被静默截断。
1.1.9 /proc/[pid]/coredump_filter
root@ubuntu:/proc/1# cat coredump_filter
00000033
1.1.10 /proc/[pid]/cpu_resctrl_groups
root@ubuntu:/proc/1# cat cpu_resctrl_groups
res:
mon:
1.1.11 /proc/[pid]/cpuset
root@ubuntu:/proc/1# cat cpuset
/
1.1.12 /proc/[pid]/cwd -> /
这是到进程当前工作目录的符号链接,也就是执行命令的时候所在的目录。在多线程进程中,如果主线程已经终止(通常通过调用pthread_exit(3)),则此符号链接的内容将不可用。
1.1.13 /proc/[pid]/environ
root@ubuntu:/proc/1# cat environ | tr '\000' '\n'
find_preseed=/preseed.cfg
HOME=/
init=/sbin/init
NETWORK_SKIP_ENSLAVED=
locale=en_US
TERM=linux
BOOT_IMAGE=/boot/vmlinuz-5.15.0-56-generic
drop_caps=
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
rootmnt=/root
priority=critical
该文件包含当前正在执行的程序通过execve(2)启动时设置的初始环境。条目由空字节(‘\0’)分隔,并且在末尾可能有一个空字节。如果在执行execve(2)之后,进程修改了它的环境(例如,通过调用putenv(3)这样的函数或直接修改environ(7)变量),该文件将不会反映这些更改。
1.1.14 /proc/[pid]/exe
root@ubuntu:/proc/1# ll exe
lrwxrwxrwx 1 root root 0 Jan 14 05:17 exe -> /usr/lib/systemd/systemd*
该文件是一个符号链接,指向执行的程序文件,包含所执行命令的实际路径名。
1.1.15 /proc/[pid]/fd
root@ubuntu:/proc/1# ls fd
0 14 190 200 206 211 217 223 229 234 240 277 30 308 314 32 326 331 34 42 48 53 59 64 7 78
1 15 191 201 207 212 218 224 23 235 241 28 302 309 315 321 327 332 35 43 49 54 6 65 73 79
10 16 192 202 208 213 219 225 230 236 242 29 303 31 316 322 328 334 36 44 5 55 60 66 74 8
11 17 199 203 209 214 22 226 231 238 25 292 304 310 317 323 329 335 4 45 50 56 61 67 75 9
12 18 2 204 21 215 220 227 232 239 26 299 306 311 318 324 33 336 40 46 51 57 62 68 76
13 19 20 205 210 216 221 228 233 24 27 3 307 313 319 325 330 337 41 47 52 58 63 69 77
root@ubuntu:/proc/1#
这是一个子目录,包含进程打开的每个文件的一个条目,由其文件描述符命名,是到实际文件的符号链接。
root@ubuntu:/proc/1/fd# ll
total 0
dr-x------ 2 root root 0 Jan 14 05:17 ./
dr-xr-xr-x 9 root root 0 Jan 14 05:17 ../
lrwx------ 1 root root 64 Jan 14 05:17 0 -> /dev/null
lrwx------ 1 root root 64 Jan 14 05:17 1 -> /dev/null
lr-x------ 1 root root 64 Jan 14 05:19 10 -> /proc/1/mountinfo
lr-x------ 1 root root 64 Jan 14 05:19 11 -> anon_inode:inotify
lr-x------ 1 root root 64 Jan 14 05:17 12 -> anon_inode:inotify
lr-x------ 1 root root 64 Jan 14 05:19 13 -> anon_inode:inotify
lr-x------ 1 root root 64 Jan 14 05:19 14 -> /proc/swaps
lrwx------ 1 root root 64 Jan 14 05:19 15 -> 'socket:[25142]'
lr-x------ 1 root root 64 Jan 14 05:19 16 -> anon_inode:inotify
lr-x------ 1 root root 64 Jan 14 05:19 17 -> anon_inode:inotify
lrwx------ 1 root root 64 Jan 14 05:19 18 -> 'socket:[58239]'
lrwx------ 1 root root 64 Jan 14 05:19 19 -> 'socket:[25146]'
lrwx------ 1 root root 64 Jan 14 05:19 190 -> 'socket:[25143]'
lrwx------ 1 root root 64 Jan 14 05:19 191 -> 'socket:[25144]'
lrwx------ 1 root root 64 Jan 14 05:19 192 -> 'socket:[25145]'
lrwx------ 1 root root 64 Jan 14 05:19 199 -> 'socket:[42574]'
lrwx------ 1 root root 64 Jan 14 05:17 2 -> /dev/null
lrwx------ 1 root root 64 Jan 14 05:17 20 -> 'socket:[25148]'
lrwx------ 1 root root 64 Jan 14 05:19 200 -> 'socket:[42575]'
lrwx------ 1 root root 64 Jan 14 05:19 201 -> 'socket:[25173]'
lr-x------ 1 root root 64 Jan 14 05:19 202 -> 'pipe:[25155]'
lrwx------ 1 root root 64 Jan 14 05:19 203 -> 'socket:[34670]'
lrwx------ 1 root root 64 Jan 14 05:19 204 -> 'socket:[34662]'
lrwx------ 1 root root 64 Jan 14 05:19 205 -> 'socket:[34660]'
lrwx------ 1 root root 64 Jan 14 05:19 206 -> 'socket:[25169]'
lrwx------ 1 root root 64 Jan 14 05:19 207 -> 'socket:[25171]'
lrwx------ 1 root root 64 Jan 14 05:19 208 -> /run/initctl|
lrwx------ 1 root root 64 Jan 14 05:19 209 -> 'socket:[25167]'
lrwx------ 1 root root 64 Jan 14 05:19 21 -> 'socket:[50747]'
lrwx------ 1 root root 64 Jan 14 05:19 210 -> 'socket:[34666]'
lrwx------ 1 root root 64 Jan 14 05:19 211 -> 'socket:[34668]'
lrwx------ 1 root root 64 Jan 14 05:19 212 -> 'socket:[25159]'
lrwx------ 1 root root 64 Jan 14 05:19 213 -> 'socket:[34664]'
lrwx------ 1 root root 64 Jan 14 05:19 214 -> 'socket:[25166]'
lrwx------ 1 root root 64 Jan 14 05:19 215 -> 'socket:[52770]'
lrwx------ 1 root root 64 Jan 14 05:19 216 -> 'socket:[52769]'
lrwx------ 1 root root 64 Jan 14 05:19 217 -> 'socket:[52689]'
lrwx------ 1 root root 64 Jan 14 05:19 218 -> 'socket:[52578]'
lrwx------ 1 root root 64 Jan 14 05:19 219 -> 'socket:[52485]'
lrwx------ 1 root root 64 Jan 14 05:19 22 -> 'socket:[58263]'
lrwx------ 1 root root 64 Jan 14 05:19 220 -> 'socket:[52472]'
lrwx------ 1 root root 64 Jan 14 05:19 221 -> 'socket:[52451]'
lrwx------ 1 root root 64 Jan 14 05:19 223 -> 'socket:[51377]'
lrwx------ 1 root root 64 Jan 14 05:19 224 -> 'socket:[51376]'
lrwx------ 1 root root 64 Jan 14 05:19 225 -> 'socket:[51368]'
lrwx------ 1 root root 64 Jan 14 05:19 226 -> 'socket:[51367]'
lrwx------ 1 root root 64 Jan 14 05:19 227 -> 'socket:[51366]'
lrwx------ 1 root root 64 Jan 14 05:19 228 -> 'socket:[51365]'
lrwx------ 1 root root 64 Jan 14 05:19 229 -> 'socket:[51364]'
lrwx------ 1 root root 64 Jan 14 05:19 23 -> 'socket:[50752]'
lrwx------ 1 root root 64 Jan 14 05:19 230 -> 'socket:[51363]'
lrwx------ 1 root root 64 Jan 14 05:19 231 -> 'socket:[51362]'
lrwx------ 1 root root 64 Jan 14 05:19 232 -> 'socket:[51361]'
lrwx------ 1 root root 64 Jan 14 05:19 233 -> 'socket:[51360]'
lrwx------ 1 root root 64 Jan 14 05:19 234 -> 'socket:[51359]'
lrwx------ 1 root root 64 Jan 14 05:19 235 -> 'socket:[51358]'
lrwx------ 1 root root 64 Jan 14 05:19 236 -> 'socket:[51357]'
lrwx------ 1 root root 64 Jan 14 05:19 238 -> 'socket:[51355]'
lrwx------ 1 root root 64 Jan 14 05:19 239 -> 'socket:[47559]'
lrwx------ 1 root root 64 Jan 14 05:19 24 -> anon_inode:bpf-prog
lrwx------ 1 root root 64 Jan 14 05:19 240 -> 'socket:[46764]'
lrwx------ 1 root root 64 Jan 14 05:19 241 -> 'socket:[46763]'
lrwx------ 1 root root 64 Jan 14 05:19 242 -> 'socket:[46688]'
lrwx------ 1 root root 64 Jan 14 05:19 25 -> anon_inode:bpf-prog
lr-x------ 1 root root 64 Jan 14 05:19 26 -> /dev/autofs
lrwx------ 1 root root 64 Jan 14 05:19 27 -> anon_inode:bpf-prog
lrwx------ 1 root root 64 Jan 14 05:19 277 -> 'socket:[46107]'
lrwx------ 1 root root 64 Jan 14 05:19 28 -> 'anon_inode:[timerfd]'
lrwx------ 1 root root 64 Jan 14 05:19 29 -> anon_inode:bpf-prog
lrwx------ 1 root root 64 Jan 14 05:19 292 -> 'socket:[41161]'
lrwx------ 1 root root 64 Jan 14 05:19 299 -> 'socket:[40535]'
l-wx------ 1 root root 64 Jan 14 05:17 3 -> /dev/kmsg
lrwx------ 1 root root 64 Jan 14 05:17 30 -> anon_inode:bpf-prog
lrwx------ 1 root root 64 Jan 14 05:19 302 -> 'socket:[39802]'
lrwx------ 1 root root 64 Jan 14 05:19 303 -> 'socket:[39796]'
lrwx------ 1 root root 64 Jan 14 05:19 304 -> 'socket:[36460]'
lrwx------ 1 root root 64 Jan 14 05:19 306 -> 'socket:[36362]'
lrwx------ 1 root root 64 Jan 14 05:19 307 -> 'socket:[38990]'
lrwx------ 1 root root 64 Jan 14 05:19 308 -> 'socket:[37428]'
lrwx------ 1 root root 64 Jan 14 05:19 309 -> 'socket:[37427]'
lrwx------ 1 root root 64 Jan 14 05:17 31 -> anon_inode:bpf-prog
lrwx------ 1 root root 64 Jan 14 05:19 310 -> 'socket:[37426]'
lrwx------ 1 root root 64 Jan 14 05:19 311 -> 'socket:[37259]'
lrwx------ 1 root root 64 Jan 14 05:19 313 -> 'socket:[35883]'
lrwx------ 1 root root 64 Jan 14 05:19 314 -> 'socket:[35868]'
lrwx------ 1 root root 64 Jan 14 05:19 315 -> 'socket:[34708]'
lrwx------ 1 root root 64 Jan 14 05:19 316 -> 'socket:[34707]'
lrwx------ 1 root root 64 Jan 14 05:19 317 -> 'socket:[34705]'
lrwx------ 1 root root 64 Jan 14 05:19 318 -> 'socket:[34704]'
lrwx------ 1 root root 64 Jan 14 05:19 319 -> 'socket:[34703]'
lrwx------ 1 root root 64 Jan 14 05:19 32 -> anon_inode:bpf-prog
lrwx------ 1 root root 64 Jan 14 05:19 321 -> 'socket:[34700]'
lrwx------ 1 root root 64 Jan 14 05:19 322 -> 'socket:[34606]'
lrwx------ 1 root root 64 Jan 14 05:19 323 -> 'socket:[31292]'
lrwx------ 1 root root 64 Jan 14 05:19 324 -> 'socket:[31146]'
lrwx------ 1 root root 64 Jan 14 05:19 325 -> 'socket:[31145]'
lrwx------ 1 root root 64 Jan 14 05:19 326 -> 'socket:[29691]'
lrwx------ 1 root root 64 Jan 14 05:19 327 -> /dev/input/event2
lrwx------ 1 root root 64 Jan 14 05:19 328 -> /dev/input/event3
lrwx------ 1 root root 64 Jan 14 05:19 329 -> /dev/input/event1
lrwx------ 1 root root 64 Jan 14 05:19 33 -> anon_inode:bpf-prog
lrwx------ 1 root root 64 Jan 14 05:19 330 -> /dev/input/event4
lrwx------ 1 root root 64 Jan 14 05:19 331 -> /dev/input/event0
lrwx------ 1 root root 64 Jan 14 05:19 332 -> /dev/dri/card0
lrwx------ 1 root root 64 Jan 14 05:19 334 -> /dev/rfkill
lrwx------ 1 root root 64 Jan 14 05:19 335 -> 'socket:[34658]'
lrwx------ 1 root root 64 Jan 14 05:19 336 -> 'socket:[25175]'
lrwx------ 1 root root 64 Jan 14 05:19 337 -> 'socket:[25157]'
lrwx------ 1 root root 64 Jan 14 05:17 34 -> 'socket:[58264]'
lrwx------ 1 root root 64 Jan 14 05:17 35 -> 'socket:[72575]'
lrwx------ 1 root root 64 Jan 14 05:17 36 -> 'socket:[72576]'
lrwx------ 1 root root 64 Jan 14 05:19 4 -> 'anon_inode:[eventpoll]'
lrwx------ 1 root root 64 Jan 14 05:19 40 -> 'socket:[25202]'
lrwx------ 1 root root 64 Jan 14 05:19 41 -> 'socket:[28910]'
lrwx------ 1 root root 64 Jan 14 05:19 42 -> 'socket:[50715]'
lrwx------ 1 root root 64 Jan 14 05:19 43 -> 'socket:[50716]'
lrwx------ 1 root root 64 Jan 14 05:19 44 -> 'socket:[50717]'
lrwx------ 1 root root 64 Jan 14 05:19 45 -> 'socket:[50753]'
lrwx------ 1 root root 64 Jan 14 05:19 46 -> 'anon_inode:[timerfd]'
lrwx------ 1 root root 64 Jan 14 05:19 47 -> 'socket:[50761]'
lrwx------ 1 root root 64 Jan 14 05:19 48 -> 'socket:[50927]'
lrwx------ 1 root root 64 Jan 14 05:19 49 -> 'socket:[50778]'
lrwx------ 1 root root 64 Jan 14 05:19 5 -> 'anon_inode:[signalfd]'
lrwx------ 1 root root 64 Jan 14 05:19 50 -> 'socket:[50779]'
lrwx------ 1 root root 64 Jan 14 05:19 51 -> 'socket:[50867]'
lrwx------ 1 root root 64 Jan 14 05:19 52 -> 'socket:[50868]'
lrwx------ 1 root root 64 Jan 14 05:19 53 -> 'socket:[50869]'
lrwx------ 1 root root 64 Jan 14 05:17 54 -> 'socket:[50928]'
lrwx------ 1 root root 64 Jan 14 05:17 55 -> 'socket:[50929]'
lrwx------ 1 root root 64 Jan 14 05:17 56 -> 'socket:[50882]'
lrwx------ 1 root root 64 Jan 14 05:17 57 -> 'socket:[50932]'
lrwx------ 1 root root 64 Jan 14 05:17 58 -> 'socket:[50933]'
lrwx------ 1 root root 64 Jan 14 05:17 59 -> 'socket:[54623]'
lr-x------ 1 root root 64 Jan 14 05:19 6 -> anon_inode:inotify
lrwx------ 1 root root 64 Jan 14 05:17 60 -> 'socket:[34697]'
lrwx------ 1 root root 64 Jan 14 05:19 61 -> 'socket:[54624]'
lrwx------ 1 root root 64 Jan 14 05:19 62 -> 'socket:[54625]'
lrwx------ 1 root root 64 Jan 14 05:19 63 -> 'socket:[56790]'
lrwx------ 1 root root 64 Jan 14 05:19 64 -> 'socket:[51029]'
lrwx------ 1 root root 64 Jan 14 05:19 65 -> 'socket:[51030]'
lrwx------ 1 root root 64 Jan 14 05:19 66 -> 'socket:[51042]'
lrwx------ 1 root root 64 Jan 14 05:19 67 -> 'socket:[51043]'
lrwx------ 1 root root 64 Jan 14 05:19 68 -> 'socket:[51034]'
lrwx------ 1 root root 64 Jan 14 05:19 69 -> 'socket:[51035]'
lr-x------ 1 root root 64 Jan 14 05:19 7 -> /sys/fs/cgroup/unified/
lrwx------ 1 root root 64 Jan 14 05:19 73 -> 'socket:[53966]'
lrwx------ 1 root root 64 Jan 14 05:19 74 -> 'socket:[51101]'
lrwx------ 1 root root 64 Jan 14 05:19 75 -> 'socket:[51102]'
lrwx------ 1 root root 64 Jan 14 05:19 76 -> 'socket:[51160]'
lrwx------ 1 root root 64 Jan 14 05:19 77 -> 'socket:[51161]'
lrwx------ 1 root root 64 Jan 14 05:19 78 -> 'socket:[51176]'
lrwx------ 1 root root 64 Jan 14 05:19 79 -> 'socket:[51171]'
lrwx------ 1 root root 64 Jan 14 05:19 8 -> 'anon_inode:[timerfd]'
lrwx------ 1 root root 64 Jan 14 05:17 9 -> 'anon_inode:[eventpoll]'
root@ubuntu:/proc/1/fd#
0是标准输入,1是标准输出,2是标准误差,依此类推,其他数字就是打开的fd文件。打开的文件分为以下几种类型的文件描述符:
类型 | 格式 | 含义 |
---|---|---|
管道 | ‘pipe:[25155]’ | 表示这是一个管道文件,inode是50867 |
套接字 | ‘socket:[50867]’ | 表示这是一个套接字文件,inode是50867 |
没有inode的文件描述符 | anon_inode:[eventpoll] | 这里的文件类型是eventpoll,还有其他文件类型,比如timerfd和signalfd |
普通文件描述符 | /dev/input/event2 | 表示该文件是打开 /dev/input/event2返回的fd |
1.1.16 /proc/[pid]/fdinfo
root@ubuntu:/proc/1/fdinfo# ls
0 14 190 200 206 211 217 223 229 234 240 277 30 308 314 32 326 331 34 42 48 53 59 64 7 78
1 15 191 201 207 212 218 224 23 235 241 28 302 309 315 321 327 332 35 43 49 54 6 65 73 79
10 16 192 202 208 213 219 225 230 236 242 29 303 31 316 322 328 334 36 44 5 55 60 66 74 8
11 17 199 203 209 214 22 226 231 238 25 292 304 310 317 323 329 335 4 45 50 56 61 67 75 9
12 18 2 204 21 215 220 227 232 239 26 299 306 311 318 324 33 336 40 46 51 57 62 68 76
13 19 20 205 210 216 221 228 233 24 27 3 307 313 319 325 330 337 41 47 52 58 63 69 77
root@ubuntu:/proc/1/fdinfo# cat 0
pos: 0
flags: 0100002
mnt_id: 26
ino: 5
root@ubuntu:/proc/1/fdinfo#
//poll文件描述符
root@ubuntu:/proc/1# cat fdinfo/9
pos: 0
flags: 02000002
mnt_id: 15
ino: 13577
tfd: 10 events: 80000019 data: 563bcf660010 pos:0 ino:6235 sdev:17
tfd: 13 events: 19 data: 563bcf660050 pos:0 ino:3509 sdev:e
//时间描述符
root@ubuntu:/proc/1# cat fdinfo/28
pos: 0
flags: 02004002
mnt_id: 15
ino: 13577
clockid: 1
ticks: 0
settime flags: 01
it_value: (74, 678839584)
it_interval: (0, 0)
这是一个子目录,包含进程打开的每个文件的一个条目,由其文件描述符命名。此目录下的文件仅由进程的所有者可读。可以读取每个文件的内容以获得有关相应文件描述符的信息。内容取决于对应的文件描述符所引用的文件类型。对于常规文件和目录,我们会看到值,其含义是:
值 | 例子 | 含义 |
---|---|---|
pos | pos: 0 | 这是一个十进制数字,显示文件偏移量。 |
flags | flags: 02000002 | 这是一个八进制数,显示文件访问模式和文件状态标志(参见open(2))。如果设置了close-on-exec文件描述符标志,则标志还将包括值O_CLOEXEC。 |
mnt_id | mnt_id: 15 | 该字段是包含该文件的挂载点的ID,具体请参见/proc/[pid]/mountinfo的描述。 |
eventfd-count | eventfd-count: 40 | eventfd文件描述符特有,eventfd-count是eventfd计数器的当前值,以十六进制表示。 |
tfd | tfd: 10 events: 80000019 data: 563bcf660010 pos:0 ino:6235 sdev:17 | epoll文件描述符特有,以tfd开头的每一行都描述了通过epoll文件描述符监视的一个文件描述符(有关详细信息,请参阅epoll_ctl(2))。tfd字段是文件描述符的编号。events字段是此文件描述符正在监视的事件的十六进制掩码。data字段是与此文件描述符关联的数据值。 |
sigmask | sigmask: 0000000000000006 | signalfd文件描述符,Sigmask是通过signalfd文件描述符接受的信号的十六进制掩码。(在本例中,位2和位3被设置,分别对应信号SIGINT和SIGQUIT;看到信号(7))。 |
inotify wd | inotify wd:2 ino:7ef82a sdev:800001 mask:800afff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:2af87e00220ffd73 | wd表示描述符编号(十进制)。ino表示目标文件的inode号,16进制。sdev表示目标文件所在的设备ID(十六进制)。mask表示目标文件被监控事件的掩码(十六进制)。 |
ino | ino: 13577 | 目标文件的inode号(十六进制)。 |
clockid | clockid: 1 | 这是时钟ID的数值,用于标记计时器的进度。 |
ticks | ticks: 0 | 这是已经发生的计时器过期次数(即读取(2)后返回的值)。 |
settime flags | settime flags: 01 | 这个字段列出了timerfd最后一次设置的标志,以八进制为单位 |
it_value | it_value: (74, 678839584) | 此字段包含计时器下一次到期之前的时间量,以秒和纳秒表示。无论计时器是否使用TFD_TIMER_ABSTIME标志创建,它总是以相对值表示。 |
it_interval | it_interval: (0, 0) | 该字段包含计时器的间隔,以秒和纳秒为单位。(it_value和it_interval字段包含该文件描述符上timerfd_gettime(2)将返回的值。) |
1.1.17 /proc/[pid]/gid_map
root@ubuntu:/proc/1# cat gid_map
0 0 4294967295
该文件可以看到进程从用户命名空间映射的组ID的信息。这三个数字含义:
第一个数字:进程pid所在的用户命名空间中用户起始ID。
第二个数字:这里如何解释取决于打开uid_map的进程和进程pid是否在同一个用户命名空间中
- 如果这两个进程在不同的用户名称空间中,第二个数字是打开uid_map的进程的用户名称空间中用户id范围的开始。
- 如果两个进程属于同一个用户命名空间,第二个数字是进程pid的父用户命名空间中用户id范围的开始。这种情况允许uid_map的打开器(这里常见的情况是打开/proc/self/uid_map)查看用户id到创建该用户名称空间的进程的用户名称空间的映射。
第三个数字:映射在两个用户名称空间之间的用户id范围的长度。这里4294967295表示负一。
1.1.18 /proc/[pid]/io
root@ubuntu:/proc/1# cat io
rchar: 1737528570
wchar: 1510335625
syscr: 337293
syscw: 257345
read_bytes: 459443712
write_bytes: 703746048
cancelled_write_bytes: 92532736
该文件包含进程的I/O统计信息,文件中个字段含义如下:
字段 | 全称 | 含义 |
---|---|---|
rchar | characters read | 进程从存储器中读取的字节数。这只是该进程传递给read(2)和类似系统调用的字节之和。它包括像终端I/O这样的东西,并且不受是否需要实际的物理磁盘I/O的影响(读取可能已经从页面缓存中得到满足)。 |
wchar | characters written | 进程已经或将写入磁盘的字节数。这里的注意事项与rchar类似 |
syscr | read syscalls | 统计通过read和pread这样的系统调用尝试读I/O操作的数量 |
syscw | write syscalls | 统计通过write和pwrite这样的系统调用尝试读I/O操作的数量 |
read_bytes | bytes read | 计算该进程实际从存储层获取的字节数。这对于块支持的文件系统是准确的。 |
write_bytes | bytes written | 计算此进程实际发送到存储层的字节数。 |
cancelled_write_bytes | cancelled write bytes | 这个字段表示这个进程通过截断页缓存导致不发生的字节数。任务也可能导致“负”I/O。如果这个进程截断了某个脏页缓存,那么另一个进程(在它的write_bytes中)占用的某个I/O将不会发生。 |
1.1.19 /proc/[pid]/limits
root@ubuntu:/proc/1# cat limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 31362 31362 processes
Max open files 1048576 1048576 files
Max locked memory 67108864 67108864 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 31362 31362 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
该文件显示每个进程的资源限制的软限制、硬限制和度量单位(请参阅getrlimit(2))。
1.1.20 /proc/[pid]/loginuid
root@ubuntu:/proc/1# cat loginuid
4294967295
root@ubuntu:/proc/1#
root@ubuntu:/proc/1# cat ../1909/loginuid
1000
root@ubuntu:/proc/1#
4294967295只是(无符号长整数)-1。-1表示未设置loginuid。这是任何登录过程未生成的进程的正常行为(例如,守护进程和内核进程)。loginuid默认为-1;pam_loginuid模块在您登录时(在tty / in DM / via ssh中)将其更改为您的用户ID,并且子进程会保留此值。
root@ubuntu:/proc/1# cat /etc/passwd |grep 1000
jian:x:1000:1000:jian,,,:/home/jian:/bin/bash
1000表示用户jian,登录过。
1.1.21 /proc/[pid]/map_files
root@ubuntu:/proc/1# ll map_files/
total 0
dr-x------ 2 root root 0 Jan 14 07:08 ./
dr-xr-xr-x 9 root root 0 Jan 14 05:17 ../
lr-------- 1 root root 64 Jan 14 22:10 563bcd968000-563bcd99a000 -> /usr/lib/systemd/systemd*
lr-------- 1 root root 64 Jan 14 22:10 563bcd99a000-563bcda58000 -> /usr/lib/systemd/systemd*
lr-------- 1 root root 64 Jan 14 22:10 563bcda58000-563bcdaae000 -> /usr/lib/systemd/systemd*
lr-------- 1 root root 64 Jan 14 22:10 563bcdaae000-563bcdaf4000 -> /usr/lib/systemd/systemd*
lr-------- 1 root root 64 Jan 14 22:10 563bcdaf4000-563bcdaf5000 -> /usr/lib/systemd/systemd*
lr-------- 1 root root 64 Jan 14 22:10 7fe5fc70c000-7fe5fc719000 -> /usr/lib/x86_64-linux-gnu/libm-2.31.so
lr-------- 1 root root 64 Jan 14 22:10 7fe5fc719000-7fe5fc7c0000 -> /usr/lib/x86_64-linux-gnu/libm-2.31.so
lr-------- 1 root root 64 Jan 14 22:10 7fe5fc7c0000-7fe5fc859000 -> /usr/lib/x86_64-linux-gnu/libm-2.31.so
lr-------- 1 root root 64 Jan 14 22:10 7fe5fc859000-7fe5fc85a000 -> /usr/lib/x86_64-linux-gnu/libm-2.31.so
lr-------- 1 root root 64 Jan 14 22:10 7fe5fc85a000-7fe5fc85b000 -> /usr/lib/x86_64-linux-gnu/libm-2.31.so
...
lr-------- 1 root root 64 Jan 14 22:10 7fe5fd75a000-7fe5fd75b000 -> /usr/lib/x86_64-linux-gnu/ld-2.31.so*
这个子目录包含与内存映射文件对应的条目(参见mmap(2))。条目由内存区域的开始和结束地址对命名(用十六进制数表示),并且是到映射文件本身的符号链接。
1.1.22 /proc/[pid]/maps
root@ubuntu:/proc/1# cat maps
563bcd968000-563bcd99a000 r--p 00000000 08:05 32773659 /usr/lib/systemd/systemd
563bcd99a000-563bcda58000 r-xp 00032000 08:05 32773659 /usr/lib/systemd/systemd
563bcda58000-563bcdaae000 r--p 000f0000 08:05 32773659 /usr/lib/systemd/systemd
563bcdaae000-563bcdaf4000 r--p 00145000 08:05 32773659 /usr/lib/systemd/systemd
563bcdaf4000-563bcdaf5000 rw-p 0018b000 08:05 32773659 /usr/lib/systemd/systemd
563bcf65b000-563bcf8f1000 rw-p 00000000 00:00 0 [heap]
7fe5fc70c000-7fe5fc719000 r--p 00000000 08:05 32774684 /usr/lib/x86_64-linux-gnu/libm-2.31.so
...
7fe5fd72c000-7fe5fd72d000 r--p 00000000 08:05 32773810 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fe5fd72d000-7fe5fd750000 r-xp 00001000 08:05 32773810 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fe5fd750000-7fe5fd758000 r--p 00024000 08:05 32773810 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fe5fd759000-7fe5fd75a000 r--p 0002c000 08:05 32773810 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fe5fd75a000-7fe5fd75b000 rw-p 0002d000 08:05 32773810 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fe5fd75b000-7fe5fd75c000 rw-p 00000000 00:00 0
7ffeefc06000-7ffeefd08000 rw-p 00000000 00:00 0 [stack]
7ffeefd42000-7ffeefd46000 r--p 00000000 00:00 0 [vvar]
7ffeefd46000-7ffeefd48000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
该文件包含当前映射的内存区域及其访问权限的文件。
1.1.23 /proc/[pid]/mem
该文件可用于通过open(2)、read(2)和lseek(2)访问进程内存中的页面。
1.1.24 /proc/[pid]/mountinfo
root@ubuntu:/proc/1# cat mountinfo
24 29 0:22 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw
25 29 0:23 / /proc rw,nosuid,nodev,noexec,relatime shared:14 - proc proc rw
...
该文件包含有关进程的挂载命名空间中的挂载点的信息。它提供了各种信息(例如,传播状态,绑定挂载的挂载根,每个挂载及其父挂载的标识符)。每一部分的含义如下表格所示,这里以第一行输出结果来讲解:
24 29 0:22 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw
项目 | 值 | 含义 |
---|---|---|
mount ID | 24 | 挂载的唯一ID ,umount后可以重复使用 |
parent ID | 29 | 父挂载的ID |
major:minor | 0:22 | 这个文件系统上文件的st_dev的值 |
root | / | 文件系统中构成这个挂载的根目录的路径名 |
mount point | /sys | 挂载点相对于进程根目录的路径名 |
mount options | rw,nosuid,nodev,noexec,relatime | 每次挂载选项 |
optional fields | shared:7 | 0个或多个“tag[:value]”形式的字段 |
separator | - | 可选字段的末尾用一个连字符标记,用作分隔符 |
filesystem type | sysfs | 格式为“type[.subtype]”的文件系统类型 |
mount source | sysfs | 文件系统特定的信息或“none” |
super options | rw | 每个超级块的选项 |
1.1.25 /proc/[pid]/mounts
root@ubuntu:/proc/1# cat mounts
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
udev /dev devtmpfs rw,nosuid,noexec,relatime,size=4014420k,nr_inodes=1003605,mode=755,inode64 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /run tmpfs rw,nosuid,nodev,noexec,relatime,size=810584k,mode=755,inode64 0 0
/dev/sda5 / ext4 rw,relatime,errors=remount-ro 0 0
securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev,inode64 0 0
tmpfs /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k,inode64 0 0
tmpfs /sys/fs/cgroup tmpfs ro,nosuid,nodev,noexec,mode=755,inode64 0 0
cgroup2 /sys/fs/cgroup/unified cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate 0 0
cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,name=systemd 0 0
pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0
bpf /sys/fs/bpf bpf rw,nosuid,nodev,noexec,relatime,mode=700 0 0
...
该文件列出当前挂载在进程的挂载名称空间中的所有文件系统。
1.1.26 /proc/[pid]/mountstats
root@ubuntu:/proc/1# cat mountstats
device sysfs mounted on /sys with fstype sysfs
device proc mounted on /proc with fstype proc
device udev mounted on /dev with fstype devtmpfs
device devpts mounted on /dev/pts with fstype devpts
device tmpfs mounted on /run with fstype tmpfs
device /dev/sda5 mounted on / with fstype ext4
device securityfs mounted on /sys/kernel/security with fstype securityfs
device tmpfs mounted on /dev/shm with fstype tmpfs
device tmpfs mounted on /run/lock with fstype tmpfs
device tmpfs mounted on /sys/fs/cgroup with fstype tmpfs
device cgroup2 mounted on /sys/fs/cgroup/unified with fstype cgroup2
device cgroup mounted on /sys/fs/cgroup/systemd with fstype cgroup
device pstore mounted on /sys/fs/pstore with fstype pstore
device bpf mounted on /sys/fs/bpf with fstype bpf
device cgroup mounted on /sys/fs/cgroup/cpuset with fstype cgroup
。。。
该文件导出进程的挂载名称空间中有关挂载点的信息(统计信息、配置信息)。该文件仅由进程的所有者可读。
1.1.27 /proc/[pid]/net
此目录包含各种文件和子目录,其中包含有关网络层的信息。更详细的请看后面的/proc]/net章节。
1.1.28 /proc/[pid]/ns
root@ubuntu:/proc/1# ls -l ns
total 0
lrwxrwxrwx 1 root root 0 Jan 15 03:48 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jan 15 03:48 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Jan 15 03:48 mnt -> 'mnt:[4026531841]'
lrwxrwxrwx 1 root root 0 Jan 15 03:48 net -> 'net:[4026531840]'
lrwxrwxrwx 1 root root 0 Jan 15 03:48 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jan 15 03:48 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jan 15 03:48 time -> 'time:[4026531834]'
lrwxrwxrwx 1 root root 0 Jan 15 03:48 time_for_children -> 'time:[4026531834]'
lrwxrwxrwx 1 root root 0 Jan 15 03:48 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jan 15 03:48 uts -> 'uts:[4026531838]'
该文件导出进程的命名名称空间中个空间的信息。
1.1.29 /proc/[pid]/numa_maps
root@ubuntu:/proc/1# cat numa_maps
563bcd968000 default file=/usr/lib/systemd/systemd mapped=50 mapmax=2 N0=50 kernelpagesize_kB=4
563bcd99a000 default file=/usr/lib/systemd/systemd mapped=189 mapmax=3 N0=189 kernelpagesize_kB=4
563bcda58000 default file=/usr/lib/systemd/systemd mapped=66 mapmax=3 N0=66 kernelpagesize_kB=4
563bcdaae000 default file=/usr/lib/systemd/systemd anon=63 dirty=63 mapmax=2 active=0 N0=63 kernelpagesize_kB=4
563bcdaf4000 default file=/usr/lib/systemd/systemd anon=1 dirty=1 active=0 N0=1 kernelpagesize_kB=4
563bcf65b000 default heap anon=602 dirty=602 mapmax=2 active=0 N0=602 kernelpagesize_kB=4
7fe5ec000000 default anon=3 dirty=3 active=0 N0=3 kernelpagesize_kB=4
7fe5ec021000 default
7fe5f4000000 default anon=3 dirty=3 active=0 N0=3 kernelpagesize_kB=4
7fe5f4021000 default
7fe5fb703000 default
7fe5fb704000 default anon=2 dirty=2 active=0 N0=2 kernelpagesize_kB=4
7fe5fbf04000 default
7fe5fbf05000 default anon=8 dirty=8 mapmax=2 active=0 N0=8 kernelpagesize_kB=4
7fe5fc70c000 default file=/usr/lib/x86_64-linux-gnu/libm-2.31.so mapped=12 mapmax=72 N0=12 kernelpagesize_kB=4
7fe5fc719000 default file=/usr/lib/x86_64-linux-gnu/libm-2.31.so mapped=62 mapmax=69 N0=62 kernelpagesize_kB=4
1.1.30 /proc/[pid]/oom_adj
root@ubuntu:/proc/1# cat oom_adj
0
该文件可用于调整用于选择在内存不足(OOM)情况下应该杀死哪个进程的分数。内核使用这个值对进程的oom_score值进行位移位操作:有效值在-16到+15之间,加上特殊值-17,这将完全禁用该进程的oom_score。一个大于0的分数增加了这个进程被oom杀手杀死的可能性;小于0的分数会降低这种可能性。这个文件的默认值是0,一个新的进程继承其父进程的oom_adj设置。但是,自Linux 2.6.36以来,这个文件的使用已弃用,取而代之的是/proc/[pid]/oom_score_adj。
1.1.31 /proc/[pid]/oom_score
root@ubuntu:/proc/1# cat oom_score
0
该文件显示内核为选择OOM-killer进程而提供给该进程的当前分数。得分越高,意味着该流程更有可能被oom杀手选中。该分数的基础是进程使用的内存量,增加(+)或减少(-)的因素包括:
- 这个过程是否使用fork创建了很多子进程(+)
- 进程是否运行了很长时间,或者占用了大量的CPU时间(-)
- 进程是否有一个低nice值,也就是> 0的nice值(+)
- 进程是否直接进行硬件访问(-)
1.1.32 /proc/[pid]/oom_score_adj
root@ubuntu:/proc/1# cat oom_score_adj
0
此文件可用于调整用于选择在内存不足条件下杀死哪个进程的。坏度启发式为每个候选任务分配一个值,范围从0(从不终止)到1000(总是终止),以确定哪个进程是目标进程。这些单元大致是进程可能分配的允许内存范围内的一个比例,基于对当前内存和交换使用的估计。例如,如果一个任务正在使用所有允许的内存,那么它的不良评分将是1000。如果它正在使用其允许内存的一半,它的分数将是500。在不良评分中还有一个额外的因素:根进程比其他任务多获得3%的内存。
1.1.33 /proc/[pid]/pagemap
该文件显示了进程的每个虚拟页到物理页帧或交换区域的映射。它为每个虚拟页面包含一个64位值,位的设置如下:
bit | 含义 |
---|---|
63 | 如果置一,表示该页存在于RAM中 |
62 | 如果置一,表示该页存在于交换空间中 |
61 | 表示该页面为文件映射页面或共享匿名页面。 |
57-60 | 零 |
56 | 如果置一,表示页面是独占映射的。 |
55 | 如果置一,表示PTE是脏的 |
0-54 | 如果页面在RAM中(位63),那么这些位提供页帧号,可以用来索引/proc/kpageflags和/proc/kpagecount。如果页面出现在交换中(第62位),那么第4-0位给出交换类型,第54-5位编码交换偏移量。 |
使用下面的代码编译成程序,可以通过这个虚拟地址对应的物理地址:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#define PAGEMAP_ENTRY 8
#define GET_BIT(X,Y) (X & ((uint64_t)1<<Y)) >> Y
#define GET_PFN(X) X & 0x7FFFFFFFFFFFFF
const int __endian_bit = 1;
#define is_bigendian() ( (*(char*)&__endian_bit) == 0 )
int i, c, pid, status;
unsigned long virt_addr;
uint64_t read_val, file_offset, page_size;
char path_buf [0x100] = {};
FILE * f;
char *end;
int read_pagemap(char * path_buf, unsigned long virt_addr);
int main(int argc, char ** argv){
if(argc!=3){
printf("Argument number is not correct!\n pagemap PID VIRTUAL_ADDRESS\n");
return -1;
}
if(!memcmp(argv[1],"self",sizeof("self"))){
sprintf(path_buf, "/proc/self/pagemap");
pid = -1;
}
else{
pid = strtol(argv[1],&end, 10);
if (end == argv[1] || *end != '\0' || pid<=0){
printf("PID must be a positive number or 'self'\n");
return -1;
}
}
virt_addr = strtoll(argv[2], NULL, 16);
if(pid!=-1)
sprintf(path_buf, "/proc/%u/pagemap", pid);
page_size = getpagesize();
read_pagemap(path_buf, virt_addr);
return 0;
}
int read_pagemap(char * path_buf, unsigned long virt_addr){
printf("Big endian? %d\n", is_bigendian());
f = fopen(path_buf, "rb");
if(!f){
printf("Error! Cannot open %s\n", path_buf);
return -1;
}
//Shifting by virt-addr-offset number of bytes
//and multiplying by the size of an address (the size of an entry in pagemap file)
file_offset = virt_addr / page_size * PAGEMAP_ENTRY;
printf("Vaddr: 0x%lx, Page_size: %lld, Entry_size: %d\n", virt_addr, page_size, PAGEMAP_ENTRY);
printf("Reading %s at 0x%llx\n", path_buf, (unsigned long long) file_offset);
status = fseek(f, file_offset, SEEK_SET);
if(status){
perror("Failed to do fseek!");
return -1;
}
errno = 0;
read_val = 0;
unsigned char c_buf[PAGEMAP_ENTRY];
for(i=0; i < PAGEMAP_ENTRY; i++){
c = getc(f);
if(c==EOF){
printf("\nReached end of the file\n");
return 0;
}
if(is_bigendian())
c_buf[i] = c;
else
c_buf[PAGEMAP_ENTRY - i - 1] = c;
printf("[%d]0x%x ", i, c);
}
for(i=0; i < PAGEMAP_ENTRY; i++){
//printf("%d ",c_buf[i]);
read_val = (read_val << 8) + c_buf[i];
}
printf("\n");
printf("Result: 0x%llx\n", (unsigned long long) read_val);
if(GET_BIT(read_val, 63)) {
uint64_t pfn = GET_PFN(read_val);
printf("PFN: 0x%llx (0x%llx)\n", pfn, pfn * page_size + virt_addr % page_size);
} else
printf("Page not present\n");
if(GET_BIT(read_val, 62))
printf("Page swapped\n");
fclose(f);
return 0;
}
通过gcc编译后,执行如下命令,aa就是程序的名字,1表示进程号,0x7fe5fd529000表示虚拟地址:
jian@ubuntu:~$ sudo ./aa 1 0x7fe5fd529000
[sudo] password for jian:
Big endian? 0
Vaddr: 0x7fe5fd529000, Page_size: 4096, Entry_size: 8
Reading /proc/1/pagemap at 0x3ff2fea948
[0]0xb2 [1]0x4c [2]0x23 [3]0x0 [4]0x0 [5]0x0 [6]0x80 [7]0xa0
Result: 0xa080000000234cb2
PFN: 0x234cb2 (0x234cb2000)
1.1.34 /proc/[pid]/patch_state
root@ubuntu:/proc/1# cat patch_state
-1
1.1.35 /proc/[pid]/personality
root@ubuntu:/proc/1# cat personality
00000000
这个只读文件公开了进程的执行域,十六进制显示。也就是说允许哪个cpu执行。00000000表示全部cpu可以执行,00000001表示cpu0不可以执行。
1.1.36 /proc/[pid]/projid_map
root@ubuntu:/proc/1# cat projid_map
0 0 4294967295
1.1.37 /proc/[pid]/root
root@ubuntu:/proc/1# ll root
lrwxrwxrwx 1 root root 0 Jan 14 05:17 root -> //
Linux支持文件系统的每进程根,由chroot系统调用设置。该文件是一个指向进程根目录的符号链接,其行为与exe和fd/*相同。
1.1.38 /proc/[pid]/sched
root@ubuntu:/proc/1# cat sched
systemd (1, #threads: 1)
-------------------------------------------------------------------
se.exec_start : 94545997.349824
se.vruntime : 1579.667011
se.sum_exec_runtime : 3553.995528
se.nr_migrations : 533
nr_switches : 10311
nr_voluntary_switches : 8374
nr_involuntary_switches : 1937
se.load.weight : 1048576
se.avg.load_sum : 1109
se.avg.runnable_sum : 1136355
se.avg.util_sum : 1074578
se.avg.load_avg : 16
se.avg.runnable_avg : 16
se.avg.util_avg : 15
se.avg.last_update_time : 94545997348864
se.avg.util_est.ewma : 37
se.avg.util_est.enqueued : 15
uclamp.min : 0
uclamp.max : 1024
effective uclamp.min : 0
effective uclamp.max : 1024
policy : 0
prio : 120
clock-delta : 17
mm->numa_scan_seq : 0
numa_pages_migrated : 0
numa_preferred_nid : -1
total_numa_faults : 0
current_node=0, numa_group_id=0
numa_faults node=0 task_private=0 task_shared=0 group_private=0 group_shared=0
可以查看进程的调度实体相关的信息。
se.exec_start 是各个调度类维护的时间线信息,两者都频繁更新,cat sched文件中的这个字段没啥参考意义了。
se.vruntime是cfs调度的虚拟时间。
se.sum_exec_runtime表示任务运行的总时间。
se.nr_migrations 记录任务在不同CPU间迁移的次数。
sum_sleep_runtime 统计的是任务测试时间段内 sleep 和 block 两种休眠状态的的时长之和。
nr_switches 表示被切走的总次数 。
nr_voluntary_switches 表示非抢占任务被切走的次数。
nr_involuntary_switches 表示被抢占而导致的任务被切走的次数。
se.load.weight 表示CFS任务的权重,和其优先级挂钩,优先级变化了也会设置 。
policy 表示进程的调度策略。
prio 表示进程的优先级,RT: 0-99,CFS: 100-139,数值越小优先级越高。
clock-delta 是记录一次读取CPU时间需要的时长,涉及到读取硬件,测试发现和 CPU 频点高低无线性关系。
1.1.39 /proc/[pid]/schedstat
root@ubuntu:/proc/1# cat schedstat
3573454261 414543036 10366
1.1.40 /proc/[pid]/sessionid
root@ubuntu:/proc/1# cat sessionid
4294967295
1.1.41 /proc/[pid]/setgroups
root@ubuntu:/proc/1# cat setgroups
allow
该文件用于限制使用setgroups函数设置group的权限,默认是“allow”,此值只能被设置一次,后续设置将会返回错误。
1.1.42 /proc/[pid]/smaps
root@ubuntu:/proc/1# cat smaps
563bcd968000-563bcd99a000 r--p 00000000 08:05 32773659 /usr/lib/systemd/systemd
Size: 200 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 200 kB
Pss: 100 kB
Shared_Clean: 200 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 200 kB
Anonymous: 0 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd mr mw me sd
563bcd99a000-563bcda58000 r-xp 00032000 08:05 32773659 /usr/lib/systemd/systemd
Size: 760 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 756 kB
Pss: 353 kB
Shared_Clean: 756 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 756 kB
Anonymous: 0 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd ex mr mw me sd
...
该文件显示了每个进程映射的内存消耗详细情况。
第一行显示的信息与/proc/[pid]/maps中的映射显示的信息相同。下面几行显示了映射的大小、当前驻留在RAM中的映射数量(“Rss”)、进程在该映射中的比例份额(“Pss”)、映射中干净的共享页和不干净的共享页的数量,以及映射中干净的私有页和不干净的私有页的数量。“Referenced”表示当前标记为引用或访问的内存量。“Anonymous”显示不属于任何文件的内存量。“Swap”显示了有多少匿名内存也被使用了,但是在交换时被释放了。“KernelPageSize”行是内核用于备份虚拟内存区域的页大小。“MMUPageSize”行报告MMU使用的页面大小。“Locked”表示映射是否锁定在内存中。“ProtectionKey”行包含与虚拟内存区域相关的内存保护键。“VmFlags”行表示与虚拟内存区域相关的内核标志。
1.1.43 /proc/[pid]/smaps_rollup
root@ubuntu:/proc/1# cat smaps_rollup
563bcd968000-7ffeefd48000 ---p 00000000 00:00 0 [rollup]
Rss: 12784 kB
Pss: 5236 kB
Pss_Anon: 3982 kB
Pss_File: 1254 kB
Pss_Shmem: 0 kB
Shared_Clean: 8308 kB
Shared_Dirty: 924 kB
Private_Clean: 32 kB
Private_Dirty: 3520 kB
Referenced: 12784 kB
Anonymous: 4444 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
该文件可以提高用户程序的性能,这些用户程序决定一个进程的聚合内存统计数据(例如,总PSS)。
1.1.44 /proc/[pid]/stack
root@ubuntu:/proc/1# cat stack
[<0>] ep_poll+0x55b/0x6a0
[<0>] do_epoll_wait+0xba/0xe0
[<0>] __x64_sys_epoll_wait+0x59/0x90
[<0>] do_syscall_64+0x59/0xc0
[<0>] entry_SYSCALL_64_after_hwframe+0x61/0xcb
该文件提供了该进程内核堆栈中函数调用的符号跟踪。
1.1.45 /proc/[pid]/stat
root@ubuntu:/proc/1# cat stat
1 (systemd) S 0 1 1 0 -1 4194560 65530 9078825 158 7113 57 302 12565 8530 20 0 1 0 70 173490176 3196 18446744073709551615 94814852456448 94814853234277 140732921837168 0 0 0 671173123 4096 1260 1 0 0 17 1 0 0 0 0 0 94814853587856 94814853873704 94814882607104 140732921839318 140732921839343 140732921839343 140732921839597 0
该文件记录进程的状态信息。每一个数字都有自己的含义。
1.1.46 /proc/[pid]/statm
root@ubuntu:/proc/1# cat statm
42356 3196 2085 190 0 5182 0
提供有关内存使用情况的信息(以页为单位)。
第一个数字表示程序总大小。
第二个数字表示常驻集大小
第三个数字表示常驻共享页的数量。
第四个数字表示代码段大小。
第五个数字表示库大小,不过现在没有使用了,一直是0。
第六个数字表示数据段和栈的总和
第七个数字表示脏页数量,不过现在没有使用了,一直是0。
1.1.47 /proc/[pid]/status
root@ubuntu:/proc/1# cat status
Name: systemd //该进程执行的命令
Umask: 0000 //进程Umask标志,以八进制形式表示,前导为零;
State: S (sleeping) //进程的当前状态。“R(运行)”、“S(休眠)”、“D(磁盘休眠)”、“T(停止)”、“T(跟踪停止)”、“Z(僵尸)”或“X(死亡)”之一。
Tgid: 1 //线程组ID(即进程ID)。
Ngid: 0 //NUMA组ID
Pid: 1 //线程ID
PPid: 0 //父进程PID。
TracerPid: 0 //跟踪该进程的PID(如果没有跟踪则为0)。
Uid: 0 0 0 0 //真实的,有效的,保存的集合,和文件系统Uid (Gid)。
Gid: 0 0 0 0 //
FDSize: 512 //当前分配的文件描述符插槽数。
Groups: //补充分组列表
NStgid: 1 //
NSpid: 1 //
NSpgid: 1 //
NSsid: 1 //
VmPeak: 233384 kB //峰值虚拟内存大小
VmSize: 169424 kB //虚拟内存大小
VmLck: 0 kB //锁定内存大小
VmPin: 0 kB //固定内存大小这些页面不能移动,因为需要直接访问物理内存。
VmHWM: 12784 kB //峰值常驻集大小(“高水位标志”)
VmRSS: 12784 kB //常驻集大小。注意,这里的值是RssAnon、RssFile和RssShmem的和
RssAnon: 4444 kB //常驻匿名内存的大小
RssFile: 8340 kB //常驻文件映射的大小
RssShmem: 0 kB //常驻共享内存的大小
VmData: 19696 kB //数据段的大小
VmStk: 1032 kB //堆栈的大小
VmExe: 760 kB //文本段的大小
VmLib: 9552 kB //共享库代码大小
VmPTE: 88 kB //页表项大小
VmSwap: 0 kB //通过匿名私有页面交换出虚拟内存大小
HugetlbPages: 0 kB // hugetlb内存部分的大小(
CoreDumping: 0 //如果进程当前正在转储内核,则值为1
THP_enabled: 1 //
Threads: 1 //包含该线程的进程中的线程数
SigQ: 0/31362 //该字段包含两个以斜杠分隔的数字,。第一个是该真实用户ID当前排队的信号数量,第二个是该进程排队信号数量的资源限制
SigPnd: 0000000000000000 //线程待定信号的掩码
ShdPnd: 0000000000000000 //进程待定信号的掩码
SigBlk: 7be3c0fe28014a03 //表示信号被阻塞的掩码
SigIgn: 0000000000001000 //表示信号被忽略的掩码
SigCgt: 00000001800004ec //表示信号捕获的掩码
CapInh: 0000000000000000 //在可继承集中启用的能力的掩码
CapPrm: 000001ffffffffff //在允许集中启用的能力的掩码
CapEff: 000001ffffffffff //在有效集中启用的能力的掩码
CapBnd: 000001ffffffffff //能力边界集,以十六进制表示
CapAmb: 0000000000000000 //环境能力集,以十六进制表示
NoNewPrivs: 0 //no_new_privs位的值
Seccomp: 0 //进程的Seccomp模式;0表示SECCOMP_MODE_DISABLED;1表示SECCOMP_MODE_STRICT;2表示SECCOMP_MODE_FILTER。
Seccomp_filters: 0 //
Speculation_Store_Bypass: thread vulnerable //推测缺陷缓解状态
SpeculationIndirectBranch: conditional enabled //
Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff //该进程可能运行的cpu的十六进制掩码
Cpus_allowed_list: 0-127 //和前面一样,但是是“列表格式”
Mems_allowed: // 允许该进程运行的内存节点掩码00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0 //和前面一样,但是是“列表格式”
voluntary_ctxt_switches: 8489 //自愿上下文切换的数量
nonvoluntary_ctxt_switches: 1946 //非自愿上下文切换的数量
root@ubuntu:/proc/1#
1.1.48 /proc/[pid]/syscall
root@ubuntu:/proc/1# cat syscall
232 0x4 0x563bcf846950 0x90 0xffffffff 0x0 0x3a10 0x7ffeefd070f0 0x7fe5fd64846e
该文件显示系统调用号码和当前进程正在执行的系统调用的参数寄存器,以及堆栈指针和程序计数器寄存器的值。
1.1.49 /proc/[pid]/task
这个目录为进程中的每个线程包含一个子目录。每个子目录的名称是线程的数字线程ID 。在每个子目录中,都有一组与/proc/[pid]目录下具有相同名称和内容的文件。对于所有线程共享的属性,task/[tid]子目录下的每个文件的内容将与父/proc/[pid]目录下的相应文件中的内容相同。对于每个线程都不同的属性,task/[tid]下的相应文件可能有不同的值,或者它们可能根本不存在于/proc/[pid]中。
1.1.50 /proc/[pid]/timens_offsets
root@ubuntu:/proc/1# cat timens_offsets
monotonic 0 0
boottime 0 0
1.1.51 /proc/[pid]/timers
1.1.52 /proc/[pid]/timerslack_ns
root@ubuntu:/proc/1# cat timerslack_ns
50000
1.1.53 /proc/[pid]/uid_map
root@ubuntu:/proc/1# cat uid_map
0 0 4294967295
1.1.54 /proc/[pid]/wchan
root@ubuntu:/proc/1# cat wchan
ep_poll
root@ubuntu:/proc/1#
进程在内核中休眠的位置对应的符号名。