/proc/[pid] 目录文件详解

proc是一个伪文件系统,它被用作内核数据结构的接口,通常被挂载在/proc上,大部分文件都是只读的,但是有一些文件允许内核变量修改。

下面介绍一下/proc的目录结构

/proc/[pid]

每个运行中的进程都有以一个数字命名的子目录,目录名是进程PID,每个这样的子目录包含了下面一些伪文件和目录。

/proc/[pid]/auxv

包含了传递给运行时进程的 ELF 解释器信息,格式是每一项都是一个 unsigned long长度的 ID 加上一个 unsigned long 长度的值。最后一项以连续的两个 0x00 开头。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ hexdump  /proc/15104/auxv 
0000000 0021 0000 0000 0000 8000 8168 7fff 0000
0000010 0010 0000 0000 0000 fbff bfeb 0000 0000
0000020 0006 0000 0000 0000 1000 0000 0000 0000
0000030 0011 0000 0000 0000 0064 0000 0000 0000
0000040 0003 0000 0000 0000 0040 0040 0000 0000
0000050 0004 0000 0000 0000 0038 0000 0000 0000
0000060 0005 0000 0000 0000 0009 0000 0000 0000
0000070 0007 0000 0000 0000 1000 c87a 7ff9 0000
0000080 0008 0000 0000 0000 0000 0000 0000 0000
0000090 0009 0000 0000 0000 0ce5 0042 0000 0000
00000a0 000b 0000 0000 0000 03e8 0000 0000 0000
00000b0 000c 0000 0000 0000 03e8 0000 0000 0000
00000c0 000d 0000 0000 0000 03e8 0000 0000 0000
00000d0 000e 0000 0000 0000 03e8 0000 0000 0000
00000e0 0017 0000 0000 0000 0000 0000 0000 0000
00000f0 0019 0000 0000 0000 0649 8168 7fff 0000
0000100 001a 0000 0000 0000 0000 0000 0000 0000
0000110 001f 0000 0000 0000 2fd2 8168 7fff 0000
0000120 000f 0000 0000 0000 0659 8168 7fff 0000
0000130 0000 0000 0000 0000 0000 0000 0000 0000
0000140

/proc/[pid]/cgroup

这个文件描述了归属进程/任务的资源控制信息,每个cgroup描述都是用:分割开的形式:

1
2
3
4
5
6
7
8
9
10
11
12
$ cat /proc/15104/cgroup 
11:memory:/user.slice
10:devices:/user.slice
9:blkio:/user.slice
8:freezer:/
7:net_prio,net_cls:/
6:perf_event:/
5:hugetlb:/
4:cpuacct,cpu:/user.slice
3:cpuset:/
2:pids:/
1:name=systemd:/user.slice/user-1000.slice/session-16754.scope

第一列是层次结构的ID,第二列是绑定到该层次结构的子系统集合,最后一列表示层次结构中的控制组属于哪个进程。需要注意的是这个文件只有在内核配置选项CONFIG_CGROUPS启用时才有。

/proc/[pid]/cmdline

这个文件保存了进程的完整命令行信息。如果这个进程是 僵尸进程,则这个文件没有任何内容。该文件以空字符 null 而不是换行符作为结束标志

/proc/[pid]/coredump_filter

进程coredump时,内核转储掩码设置的值

1
2
3
4
5
6
7
8
9
The following 7 memory types are supported:
- (bit 0) anonymous private memory(匿名私有内存段)
- (bit 1) anonymous shared memory(匿名共享内存段)
- (bit 2) file-backed private memory(file-backed 私有内存段)
- (bit 3) file-backed shared memory(file-bakced 共享内存段)
- (bit 4) ELF header pages in file-backed private memory areas (it is
effective only if the bit 2 is cleared)(ELF 文件映射,只有在bit 2 复位的时候才起作用)
- (bit 5) hugetlb private memory(大页面私有内存)
- (bit 6) hugetlb shared memory(大页面共享内存)

/proc/[pid]/cpuset

将进程限制在cpu的子集中

/proc/[pid]/cwd

这是进程当前工作目录的一个软链接,可以使用下面的命令找出当前进程的工作目录cd cwd/;/bin/pwd

1
cd /proc/[pid]/cwd/; /bin/pwd

/proc/[pid]/environ

这个文件包含了进程运行的环境变量

/proc/[pid]/exe

2.2版本之后的内核,这个文件是一个软链接,它指向执行命令的实际路径。该链接可以正常地被取消引用,如果尝试打开它将会被执行,你甚至可以输入/proc/[pid]/exe来运行一份[pid]进程的拷贝。在多线程处理器中,如果主线程已经退出,则符号链接的内容将会消失。

/proc/[pid]/fd/

这个子目录包含了进程打开的所有文件描述符的链接,每个链接指向实际的文件,因此0是标准输入1是标准输出2是标准错误输出等等

/proc/[pid]/fdinfo/

这个子目录包含了进程打开的文件描述符的入口,每个文件命名都是以描述符命名, 它包含了每个文件描述符可以读取的信息

/proc/[pid]/io

这个文件包含了进程的 I/O 统计信息

1
2
3
4
5
6
7
8
$ cat /proc/15104/io
rchar: 249358100 读出总字节数
wchar: 32820986 写入总字节数
syscr: 340344 读系统调用次数
syscw: 164979 写系统调用此时
read_bytes: 1064960 实际从磁盘读取的字节总数
write_bytes: 37273600 实际写入磁盘的字节总数
cancelled_write_bytes: 0 由于截断pagecache导致应该发生而没有发生的写入字节数

/proc/[pid]/limits

这个文件展示了每个进行的资源限制情况

/proc/[pid]/map_files/

这个子目录包含的项和mmap文件一致,每一项的名称为内存起止地址对,它指向实际的映射文件。

虽然这些项表示使用MAP_FILE标志映射的内存范围,但是通过MAP_ANON|MAP_SHARED标志创建的匿名共享内存也会出现在这个目录中,其目标文件是被删除的/dev/zero。

这个目录仅在内核选项CONFIG_CHECKPOINT_RESTORE 打开时才会出现

/proc/pid/maps

这个文件包含了当前映射的内存范围和它们的访问权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
address           perms offset  dev   inode       pathname
00400000-00583000 r-xp 00000000 fd:00 44151784 /usr/local/openresty/nginx/sbin/nginx.old
00782000-00783000 r--p 00182000 fd:00 44151784 /usr/local/openresty/nginx/sbin/nginx.old
00783000-007a1000 rw-p 00183000 fd:00 44151784 /usr/local/openresty/nginx/sbin/nginx.old
007a1000-007c4000 rw-p 00000000 00:00 0
0245d000-02569000 rw-p 00000000 00:00 0 [heap]
02569000-02633000 rw-p 00000000 00:00 0 [heap]
7ff9c2ee3000-7ff9c38e3000 rw-s 00000000 00:04 12807410 /dev/zero (deleted)
7ff9c38e3000-7ff9c4ce3000 rw-s 00000000 00:04 12807409 /dev/zero (deleted)
7ff9c4ce3000-7ff9c56e3000 rw-s 00000000 00:04 12807408 /dev/zero (deleted)
7ff9c56e3000-7ff9c5707000 r-xp 00000000 fd:00 34689365 /usr/lib64/libselinux.so.1
7ff9c5707000-7ff9c5906000 ---p 00024000 fd:00 34689365 /usr/lib64/libselinux.so.1
7ff9c5906000-7ff9c5907000 r--p 00023000 fd:00 34689365 /usr/lib64/libselinux.so.1
7ff9c5907000-7ff9c5908000 rw-p 00024000 fd:00 34689365 /usr/lib64/libselinux.so.1

访问权限位标识
r = read
w = write
x = execute
s = shared
p = private (copy on write)

如果pathname项是空的,则表示这是一个通过mmap的匿名映射

/proc/[pid]/mem

这个文件可以通过open/read来访问进程的内存页

/proc/[pid]/mountinfo

这个文件包含了挂载点信息

/proc/[pid]/mounts

当前进程的挂载命名空间中挂载的文件系统

/proc/[pid]/mountstats

这个文件导出了进程命名空间中挂载点的信息

/proc/[pid]/ns/

每个命名空间支持被setns操纵

/proc/[pid]/ns/ipc

绑定挂载这个文件到文件系统中其他位置,保留pid指定的进程IPC命名空间,及时当前命名空间中所有进程终止

/proc/[pid]/ns/net

绑定挂载这个文件到文件系统中其他位置,保留pid指定的进程网络命名空间,及时当前命名空间中所有进程终止

/proc/[pid]/ns/uts

绑定挂载这个文件到文件系统中其他位置,保留UTS指定的进程网络命名空间,及时当前命名空间中所有进程终止

/proc/[pid]/numa_maps

包含有关给定进程使用的每个存储区域的信息

/proc/[pid]/oom_adj

这个文件可以用来调整 oom killer选择应该被 kill的进程的分数。内核使用该值进行位移操作,该值范围是-16到15,该值越大表示在oom时越有可能被杀掉, -17表示永远不会被oom kill

默认值是0, 一个新的进程会继承父进程的 oom_adj设置,进程必须有特权才能修改这个文件

/proc/[pid]/oom_score

这个文件展示了当前内核给这个进程计算的选择OOM kill的分数, 这个分数越高,则越有可能被oom killer 选中。这个分数基于这个进程使用的内存数量,包括以下因素:

  • 这个进程是否创建了大量子进程
  • 这个进程是否运行了一长段时间,或者使用了大量的CPU时间
  • 这个进程是否有一个低的nice值
  • 这个进程是否有特权、
  • 这个进程是否有直接的硬件访问

oom_score也反映了oom_score_adj和oom_adj调整的结果

/proc/[pid]/oom_score_adj

在计算最终的 badness score 时,会在计算结果中加上 oom_score_adj ,这样用户就可以通过该在值来保护某个进程不被杀死或者每次都杀某个进程。其取值范围为-1000到1000 。

如果将该值设置为-1000,则进程永远不会被杀死,因为此时 badness score 永远返回0

/proc/[pid]/root

进程根目录的符号链接,linux支持每个进程一个root文件系统的方式。

在一个多线程处理器中,如果主线程退出了,这个软链接的内容也会消失

/proc/[pid]/smaps

这个文件列出了进程的每一个映射的内存消耗情况

/proc/[pid]/stat

ps命令会这用的进程的信息

/proc/[pid]/statm

提供进程的内存使用信息,以页为单位

/proc/[pid]/status

相较于/proc/[pid]/stat 和 /proc/[pid]/statm 提供更为丰富的格式化信息是的人类更易读

/proc/[pid]/task

进程中的每个线程有一个子目录,目录名为线程ID[TID]。每个子目录中有一系列和/proc/[pid]/目录下相同名字的文件。对应所有线程共享的属性,task/[tid]子目录中每个文件的内容和父目录/proc/[pid]中一致。对于每个线程独立的属性,task/[tid]目录中的文件可能会有不同的值。

您的支持将鼓励我继续创作!