└── README.md /README.md: -------------------------------------------------------------------------------- 1 | [/proc/[pid]/auxv](#auxv) 2 | [/proc/[pid]/cmdline](#cmdline) 3 | [/proc/[pid]/comm](#comm) 4 | [/proc/[pid]/cwd](#cwd) 5 | [/proc/[pid]/environ](#environ) 6 | [/proc/[pid]/exe](#exe) 7 | [/proc/[pid]/fd](#fd) 8 | [/proc/[pid]/latency](#latency) 9 | [/proc/[pid]/limits](#limits) 10 | [/proc/[pid]/maps](#maps) 11 | [/proc/[pid]/root](#root) 12 | [/proc/[pid]/stack](#stack) 13 | [/proc/[pid]/statm](#statm) 14 | [/proc/[pid]/status](#status) 15 | [/proc/[pid]/syscall](#syscall) 16 | [/proc/[pid]/wchan](#wchan) 17 | 18 | ## auxv 19 | `/proc/[pid]/auxv`包含传递给进程的`ELF`解释器信息,格式是每一项都是一个`unsigned long`长度的`ID`加上一个`unsigned long`长度的值。最后一项以连续的两个`0x00`开头。举例如下: 20 | 21 | # hexdump -x /proc/2948/auxv 22 | 0000000 0021 0000 0000 0000 0000 1a82 7ffd 0000 23 | 0000010 0010 0000 0000 0000 dbf5 1fc9 0000 0000 24 | 0000020 0006 0000 0000 0000 1000 0000 0000 0000 25 | 0000030 0011 0000 0000 0000 0064 0000 0000 0000 26 | 0000040 0003 0000 0000 0000 2040 4326 7f4a 0000 27 | 0000050 0004 0000 0000 0000 0038 0000 0000 0000 28 | 0000060 0005 0000 0000 0000 0009 0000 0000 0000 29 | 0000070 0007 0000 0000 0000 f000 4303 7f4a 0000 30 | 0000080 0008 0000 0000 0000 0000 0000 0000 0000 31 | 0000090 0009 0000 0000 0000 8e67 4327 7f4a 0000 32 | 00000a0 000b 0000 0000 0000 0000 0000 0000 0000 33 | 00000b0 000c 0000 0000 0000 0000 0000 0000 0000 34 | 00000c0 000d 0000 0000 0000 0000 0000 0000 0000 35 | 00000d0 000e 0000 0000 0000 0000 0000 0000 0000 36 | 00000e0 0017 0000 0000 0000 0000 0000 0000 0000 37 | 00000f0 0019 0000 0000 0000 3de9 1a80 7ffd 0000 38 | 0000100 001f 0000 0000 0000 4fe5 1a80 7ffd 0000 39 | 0000110 000f 0000 0000 0000 3df9 1a80 7ffd 0000 40 | 0000120 0000 0000 0000 0000 0000 0000 0000 0000 41 | 0000130 42 | 解析这个文件可以参考这段[代码](http://www.wienand.org/junkcode/linux/read-auxv.c)。 43 | 44 | ## cmdline 45 | `/proc/[pid]/cmdline`是一个只读文件,包含进程的完整命令行信息。如果这个进程是`zombie`进程,则这个文件没有任何内容。举例如下: 46 | 47 | # ps -ef | grep 2948 48 | root 2948 1 0 Nov05 ? 00:00:04 /usr/sbin/libvirtd --listen 49 | 50 | # cat /proc/2948/cmdline 51 | /usr/sbin/libvirtd--listen 52 | 53 | ## comm 54 | `/proc/[pid]/comm`包含进程的命令名。举例如下: 55 | 56 | # cat /proc/2948/comm 57 | libvirtd 58 | 59 | ## cwd 60 | `/proc/[pid]/cwd`是进程当前工作目录的符号链接。举例如下: 61 | 62 | # ls -lt /proc/2948/cwd 63 | lrwxrwxrwx 1 root root 0 Nov 9 12:14 /proc/2948/cwd -> / 64 | 65 | 66 | ## environ 67 | `/proc/[pid]/environ`显示进程的环境变量。举例如下: 68 | 69 | # strings /proc/2948/environ 70 | LANG=POSIX 71 | LC_CTYPE=en_US.UTF-8 72 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 73 | NOTIFY_SOCKET=@/org/freedesktop/systemd1/notify 74 | LIBVIRTD_CONFIG=/etc/libvirt/libvirtd.conf 75 | LIBVIRTD_ARGS=--listen 76 | LIBVIRTD_NOFILES_LIMIT=2048 77 | 78 | ## exe 79 | `/proc/[pid]/exe`为实际运行程序的符号链接。举例如下: 80 | 81 | # ls -lt /proc/2948/exe 82 | lrwxrwxrwx 1 root root 0 Nov 5 13:04 /proc/2948/exe -> /usr/sbin/libvirtd 83 | 84 | ## fd 85 | `/proc/[pid]/fd`是一个目录,包含进程打开文件的情况。举例如下: 86 | 87 | # ls -lt /proc/3801/fd 88 | total 0 89 | lrwx------. 1 root root 64 Apr 18 16:51 0 -> socket:[37445] 90 | lrwx------. 1 root root 64 Apr 18 16:51 1 -> socket:[37446] 91 | lrwx------. 1 root root 64 Apr 18 16:51 10 -> socket:[31729] 92 | lrwx------. 1 root root 64 Apr 18 16:51 11 -> socket:[34562] 93 | lrwx------. 1 root root 64 Apr 18 16:51 12 -> socket:[39978] 94 | lrwx------. 1 root root 64 Apr 18 16:51 13 -> socket:[34574] 95 | lrwx------. 1 root root 64 Apr 18 16:51 14 -> socket:[39137] 96 | lrwx------. 1 root root 64 Apr 18 16:51 15 -> socket:[39208] 97 | lrwx------. 1 root root 64 Apr 18 16:51 16 -> socket:[39221] 98 | lrwx------. 1 root root 64 Apr 18 16:51 17 -> socket:[41080] 99 | lrwx------. 1 root root 64 Apr 18 16:51 18 -> socket:[40014] 100 | lrwx------. 1 root root 64 Apr 18 16:51 19 -> socket:[34617] 101 | lrwx------. 1 root root 64 Apr 18 16:51 20 -> socket:[34620] 102 | lrwx------. 1 root root 64 Apr 18 16:51 23 -> socket:[42357] 103 | lr-x------. 1 root root 64 Apr 18 16:51 3 -> /dev/urandom 104 | lrwx------. 1 root root 64 Apr 18 16:51 4 -> socket:[37468] 105 | lrwx------. 1 root root 64 Apr 18 16:51 5 -> socket:[37471] 106 | lrwx------. 1 root root 64 Apr 18 16:51 6 -> socket:[289532] 107 | lrwx------. 1 root root 64 Apr 18 16:51 7 -> socket:[31728] 108 | lrwx------. 1 root root 64 Apr 18 16:51 8 -> socket:[37450] 109 | lrwx------. 1 root root 64 Apr 18 16:51 9 -> socket:[37451] 110 | l-wx------. 1 root root 64 Apr 13 16:35 2 -> /root/.vnc/localhost.localdomain:1.log 111 | 目录中的每一项都是一个符号链接,指向打开的文件,数字则代表文件描述符。 112 | 113 | ## latency 114 | `/proc/[pid]/latency`显示哪些代码造成的延时比较大(使用这个`feature`,需要执行“`echo 1 > /proc/sys/kernel/latencytop`”)。举例如下: 115 | 116 | # cat /proc/2948/latency 117 | Latency Top version : v0.1 118 | 30667 10650491 4891 poll_schedule_timeout do_sys_poll SyS_poll system_call_fastpath 0x7f636573dc1d 119 | 8 105 44 futex_wait_queue_me futex_wait do_futex SyS_futex system_call_fastpath 0x7f6365a167bc 120 | 每一行前三个数字分别是后面代码执行的次数,总共执行延迟时间(单位是微秒)和最长执行延迟时间(单位是微秒),后面则是代码完整的调用栈。 121 | 122 | ## limits 123 | `/proc/[pid]/limits`显示当前进程的资源限制。举例如下: 124 | 125 | # cat /proc/2948/limits 126 | Limit Soft Limit Hard Limit Units 127 | Max cpu time unlimited unlimited seconds 128 | Max file size unlimited unlimited bytes 129 | Max data size unlimited unlimited bytes 130 | Max stack size 8388608 unlimited bytes 131 | Max core file size 0 unlimited bytes 132 | Max resident set unlimited unlimited bytes 133 | Max processes 6409 6409 processes 134 | Max open files 1024 4096 files 135 | Max locked memory 65536 65536 bytes 136 | Max address space unlimited unlimited bytes 137 | Max file locks unlimited unlimited locks 138 | Max pending signals 6409 6409 signals 139 | Max msgqueue size 819200 819200 bytes 140 | Max nice priority 0 0 141 | Max realtime priority 0 0 142 | Max realtime timeout unlimited unlimited us 143 | `Soft Limit`表示`kernel`设置给资源的值,`Hard Limit`表示`Soft Limit`的上限,而`Units`则为计量单元。 144 | 145 | ## maps 146 | `/proc/[pid]/maps`显示进程的内存区域映射信息。举例如下: 147 | 148 | # cat /proc/2948/maps 149 | ...... 150 | address perms offset dev inode pathname 151 | 7f4a2e2ad000-7f4a2e2ae000 rw-p 00006000 08:14 6505977 /usr/lib64/sasl2/libsasldb.so.3.0.0 152 | 7f4a2e2ae000-7f4a2e2af000 ---p 00000000 00:00 0 153 | 7f4a2e2af000-7f4a2eaaf000 rw-p 00000000 00:00 0 [stack:94671] 154 | 7f4a2eaaf000-7f4a2eab0000 ---p 00000000 00:00 0 155 | 7f4a2eab0000-7f4a2f2b0000 rw-p 00000000 00:00 0 [stack:94670] 156 | ...... 157 | 7f4a434d0000-7f4a434d5000 rw-p 0006e000 08:14 4292988 /usr/sbin/libvirtd 158 | 7f4a4520a000-7f4a452f7000 rw-p 00000000 00:00 0 [heap] 159 | 7ffd1a7e4000-7ffd1a805000 rw-p 00000000 00:00 0 [stack] 160 | 7ffd1a820000-7ffd1a821000 r-xp 00000000 00:00 0 [vdso] 161 | ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] 162 | 163 | 其中注意的一点是`[stack:]`是线程的堆栈信息,对应于`/proc/[pid]/task/[tid]/`路径。 164 | 165 | ## root 166 | `/proc/[pid]/root`是进程根目录的符号链接。举例如下: 167 | 168 | # ls -lt /proc/2948/root 169 | lrwxrwxrwx 1 root root 0 Nov 9 12:14 /proc/2948/root -> / 170 | 171 | ## stack 172 | `/proc/[pid]/stack`显示当前进程的内核调用栈信息,只有内核编译时打开了`CONFIG_STACKTRACE`编译选项,才会生成这个文件。举例如下: 173 | 174 | # cat /proc/2948/stack 175 | [] poll_schedule_timeout+0x45/0x60 176 | [] do_sys_poll+0x49d/0x550 177 | [] SyS_poll+0x5d/0xf0 178 | [] system_call_fastpath+0x16/0x1b 179 | [<00007f4a41ff2c1d>] 0x7f4a41ff2c1d 180 | [] 0xffffffffffffffff 181 | 182 | ## statm 183 | `/proc/[pid]/statm`显示进程所占用内存大小的统计信息,包含七个值,度量单位是`page`(`page`大小可通过`getconf PAGESIZE`得到)。举例如下: 184 | 185 | # cat /proc/2948/statm 186 | 72362 12945 4876 569 0 24665 0 187 | 188 | 各个值含义: 189 | a)进程占用的总的内存; 190 | b)进程当前时刻占用的物理内存; 191 | c)同其它进程共享的内存; 192 | d)进程的代码段; 193 | e)共享库(从`2.6`版本起,这个值为`0`); 194 | f)进程的堆栈; 195 | g)`dirty pages`(从`2.6`版本起,这个值为`0`)。 196 | 197 | ## status 198 | `/proc/[pid]/status`包含进程的状态信息。其很多内容与`/proc/[pid]/stat`和`/proc/[pid]/statm`,但是却是以一种更清晰地方式展现出来。举例如下: 199 | 200 | # cat /proc/$$/status 201 | Name: bash 202 | Umask: 0022 203 | State: S (sleeping) 204 | Tgid: 15694 205 | Ngid: 0 206 | Pid: 15694 207 | PPid: 15692 208 | TracerPid: 0 209 | Uid: 0 0 0 0 210 | Gid: 0 0 0 0 211 | FDSize: 256 212 | Groups: 0 1 2 3 4 6 10 19 213 | NStgid: 15694 214 | NSpid: 15694 215 | NSpgid: 15694 216 | NSsid: 15694 217 | VmPeak: 26040 kB 218 | VmSize: 26040 kB 219 | VmLck: 0 kB 220 | VmPin: 0 kB 221 | VmHWM: 5412 kB 222 | VmRSS: 5412 kB 223 | RssAnon: 2272 kB 224 | RssFile: 3140 kB 225 | RssShmem: 0 kB 226 | VmData: 2244 kB 227 | VmStk: 132 kB 228 | VmExe: 792 kB 229 | VmLib: 2732 kB 230 | VmPTE: 68 kB 231 | VmPMD: 12 kB 232 | VmSwap: 0 kB 233 | HugetlbPages: 0 kB 234 | Threads: 1 235 | SigQ: 0/11753 236 | SigPnd: 0000000000000000 237 | ShdPnd: 0000000000000000 238 | SigBlk: 0000000000010000 239 | SigIgn: 0000000000380004 240 | SigCgt: 000000004b817efb 241 | CapInh: 0000000000000000 242 | CapPrm: 0000003fffffffff 243 | CapEff: 0000003fffffffff 244 | CapBnd: 0000003fffffffff 245 | CapAmb: 0000000000000000 246 | NoNewPrivs: 0 247 | Seccomp: 0 248 | Cpus_allowed: f 249 | Cpus_allowed_list: 0-3 250 | Mems_allowed: 00000000,00000001 251 | Mems_allowed_list: 0 252 | voluntary_ctxt_switches: 1045 253 | nonvoluntary_ctxt_switches: 30 254 | 255 | 关于信号(`signal`)的信息:`SigQ`分为两部分(例如`0/11753`),前面表示当前处在队列中的信号(`0`),后面则表示队列一共可以存储多少信号(`11753`);`SigPnd`表示当前线程`pending`的信号,而`ShdPnd`则表示整个进程`pending`的信号;`SigBlk`、`SigIgn`和`SigCgt`分别表示对信号的处理是阻塞,忽略,还是捕获。(关于`Unix`信号的相关知识,可以参考[Unix: Dealing with signals](https://www.networkworld.com/article/3211296/linux/unix-dealing-with-signals.html))。 256 | ## syscall 257 | `/proc/[pid]/syscall`显示当前进程正在执行的系统调用。举例如下: 258 | 259 | # cat /proc/2948/syscall 260 | 7 0x7f4a452cbe70 0xb 0x1388 0xffffffffffdff000 0x7f4a4274a750 0x0 0x7ffd1a8033f0 0x7f4a41ff2c1d 261 | 262 | 第一个值是系统调用号(`7`代表`poll`),后面跟着`6`个系统调用的参数值(位于寄存器中),最后两个值依次是堆栈指针和指令计数器的值。如果当前进程虽然阻塞,但阻塞函数并不是系统调用,则系统调用号的值为`-1`,后面只有堆栈指针和指令计数器的值。如果进程没有阻塞,则这个文件只有一个“`running`”的字符串。 263 | 264 | 内核编译时打开了`CONFIG_HAVE_ARCH_TRACEHOOK`编译选项,才会生成这个文件。 265 | 266 | ## wchan 267 | `/proc/[pid]/wchan`显示当进程`sleep`时,`kernel`当前运行的函数。举例如下: 268 | 269 | # cat /proc/2948/wchan 270 | kauditd_thread 271 | 272 | --------------------------------------------------------------------------------