1. 程式人生 > >Linux中 /proc/[pid] 目錄各文件簡析

Linux中 /proc/[pid] 目錄各文件簡析

sig 關於 ace serve 空間 uid 代碼段 getconf 訪問

Linux 內核提供了一種通過 proc 文件系統,在運行時訪問內核內部數據結構、改變內核設置的機制。proc 文件系統是一個偽文件系統,它只存在內存當中,而不占用外存空間。它以文件系統的方式為訪問系統內核數據的操作提供接口。

用戶和應用程序可以通過 proc 得到系統的信息,並可以改變內核的某些參數。由於系統的信息,如進程,是動態改變的,所以用戶或應用程序讀取 proc 文件時,proc 文件系統是動態從系統內核讀出所需信息並提交的。

下面列出的這些文件或子文件夾,並不是都是在你的系統中存在,這取決於你的內核配置和裝載的模塊。另外,在 proc 下還有三個很重要的目錄:net,scsi 和 sys。 sys 目錄是可寫的,可以通過它來訪問或修改內核的參數,而 net 和 scsi 則依賴於內核配置。例如,如果系統不支持 scsi,則 scsi 目錄不存在。

除了以上介紹的這些,還有的是一些以數字命名的目錄,它們是進程目錄。系統中當前運行的每一個進程都有對應的一個目錄在 proc 下,以進程的 PID 號為目錄名,它們是讀取進程信息的接口。而 self 目錄則是讀取進程本身的信息接口,是一個 link。

/proc/[pid]/auxv

/proc/[pid]/auxv 包含傳遞給進程的 ELF 解釋器信息,格式是每一項都是一個 unsigned long長度的 ID 加上一個 unsigned long 長度的值。最後一項以連續的兩個 0x00 開頭。舉例如下:

$ hexdump -x /proc/2406/auxv

0000000    0021    0000    0000    0000    f000    f7fa    7fff    0000
0000010    0010    0000    0000    0000    fbff    1f8b    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    0007    0000    0000    0000
0000070    0007    0000    0000    0000    0000    0000    0000    0000
0000080    0008    0000    0000    0000    0000    0000    0000    0000
0000090    0009    0000    0000    0000    55e0    0045    0000    0000
00000a0    000b    0000    0000    0000    0000    0000    0000    0000
00000b0    000c    0000    0000    0000    0000    0000    0000    0000
00000c0    000d    0000    0000    0000    0000    0000    0000    0000
00000d0    000e    0000    0000    0000    0000    0000    0000    0000
00000e0    0017    0000    0000    0000    0000    0000    0000    0000
00000f0    0019    0000    0000    0000    f079    f7f6    7fff    0000
0000100    001f    0000    0000    0000    ffea    f7f6    7fff    0000
0000110    000f    0000    0000    0000    f089    f7f6    7fff    0000
0000120    0000    0000    0000    0000    0000    0000    0000    0000
0000130

/proc/[pid]/cmdline

/proc/[pid]/cmdline 是一個只讀文件,包含進程的完整命令行信息。如果該進程已經被交換出內存或者這個進程是 zombie 進程,則這個文件沒有任何內容。該文件以空字符 null 而不是換行符作為結束標誌。舉例如下:

$ ps aux|grep frps
root      2406  0.1  0.1  54880 10524 ?        Sl   Dec11  21:30 frps -c ./frps.ini

$ cat /proc/2406/cmdline
frps-c./frps.ini

/proc/[pid]/comm

/proc/[pid]/comm 包含進程的命令名。舉例如下:

$ cat /proc/2406/comm
frps

/proc/[pid]/cwd

/proc/[pid]/cwd 是進程當前工作目錄的符號鏈接。舉例如下:

$ ls -lt /proc/2406/cwd
lrwxrwxrwx 1 root root 0 Dec 12 20:39 /proc/2406/cwd -> /home/mike/frp_0.13.0_linux_amd64

/proc/[pid]/environ

/proc/[pid]/environ 顯示進程的環境變量。舉例如下:

$ strings /proc/2406/environ

SUPERVISOR_GROUP_NAME=ssh
TERM=linux
SUPERVISOR_SERVER_URL=unix:///var/run/supervisor.sock
SUPERVISOR_PROCESS_NAME=ssh
RUNLEVEL=2
UPSTART_EVENTS=runlevel
PREVLEVEL=N
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
UPSTART_INSTANCE=
UPSTART_JOB=rc
SUPERVISOR_ENABLED=1
runlevel=2
PWD=/
previous=N

/proc/[pid]/exe

/proc/[pid]/exe 為實際運行程序的符號鏈接。舉例如下:

$ ls -lt /proc/2406/exe
lrwxrwxrwx 1 root root 0 Dec 11 19:00 /proc/2406/exe -> /usr/bin/frps

/proc/[pid]/fd

/proc/[pid]/fd 是一個目錄,包含進程打開文件的情況。舉例如下:

$ ls -lt /proc/2406/fd

lrwx------ 1 root root 64 Dec 24 09:39 77 -> socket:[44377722]
lrwx------ 1 root root 64 Dec 17 15:07 47 -> socket:[29482617]
lr-x------ 1 root root 64 Dec 12 20:18 0 -> pipe:[13282]
l-wx------ 1 root root 64 Dec 12 20:18 1 -> pipe:[13283]
lrwx------ 1 root root 64 Dec 12 20:18 10 -> socket:[12238218]
lrwx------ 1 root root 64 Dec 12 20:18 4 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Dec 12 20:18 40 -> socket:[19378614]

目錄中的每一項都是一個符號鏈接,指向打開的文件,數字則代表文件描述符。

/proc/[pid]/latency

/proc/[pid]/latency 顯示哪些代碼造成的延時比較大。如果要使用這個特性需要執行:

$ echo 1 > /proc/sys/kernel/latencytop

舉例如下

$ cat /proc/2406/latency

Latency Top version : v0.1
30667 10650491 4891 poll_schedule_timeout do_sys_poll SyS_poll system_call_fastpath 0x7f636573dc1d
8 105 44 futex_wait_queue_me futex_wait do_futex SyS_futex system_call_fastpath 0x7f6365a167bc

每一行前三個數字分別是後面代碼執行的次數、總共執行延遲時間(單位是微秒)和最長執行延遲時間(單位是微秒)。後面則是代碼完整的調用棧。

/proc/[pid]/maps

/proc/[pid]/maps 顯示進程的內存區域映射信息。舉例如下:

$ cat /proc/2406/maps
00400000-006ea000 r-xp 00000000 fd:01 1727569                            /usr/bin/frps
006ea000-00a6c000 r--p 002ea000 fd:01 1727569                            /usr/bin/frps
00a6c000-00ab1000 rw-p 0066c000 fd:01 1727569                            /usr/bin/frps
00ab1000-00ad4000 rw-p 00000000 00:00 0
c000000000-c00000b000 rw-p 00000000 00:00 0
c41feac000-c420000000 rw-p 00000000 00:00 0
c420000000-c420400000 rw-p 00000000 00:00 0
c420400000-c420700000 rw-p 00000000 00:00 0
c420700000-c420800000 rw-p 00000000 00:00 0
c420800000-c420900000 rw-p 00000000 00:00 0
c420900000-c420a00000 rw-p 00000000 00:00 0
c420a00000-c421ea0000 rw-p 00000000 00:00 0
c421ea0000-c422a00000 rw-p 00000000 00:00 0
c422a00000-c422a60000 rw-p 00000000 00:00 0
7f0418c01000-7f0418ee1000 rw-p 00000000 00:00 0
7ffff7f4f000-7ffff7f70000 rw-p 00000000 00:00 0                          [stack:5121]
7ffff7fad000-7ffff7faf000 r--p 00000000 00:00 0                          [vvar]
7ffff7faf000-7ffff7fb1000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

其中註意的一點是 [stack:] 是線程的堆棧信息,對應於 /proc/[pid]/task/[tid]/ 路徑。

/proc/[pid]/root

/proc/[pid]/root 是進程根目錄的符號鏈接。舉例如下:

$  ls -lt /proc/2406/root
lrwxrwxrwx 1 root root 0 Dec 12 20:39 /proc/2406/root -> /

/proc/[pid]/stack

/proc/[pid]/stack 示當前進程的內核調用棧信息,只有內核編譯時打開了 CONFIG_STACKTRACE 編譯選項,才會生成這個文件。舉例如下:

$ cat /proc/2406/stack
[<ffffffff810fa996>] futex_wait_queue_me+0xc6/0x130
[<ffffffff810fb05d>] futex_wait+0x17d/0x270
[<ffffffff810fd2d5>] do_futex+0xd5/0x520
[<ffffffff810fd791>] SyS_futex+0x71/0x150
[<ffffffff8180cc76>] entry_SYSCALL_64_fastpath+0x16/0x75
[<ffffffffffffffff>] 0xffffffffffffffff

/proc/[pid]/statm

/proc/[pid]/statm 顯示進程所占用內存大小的統計信息。包含七個值,度量單位是 page(page大小可通過 getconf PAGESIZE 得到)。舉例如下:

$  cat /proc/2406/statm
13720 2617 493 746 0 12007 0

各個值含義:

a)進程占用的總的內存
b)進程當前時刻占用的物理內存
c)同其它進程共享的內存
d)進程的代碼段
e)共享庫(從2.6版本起,這個值為0)
f)進程的堆棧
g)dirty pages(從2.6版本起,這個值為0)

/proc/[pid]/status

/proc/[pid]/status 包含進程的狀態信息。其很多內容與 /proc/[pid]/stat 和 /proc/[pid]/statm 相同,但是卻是以一種更清晰地方式展現出來。舉例如下:

$ cat /proc/2406/status
Name:   frps
State:  S (sleeping)
Tgid:   2406
Ngid:   0
Pid:    2406
PPid:   2130
TracerPid:  0
Uid:    0   0   0   0
Gid:    0   0   0   0
FDSize: 128
Groups: 0
NStgid: 2406
NSpid:  2406
NSpgid: 2406
NSsid:  2130
VmPeak:    54880 kB
VmSize:    54880 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:     34872 kB
VmRSS:     10468 kB
VmData:    47896 kB
VmStk:       132 kB
VmExe:      2984 kB
VmLib:         0 kB
VmPTE:        68 kB
VmPMD:        20 kB
VmSwap:        0 kB
HugetlbPages:          0 kB
Threads:    11
SigQ:   0/31834
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: fffffffe7fc1feff
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Seccomp:    0
Cpus_allowed:   f
Cpus_allowed_list:  0-3
Mems_allowed:   00000000,00000001
Mems_allowed_list:  0
voluntary_ctxt_switches:    2251028
nonvoluntary_ctxt_switches: 18031

關於信號(signal)的信息:SigQ 分為兩部分(例如 0/31834),前面表示當前處在隊列中的信號(0),後面則表示隊列一共可以存儲多少信號(31834);SigPnd 表示當前線程 pending 的信號,而ShdPnd 則表示整個進程 pending 的信號;SigBlk、SigIgn 和 SigCgt 分別表示對信號的處理是阻塞,忽略,還是捕獲。(關於Unix信號的相關知識,可以參考 Unix: Dealing with signals)。

/proc/[pid]/syscall

/proc/[pid]/syscall 顯示當前進程正在執行的系統調用。舉例如下:

$ cat /proc/2406/syscall
202 0xab3730 0x0 0x0 0x0 0x0 0x0 0x7ffff7f6ec68 0x455bb3

第一個值是系統調用號(202代表poll),後面跟著 6 個系統調用的參數值(位於寄存器中),最後兩個值依次是堆棧指針和指令計數器的值。如果當前進程雖然阻塞,但阻塞函數並不是系統調用,則系統調用號的值為 -1,後面只有堆棧指針和指令計數器的值。如果進程沒有阻塞,則這個文件只有一個 running 的字符串。

內核編譯時打開了 CONFIG_HAVE_ARCH_TRACEHOOK 編譯選項,才會生成這個文件。

/proc/[pid]/wchan

/proc/[pid]/wchan 顯示當進程 sleep 時,kernel 當前運行的函數。舉例如下:

$ cat /proc/2406/wchan
futex_wait_queue_meadmin

Linux中 /proc/[pid] 目錄各文件簡析