使用 Linux 上的 proc 文件系统进行故障排除

proc 中的重要文件提供了关于运行进程的信息,这些信息将有助于调试和故障排除。
124 位读者喜欢这篇文章。
Bug tracking magnifying glass on computer screen

Pixabay, testbytes, CC0

proc 文件系统是 Linux 的一个重要特性,您不能忽视它。proc 是一个伪文件系统或虚拟文件系统,它为内核数据结构提供了一个接口。换句话说,proc 在现实世界的意义上并不是一个实际的文件系统;相反,它只驻留在内存中,而不是在磁盘上。它由系统自动挂载。

它的大部分内容是常规文件和目录,因此您可以使用大多数常规 Linux 工具来浏览 proc 文件系统。本文中的示例应该在任何 Linux 发行版上运行相同。我的系统使用

$ cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 7.8 (Maipo)
$
 
$ uname  -r
3.10.0-1127.el7.x86_64
$

proc 的基本用法

要找出 /proc 文件系统驻留在哪里,请运行 mount 命令并搜索 proc。在这里,您可以看到 proc 挂载在 /proc 目录下

$ mount | grep proc 
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=26,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=9506)
nfsd on /proc/fs/nfsd type nfsd (rw,relatime)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
$

进入 /proc 目录并浏览它。您将看到许多带有数字的目录;这些数字只是正在执行的进程的进程 ID(PID)。带有名称的文件是适用于系统范围的通用文件,与特定进程无关

$ cd /proc/
$ pwd
/proc
$ ls
1      157    22827  33    3413  3618  384   4709  512   5571  66    741   798   88         consoles     keys          scsi
10     15868  23     3340  3414  362   385   4768  513   5581  6723  742   799   880        cpuinfo      key-users     self
101    15900  23323  3341  3415  3622  39    4769  514   56    68    7466  8     891        crypto       kmsg          slabinfo
1033   16     23370  3342  346   363   392   4770  515   5637  69    747   80    9          devices      kpagecount    softirqs
104    17     23380  3343  3467  364   394   48    516   5652  7     75    800   906        diskstats    kpageflags    stat
10416  17580  23383  3344  347   365   4     4804  517   57    70    76    8367  928        dma          loadavg       swaps
105    18     23469  3346  349   37    40    4805  518   58    7071  77    839   96         driver       locks         sys
106    19     23491  3365  35    374   4094  4807  519   59    71    78    840   98         execdomains  mdstat        sysrq-trigger
107    2      23524  3366  351   375   4096  482   52    6     7199  783   842   9838       fb           meminfo       sysvipc
11     20767  23527  3392  352   376   41    483   53    601   72    784   8446  99         filesystems  misc          timer_list
11412  21     24     3397  3523  377   4180  49    5347  61    73    785   85    993        fs           modules       timer_stats
12     21014  26     3398  358   378   42    494   5348  62    735   786   86    994        interrupts   mounts        tty
120    21035  27     34    359   379   428   495   54    624   736   79    869   9970       iomem        mtrr          uptime
1263   21059  28     3408  36    38    43    508   5421  625   737   793   87    acpi       ioports      net           version
1265   21083  29     3409  360   380   44    509   5463  63    738   794   870   buddyinfo  ipmi         pagetypeinfo  vmallocinfo
1272   22     30     3410  3602  381   45    51    5464  636   739   795   874   bus        irq          partitions    vmstat
13     22055  31     3411  3603  382   46    510   5500  64    74    796   878   cgroups    kallsyms     sched_debug   zoneinfo
14     22074  32     3412  361   383   47    511   5519  65    740   797   879   cmdline    kcore        schedstat
$

首先浏览一些通用的系统范围文件。例如,/proc/cpuinfo 显示关于系统上 CPU 的信息——具体来说,它的制造商、型号、核心数、速度、CPU 标志等等。

$ cat /proc/cpuinfo

类似地,/proc/meminfo 提供关于系统上主内存或 RAM 的信息。它还提供额外的统计信息,例如已用内存、可用内存等等

$ cat /proc/meminfo

要查看所有已加载的内核模块,请查看 /proc/modules 文件

$ cat /proc/modules

要查看您的系统支持的所有文件系统,请查看 /proc/filesystems

$ cat /proc/filesystems

接下来,查看每个进程的文件;例如,systemd,它的 PID 为 1

$ ps aux | grep -i systemd | head -1
root         1  0.0  0.0 195976  9088 ?        Ss   Mar03   0:06 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
$

移动到 /proc 中名为 1 的目录,看看里面有什么。那里有很多文件,它们的名字在某种程度上是不言自明的

$ cd /proc/1
$ pwd
/proc/1
$

$ ls
attr        cmdline          environ  io         mem         ns             pagemap      sched      stack    task
autogroup   comm             exe      limits     mountinfo   numa_maps      patch_state  schedstat  stat     timers
auxv        coredump_filter  fd       loginuid   mounts      oom_adj        personality  sessionid  statm    uid_map
cgroup      cpuset           fdinfo   map_files  mountstats  oom_score      projid_map   setgroups  status   wchan
clear_refs  cwd              gid_map  maps       net         oom_score_adj  root         smaps      syscall
$

要找出这些文件是否为每个进程都存在,请选择当前的 shell ID。您可以通过运行 echo $$ 来获得该信息。$$ 是一个特殊变量,它保存当前 shell 的 PID。转到 /proccd 进入与 PID 相同的数字的目录。这些文件几乎与 PID 1 或 systemd 的文件相同

$ echo $$
21059
$
$ cd /proc/21059
$ pwd
/proc/21059
$
$ ls
attr        cmdline          environ  io         mem         ns             pagemap      sched      stack    task
autogroup   comm             exe      limits     mountinfo   numa_maps      patch_state  schedstat  stat     timers
auxv        coredump_filter  fd       loginuid   mounts      oom_adj        personality  sessionid  statm    uid_map
cgroup      cpuset           fdinfo   map_files  mountstats  oom_score      projid_map   setgroups  status   wchan
clear_refs  cwd              gid_map  maps       net         oom_score_adj  root         smaps      syscall
$

要查看这些文件包含什么,请运行一个长时间运行的进程。打开一个终端并运行 tty 命令以查看您正在使用的终端。然后键入 cat 命令并按 Enter 键。此命令将坐着等待您的输入

$ tty
/dev/pts/2
$
$ cat

打开另一个终端并使用 pgrep 命令找到 cat 的 PID

$ pgrep cat
24335
$

现在,浏览第一个每个进程的文件 cmdline。此文件显示命令行是如何执行的,是否使用了任何参数等等。

$ cat /proc/24335/cmdline 
cat$

接下来,查看名为 cwd 的目录,它有点像一个符号链接 (symlink),指向 cat 命令执行的目录;在本例中,它是 /root

$ ls -l  /proc/24335/cwd
lrwxrwxrwx. 1 root root 0 Mar  4 03:35 /proc/24335/cwd -> /root
$

如果执行一个二进制文件并生成一个进程,它默认会打开一些文件。一般来说,它会打开标准输入 (stdin)、标准输出 (stdout) 和标准错误 (stderr)。如果您列出 /proc/ 下的 fd 目录,后跟 PID,您可以看到它返回三个符号链接,都指向用于执行命令的终端 (pts2)

$ ls -l  /proc/24335/fd/
total 0
lrwx------. 1 root root 64 Mar  4 03:35 0 -> /dev/pts/2
lrwx------. 1 root root 64 Mar  4 03:35 1 -> /dev/pts/2
lrwx------. 1 root root 64 Mar  4 03:35 2 -> /dev/pts/2
$

另一个重要的文件是 exe,它是一个符号链接,指向执行的二进制文件的绝对路径。在本例中,它是 cat 命令的路径

$ ls -l /proc/24335/exe
lrwxrwxrwx. 1 root root 0 Mar  4 03:35 /proc/24335/exe -> /usr/bin/cat
$

类似地,如果您 cat 每个进程的 environ 文件,您可以查看为 cat 进程定义的所有环境变量

$ cat /proc/24335/environ

proc 中的重要文件

上面的例子提供了大量关于运行进程和您的系统的信息,这些信息通常可以帮助调试和解决问题。

重要的每个进程文件

以下是在 /proc/ 文件系统中要查找的重要每个进程文件

  • /proc/$pid/cmdline 保存进程的完整命令行
  • /proc/$pid/cwd 符号链接到进程的当前工作目录
  • /proc/$pid/environ 包含程序启动时设置的初始环境
  • /proc/$pid/exe 符号链接到已执行文件的路径
  • /proc/$pid/fd 用于列出进程已打开文件的子目录
  • /proc/$pid/io 包含进程的 I/O 统计信息
  • /proc/$pid/limits 显示进程资源限制
  • /proc/$pid/maps 当前映射的内存区域和访问权限
  • /proc/$pid/stack 进程内核堆栈中的函数调用跟踪
  • /proc/$pid/stat 关于进程的状态信息
  • /proc/$pid/task/ 包含线程信息的目录

重要的系统范围文件

这里列出了一些重要的通用文件(即,不特定于任何进程)

  • /proc/cmdline 启动时传递给 Linux 内核的参数
  • /proc/cpuinfo CPU 相关信息
  • /proc/meminfo 内存使用统计信息
  • /proc/filesystems 内核支持的文件系统列表
  • /proc/modules 当前已加载的内核模块
  • /proc/partitions 关于系统上每个分区的信息
  • /proc/swaps 关于系统上交换空间的信息
  • /proc/self 目录指向访问 /proc 文件系统的进程
  • /proc/slabinfo 关于内核缓存的信息
  • /proc/sys 关于内核变量的各种文件和子目录

进一步的步骤

本文对 proc 文件系统的概述仅触及了它提供的可能性。有关更多信息,请通过输入 man proc 命令或访问 proc 手册页 的在线版本来查看 proc 的手册页。

接下来阅读
标签
User profile image.
经验丰富的软件工程专业人士。主要兴趣是安全、Linux、恶意软件。喜欢在命令行工作。对底层软件和理解事物的工作原理感兴趣。此处表达的观点仅代表我个人,不代表我的雇主。

2 条评论

优秀的入门指南!我从不知道有比使用 ps 更好的方法来查找命令行参数。此外,还有更多我从未了解过的东西存在于 /proc 中!

好文章!
在 /proc 中,您还有 /proc/interrupts 和目录 /proc/irq/
有时驱动程序可能会在 CPU 上产生大量中断,然后系统性能可能会很差。例如,不良的 wifi 或 gpu 驱动程序。

Creative Commons License本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.