Linux下进程信息的深入分析

本文发布时间: 2019-Mar-22
这里我们主要介绍进程的状态,进程的状态可以通过/proc/PID/status来查看,也可以通过/proc/PID/stat来查看.如果说到工具大家用的最多的ps也可以看到进程的信息.这里我们通过/proc/PID/status来分析进程的信息.在2.6.18之后的内核,多了capibilty/cpusets等信息.查看进程状态信息如下:more statusName: rsyslogdState: S (sleeping)Tgid: 987Pid: 987PPid: 1TracerPid: 0Uid: 0 0 0 0Gid: 0 0 0 0Utrace: 0FDSize: 32Groups:VmPeak: 36528 kBVmSize: 36528 kBVmLck: 0 kBVmHWM: 1432 kBVmRSS: 1420 kBVmData: 33980 kBVmStk: 88 kBVmExe: 320 kBVmLib: 2044 kBVmPTE: 56 kBVmSwap: 0 kBThreads: 3SigQ: 1/7954SigPnd: 0000000000000000ShdPnd: 0000000000000000SigBlk: 0000000000000000SigIgn: 0000000001001206SigCgt: 0000000180014c21CapInh: 0000000000000000CapPrm: ffffffffffffffffCapEff: ffffffffffffffffCapBnd: ffffffffffffffffCpus_allowed: 3Cpus_allowed_list: 0-1Mems_allowed: 1Mems_allowed_list: 0voluntary_ctxt_switches: 1nonvoluntary_ctxt_switches: 0Name: rsyslogd解释:进程名State: S (sleeping)解释:进程的状态我们前文已经做了很详细的分析,各进程的状态代表的意义如下:R (running)", "S (sleeping)", "D (disk sleep)", "T (stopped)", "T(tracing stop)", "Z (zombie)", or "X (dead)"Tgid: 987解释:Tgid是线程组的ID,一个线程一定属于一个线程组(进程组).Pid: 987解释:这个是进程的ID,更准确的说应该是线程的ID.例如:UID PID PPID LWP C NLWP STIME TTY TIME CMDroot 987 1 987 0 3 00:18 ? 00:00:00 /sbin/rsyslogd -c 4root 987 1 989 0 3 00:18 ? 00:00:00 /sbin/rsyslogd -c 4root 987 1 990 0 3 00:18 ? 00:00:00 /sbin/rsyslogd -c 4注:/proc/pid/status中的Pid就是ps命令的LWP列输出,PID一列其实是进程组,而LWP是轻量级进程,也就是线程,因为所有的进程必须一个线程,那就是它自己.PPid: 1解释:当前进程的父进程TracerPid: 0解释:跟踪当前进程的进程ID,如果是0,表示没有跟踪.例如:用strace跟踪top程序strace top查看top进程ps -axjfPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND2491 2500 2500 2491 pts/2 2500 S+ 0 0:00 \_ strace top2500 2501 2500 2491 pts/2 2500 S+ 0 0:00 \_ top查看top进程的TracerPid位cat /proc/2501/statstat statm statustest1:/proc/2431# cat /proc/2501/statusName: topState: S (sleeping)Tgid: 2501Pid: 2501PPid: 2500TracerPid: 2500Uid: 0 0 0 0Gid: 0 0 0 0解释:第一列数字(RUID):实际用户ID,指的是进程执行者是谁.第二列数字(EUID):有效用户ID,指进程执行时对文件的访问权限.第三列数字(SUID):保存设置用户ID,作为effective user ID的副本,在执行exec调用时后能重新恢复原来的effectiv user ID.第四列数字(FSUID):目前进程的文件系统的用户识别码.一般情况下,文件系统的用户识别码(fsuid)与有效的用户识别码(euid)是相同的.这里重点说明RUID和EUID,我们用test用户启动top,如下:终端1)su - testtop查看该进程的EUID和RUID,如下:终端2)cat /proc/`pgrep top|grep -v grep`/status前面略Uid: 1002 1002 1002 1002Gid: 1003 1003 1003 1003后面略注:这里我们看到进程的RUID和EUID都变成了1002.我们将程序top加上setuid权限,如下:chmod +s /usr/bin/top重新运行top程序,并查看它的RUID和EUID,如下:cat /proc/`pgrep top|grep -v grep`/status前面略Uid: 1002 0 0 0Gid: 1003 0 0 0后面略注:我们看到RUID还是1002,说明程序是由test用户(UID=1002)启动的,而程序设定了setuid,那么在程序运行时是用程序的owner权限来运行程序,而不是启动的用户权限.由于top的owner是root,那么它的EUID是0.FDSize: 32解释:FDSize是当前分配的文件描述符,这个值不是当前进程使用文件描述符的上限.我们看到这里是32,但实际并没有分配32个文件,如下:ls -l /proc/`pgrep rsyslogd|grep -v grep`/fdtotal 0lrwx------ 1 root root 64 2011-04-20 20:03 0 -> socket:[5741]l-wx------ 1 root root 64 2011-04-20 20:03 1 -> /var/log/auth.logl-wx------ 1 root root 64 2011-04-20 20:03 10 -> /var/log/mail.errl-wx------ 1 root root 64 2011-04-20 20:03 11 -> /var/log/news/news.critl-wx------ 1 root root 64 2011-04-20 20:03 12 -> /var/log/news/news.errl-wx------ 1 root root 64 2011-04-20 20:03 13 -> /var/log/news/news.noticel-wx------ 1 root root 64 2011-04-20 20:03 14 -> /var/log/debugl-wx------ 1 root root 64 2011-04-20 20:03 15 -> /var/log/messageslrwx------ 1 root root 64 2011-04-20 20:03 16 -> /dev/xconsolelr-x------ 1 root root 64 2011-04-20 20:03 17 -> /proc/kmsgl-wx------ 1 root root 64 2011-04-20 20:03 2 -> /var/log/syslogl-wx------ 1 root root 64 2011-04-20 20:03 3 -> /var/log/daemon.logl-wx------ 1 root root 64 2011-04-20 20:03 4 -> /var/log/kern.logl-wx------ 1 root root 64 2011-04-20 20:03 5 -> /var/log/lpr.logl-wx------ 1 root root 64 2011-04-20 20:03 6 -> /var/log/mail.logl-wx------ 1 root root 64 2011-04-20 20:03 7 -> /var/log/user.logl-wx------ 1 root root 64 2011-04-20 20:03 8 -> /var/log/mail.infol-wx------ 1 root root 64 2011-04-20 20:03 9 -> /var/log/mail.warn我们看到这里只用到了18个文件描述符.而如果超过32个文件描述符,将以32进行递增,如果是64位系统,将以64进行递增.FDSize这个值不会减少,如果我们程序打开了300个文件,并不会因为关闭文件,而减少FDSize这个值.Groups: 0解释:这里的groups表示启动这个进程的用户所在的组.我们当前的用户test,现在在两个组(1000,2000)里面,如下:iduid=1002(test) gid=1002(nagcmd) groups=1000(chenkuo),1002(nagcmd)用test用户启动top程序,并查看它的groups,如下:终端1top终端2cat /proc/`pgrep top|grep -v grep`/status截取信息如下:Groups: 1000 1002VmPeak: 36528 kB解释:这里的VmPeak代表当前进程运行过程中占用内存的峰值.我们用下面的程序申请内存,然后释放内存,最后通pause()函数中止程序的运行,程序源码如下:#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>intmain (int argc, char *argv[]){ if (argc != 2) exit (0); size_t mb = strtoul(argv[1],NULL,0); size_t nbytes = mb * 0x100000; char *ptr = (char *) malloc(nbytes); if (ptr == NULL){ perror("malloc"); exit (EXIT_FAILURE); } printf("allocated %d mb\n", mb); free(ptr); pause(); return 0;}gcc callmem.c -o callmem./callmem 10allocated 10 mb终端2我们打开status文件,查看VmPeak值,如下:cat /proc/`pgrep callmem|grep -v grep`/statusName: callmemState: S (sleeping)Tgid: 2930Pid: 2930PPid: 2831TracerPid: 0Uid: 1002 1002 1002 1002Gid: 1002 1002 1002 1002FDSize: 256Groups: 1000 1002VmPeak: 11852 kBVmSize: 1608 kBVmLck: 0 kBVmHWM: 396 kBVmRSS: 396 kBVmData: 28 kBVmStk: 84 kBVmExe: 4 kBVmLib: 1468 kBVmPTE: 12 kB下面略注:我们看到程序申请了10240kb(10MB)的内存,VmPeak的值为11852kb,为什么不是10MB呢,因为除了我们申请的内存外,程序还会为加载动态链接库而占用内存.VmSize: 36528 kB解释:VmSize代表进程现在正在占用的内存这个值与pmap pid的值基本一致,如果略有不同,可能是内存裂缝所造成的.VmLck: 0 kB解释:VmLck代表进程已经锁住的物理内存的大小.锁住的物理内存不能交换到硬盘.我们用下面的程序进行测试,如下:#include <stdio.h>#include <sys/mman.h>int main(int argc, char* argv[]){ char array[2048]; if (mlock((const void *)array, sizeof(array)) == -1) { perror("mlock: "); return -1; } printf("success to lock stack mem at: %p, len=%zd\n", array, sizeof(array)); sleep(60); if (munlock((const void *)array, sizeof(array)) == -1) { perror("munlock: "); return -1; } printf("success to unlock stack mem at: %p, len=%zd\n", array, sizeof(array)); return 0;}编译后运行:gcc memlock.c -o memlock


(以上内容不代表本站观点。)
---------------------------------
本网站以及域名有仲裁协议。
本網站以及域名有仲裁協議。

2020-Jul-13 01:15am
栏目列表