Linux?內(nèi)核提供了一種通過 proc 文件系統(tǒng),在運行時訪問內(nèi)核內(nèi)部數(shù)據(jù)結(jié)構(gòu)、改變內(nèi)核設(shè)置的機(jī)制。proc 文件系統(tǒng)是一個偽文件系統(tǒng),它只存在內(nèi)存當(dāng)中,而不占用外存空間。它以文件系統(tǒng)的方式為訪問系統(tǒng)內(nèi)核數(shù)據(jù)的操作提供接口。
用戶和應(yīng)用程序可以通過 proc 得到系統(tǒng)的信息,并可以改變內(nèi)核的某些參數(shù)。由于系統(tǒng)的信息,如進(jìn)程,是動態(tài)改變的,所以用戶或應(yīng)用程序讀取 proc 文件時,proc 文件系統(tǒng)是動態(tài)從系統(tǒng)內(nèi)核讀出所需信息并提交的。
下面列出的這些文件或子文件夾,并不是都是在你的系統(tǒng)中存在,這取決于你的內(nèi)核配置和裝載的模塊。另外,在 proc 下還有三個很重要的目錄:net,scsi 和 sys。 sys 目錄是可寫的,可以通過它來訪問或修改內(nèi)核的參數(shù),而 net 和 scsi 則依賴于內(nèi)核配置。例如,如果系統(tǒng)不支持 scsi,則 scsi 目錄不存在。
除了以上介紹的這些,還有的是一些以數(shù)字命名的目錄,它們是進(jìn)程目錄。系統(tǒng)中當(dāng)前運行的每一個進(jìn)程都有對應(yīng)的一個目錄在 proc 下,以進(jìn)程的 PID 號為目錄名,它們是讀取進(jìn)程信息的接口。而 self 目錄則是讀取進(jìn)程本身的信息接口,是一個 link。
/proc/[pid]/auxv
/proc/[pid]/auxv 包含傳遞給進(jìn)程的 ELF 解釋器信息,格式是每一項都是一個 unsigned long長度的 ID 加上一個 unsigned long 長度的值。最后一項以連續(xù)的兩個 0x00 開頭。舉例如下:
$ hexdump -x /proc/2406/auxv0000000 0021 0000 0000 0000 f000 f7fa 7fff 00000000010 0010 0000 0000 0000 fbff 1f8b 0000 00000000020 0006 0000 0000 0000 1000 0000 0000 00000000030 0011 0000 0000 0000 0064 0000 0000 00000000040 0003 0000 0000 0000 0040 0040 0000 00000000050 0004 0000 0000 0000 0038 0000 0000 00000000060 0005 0000 0000 0000 0007 0000 0000 00000000070 0007 0000 0000 0000 0000 0000 0000 00000000080 0008 0000 0000 0000 0000 0000 0000 00000000090 0009 0000 0000 0000 55e0 0045 0000 000000000a0 000b 0000 0000 0000 0000 0000 0000 000000000b0 000c 0000 0000 0000 0000 0000 0000 000000000c0 000d 0000 0000 0000 0000 0000 0000 000000000d0 000e 0000 0000 0000 0000 0000 0000 000000000e0 0017 0000 0000 0000 0000 0000 0000 000000000f0 0019 0000 0000 0000 f079 f7f6 7fff 00000000100 001f 0000 0000 0000 ffea f7f6 7fff 00000000110 000f 0000 0000 0000 f089 f7f6 7fff 00000000120 0000 0000 0000 0000 0000 0000 0000 00000000130
/proc/[pid]/cmdline
/proc/[pid]/cmdline 是一個只讀文件,包含進(jìn)程的完整命令行信息。如果該進(jìn)程已經(jīng)被交換出內(nèi)存或者這個進(jìn)程是 zombie 進(jìn)程,則這個文件沒有任何內(nèi)容。該文件以空字符 null 而不是換行符作為結(jié)束標(biāo)志。舉例如下:
$ ps aux|grep frpsroot 2406 0.1 0.1 54880 10524 ? Sl Dec11 21:30 frps -c ./frps.ini$ cat /proc/2406/cmdlinefrps-c./frps.ini
/proc/[pid]/comm
/proc/[pid]/comm 包含進(jìn)程的命令名。舉例如下:
$ cat /proc/2406/commfrps
/proc/[pid]/cwd
/proc/[pid]/cwd 是進(jìn)程當(dāng)前工作目錄的符號鏈接。舉例如下:
$ ls -lt /proc/2406/cwdlrwxrwxrwx 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 顯示進(jìn)程的環(huán)境變量。舉例如下:
$ strings /proc/2406/environSUPERVISOR_GROUP_NAME=sshTERM=linuxSUPERVISOR_SERVER_URL=unix:///var/run/supervisor.sockSUPERVISOR_PROCESS_NAME=sshRUNLEVEL=2UPSTART_EVENTS=runlevelPREVLEVEL=NPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/binUPSTART_INSTANCE=UPSTART_JOB=rcSUPERVISOR_ENABLED=1runlevel=2PWD=/previous=N
/proc/[pid]/exe
/proc/[pid]/exe 為實際運行程序的符號鏈接。舉例如下:
$ ls -lt /proc/2406/exelrwxrwxrwx 1 root root 0 Dec 11 19:00 /proc/2406/exe -> /usr/bin/frps
/proc/[pid]/fd
/proc/[pid]/fd 是一個目錄,包含進(jìn)程打開文件的情況。舉例如下:
$ ls -lt /proc/2406/fdlrwx------ 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]
目錄中的每一項都是一個符號鏈接,指向打開的文件,數(shù)字則代表文件描述符。
/proc/[pid]/latency
/proc/[pid]/latency 顯示哪些代碼造成的延時比較大。如果要使用這個特性需要執(zhí)行:
$ echo 1 > /proc/sys/kernel/latencytop
舉例如下
$ cat /proc/2406/latencyLatency Top version : v0.130667 10650491 4891 poll_schedule_timeout do_sys_poll SyS_poll system_call_fastpath 0x7f636573dc1d8 105 44 futex_wait_queue_me futex_wait do_futex SyS_futex system_call_fastpath 0x7f6365a167bc
每一行前三個數(shù)字分別是后面代碼執(zhí)行的次數(shù)、總共執(zhí)行延遲時間(單位是微秒)和最長執(zhí)行延遲時間(單位是微秒)。后面則是代碼完整的調(diào)用棧。
/proc/[pid]/maps
/proc/[pid]/maps 顯示進(jìn)程的內(nèi)存區(qū)域映射信息。舉例如下:
$ cat /proc/2406/maps00400000-006ea000 r-xp 00000000 fd:01 1727569 /usr/bin/frps006ea000-00a6c000 r--p 002ea000 fd:01 1727569 /usr/bin/frps00a6c000-00ab1000 rw-p 0066c000 fd:01 1727569 /usr/bin/frps00ab1000-00ad4000 rw-p 00000000 00:00 0c000000000-c00000b000 rw-p 00000000 00:00 0c41feac000-c420000000 rw-p 00000000 00:00 0c420000000-c420400000 rw-p 00000000 00:00 0c420400000-c420700000 rw-p 00000000 00:00 0c420700000-c420800000 rw-p 00000000 00:00 0c420800000-c420900000 rw-p 00000000 00:00 0c420900000-c420a00000 rw-p 00000000 00:00 0c420a00000-c421ea0000 rw-p 00000000 00:00 0c421ea0000-c422a00000 rw-p 00000000 00:00 0c422a00000-c422a60000 rw-p 00000000 00:00 07f0418c01000-7f0418ee1000 rw-p 00000000 00:00 07ffff7f4f000-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:] 是線程的堆棧信息,對應(yīng)于 /proc/[pid]/task/[tid]/ 路徑。
/proc/[pid]/root
/proc/[pid]/root 是進(jìn)程根目錄的符號鏈接。舉例如下:
$ ls -lt /proc/2406/rootlrwxrwxrwx 1 root root 0 Dec 12 20:39 /proc/2406/root -> /
/proc/[pid]/stack
/proc/[pid]/stack 示當(dāng)前進(jìn)程的內(nèi)核調(diào)用棧信息,只有內(nèi)核編譯時打開了 CONFIG_STACKTRACE 編譯選項,才會生成這個文件。舉例如下:
$ cat /proc/2406/stack[] futex_wait_queue_me+0xc6/0x130[] futex_wait+0x17d/0x270[] do_futex+0xd5/0x520[] SyS_futex+0x71/0x150[] entry_SYSCALL_64_fastpath+0x16/0x75[] 0xffffffffffffffff
/proc/[pid]/statm
/proc/[pid]/statm 顯示進(jìn)程所占用內(nèi)存大小的統(tǒng)計信息。包含七個值,度量單位是 page(page大小可通過 getconf PAGESIZE 得到)。舉例如下:
$ cat /proc/2406/statm13720 2617 493 746 0 12007 0
各個值含義:
a)進(jìn)程占用的總的內(nèi)存b)進(jìn)程當(dāng)前時刻占用的物理內(nèi)存c)同其它進(jìn)程共享的內(nèi)存d)進(jìn)程的代碼段e)共享庫(從2.6版本起,這個值為0)f)進(jìn)程的堆棧g)dirty pages(從2.6版本起,這個值為0)
/proc/[pid]/status
/proc/[pid]/status 包含進(jìn)程的狀態(tài)信息。其很多內(nèi)容與 /proc/[pid]/stat 和 /proc/[pid]/statm 相同,但是卻是以一種更清晰地方式展現(xiàn)出來。舉例如下:
$ cat /proc/2406/statusName: frpsState: S (sleeping)Tgid: 2406Ngid: 0Pid: 2406PPid: 2130TracerPid: 0Uid: 0 0 0 0Gid: 0 0 0 0FDSize: 128Groups: 0NStgid: 2406NSpid: 2406NSpgid: 2406NSsid: 2130VmPeak: 54880 kBVmSize: 54880 kBVmLck: 0 kBVmPin: 0 kBVmHWM: 34872 kBVmRSS: 10468 kBVmData: 47896 kBVmStk: 132 kBVmExe: 2984 kBVmLib: 0 kBVmPTE: 68 kBVmPMD: 20 kBVmSwap: 0 kBHugetlbPages: 0 kBThreads: 11SigQ: 0/31834SigPnd: 0000000000000000ShdPnd: 0000000000000000SigBlk: 0000000000000000SigIgn: 0000000000000000SigCgt: fffffffe7fc1feffCapInh: 0000000000000000CapPrm: 0000003fffffffffCapEff: 0000003fffffffffCapBnd: 0000003fffffffffCapAmb: 0000000000000000Seccomp: 0Cpus_allowed: fCpus_allowed_list: 0-3Mems_allowed: 00000000,00000001Mems_allowed_list: 0voluntary_ctxt_switches: 2251028nonvoluntary_ctxt_switches: 18031
關(guān)于信號(signal)的信息:SigQ 分為兩部分(例如 0/31834),前面表示當(dāng)前處在隊列中的信號(0),后面則表示隊列一共可以存儲多少信號(31834);SigPnd 表示當(dāng)前線程 pending 的信號,而ShdPnd 則表示整個進(jìn)程 pending 的信號;SigBlk、SigIgn 和 SigCgt 分別表示對信號的處理是阻塞,忽略,還是捕獲。(關(guān)于Unix信號的相關(guān)知識,可以參考 Unix: Dealing with signals)。
/proc/[pid]/syscall
/proc/[pid]/syscall 顯示當(dāng)前進(jìn)程正在執(zhí)行的系統(tǒng)調(diào)用。舉例如下:
$ cat /proc/2406/syscall202 0xab3730 0x0 0x0 0x0 0x0 0x0 0x7ffff7f6ec68 0x455bb3
第一個值是系統(tǒng)調(diào)用號(202代表poll),后面跟著 6 個系統(tǒng)調(diào)用的參數(shù)值(位于寄存器中),最后兩個值依次是堆棧指針和指令計數(shù)器的值。如果當(dāng)前進(jìn)程雖然阻塞,但阻塞函數(shù)并不是系統(tǒng)調(diào)用,則系統(tǒng)調(diào)用號的值為 -1,后面只有堆棧指針和指令計數(shù)器的值。如果進(jìn)程沒有阻塞,則這個文件只有一個 running 的字符串。
內(nèi)核編譯時打開了 CONFIG_HAVE_ARCH_TRACEHOOK 編譯選項,才會生成這個文件。
/proc/[pid]/wchan
/proc/[pid]/wchan 顯示當(dāng)進(jìn)程 sleep 時,kernel 當(dāng)前運行的函數(shù)。舉例如下:
$ cat /proc/2406/wchanfutex_wait_queue_meadmin
?
評論
查看更多