进程内存映射:pmap -x
pmap 命令检查进程,显示进程地址空间内的每个映射。
显示每个映射的常驻、非共享匿名和锁定内存量。
这允许我们估计共享和私有内存使用情况。
$ pmap -x 102908 102908: sh Address Kbytes Resident Anon Locked Mode Mapped File 00010000 88 88 - - r-x-- sh 00036000 8 8 8 - rwx-- sh 00038000 16 16 16 - rwx-- [ heap ] FF260000 16 16 - - r-x-- en_.so.2 FF272000 16 16 - - rwx-- en_US.so.2 FF280000 664 624 - - r-x-- libc.so.1 FF336000 32 32 8 - rwx-- libc.so.1 FF360000 16 16 - - r-x-- libc_psr.so.1 FF380000 24 24 - - r-x-- libgen.so.1 FF396000 8 8 - - rwx-- libgen.so.1 FF3A0000 8 8 - - r-x-- libdl.so.1 FF3B0000 8 8 8 - rwx-- [ anon ] FF3C0000 152 152 - - r-x-- ld.so.1 FF3F6000 8 8 8 - rwx-- ld.so.1 FFBFE000 8 8 8 - rw--- [ stack ] -------- ----- ----- ----- ----- total Kb 1072 1032 56
进程的 Grepping:pgrep
pgrep 命令提供了一种生成匹配特定条件的进程 ID 列表的便捷方法。
$ pgrep filebench 22968 22961 22966 22979 ...
进程的执行时间统计:ptime
可以使用 ptime 命令对进程进行计时,以获得准确的微观状态记帐工具。
$ ptime sleep 1 real 1.203 user 0.022 sys 0.140
进程工作目录:pwdx
可以使用 pwdx 命令显示进程的当前工作目录。
$ pwdx 22961 22961: /tmp/filebench
进程树:ptree
进程父子关系可以用ptree命令显示。
默认情况下,显示同一进程组 ID 中的所有进程。
$ ptree 22961 301 /usr/lib/ssh/sshd 21571 /usr/lib/ssh/sshd 21578 /usr/lib/ssh/sshd 21580 -ksh 22961 /opt/filebench/bin/filebench 22962 shadow -a shadow -i 1 -s ffffffff10000000 -m /var/tmp/fbench9Ca 22963 shadow -a shadow -i 2 -s ffffffff10000000 -m /var/tmp/fbench9Ca 22964 shadow -a shadow -i 3 -s ffffffff10000000 -m /var/tmp/fbench9Ca 22965 shadow -a shadow -i 4 -s ffffffff10000000 -m /var/tmp/fbench9Ca
收割僵尸进程:preap
可以使用 Solaris 9 中添加的 preap 命令收割僵尸进程。
$ preap 22961 (sleep...)
进程堆栈:pstack
可以使用 pstack 命令显示进程内所有或者特定线程的堆栈。
$ pstack 23154 23154: shadow -a shadow -i 193 -s ffffffff10000000 -m /var/tmp/fbench9Cai2S ----------------- lwp# 1 / thread# 1 ------------------- ffffffff7e7ce0f4 lwp_wait (2, ffffffff7fffe9cc) ffffffff7e7c9528 _thrp_join (2, 0, 0, 1, 100000000, ffffffff7fffe9cc) + 38 0000000100018300 threadflow_init (ffffffff3722f1b0, ffffffff10000000, 10006a658, 0, 0, 1000888b0) + 184 00000001000172f8 procflow_exec (6a000, 10006a000, 0, 6a000, 5, ffffffff3722f1b0) + 15c 0000000100026558 main (a3400, ffffffff7ffff948, ffffffff7fffeff8, a4000, 0, 1) + 414 000000010001585c _start (0, 0, 0, 0, 0, 0) + 17c ----------------- lwp# 2 / thread# 2 ------------------- 000000010001ae90 flowoplib_hog (30d40, ffffffff651f3650, 30d40, ffffffff373aa3b8, 1, 2e906) + 68 00000001000194a4 flowop_start (ffffffff373aa3b8, 0, 1, 0, 1, 1000888b0) + 408 ffffffff7e7ccea0 _lwp_start (0, 0, 0, 0, 0, 0)
pstack 命令对于诊断进程挂起或者核心转储的状态非常有用。
默认情况下,它显示进程内所有线程的堆栈回溯。
它也可以用作粗略的性能分析技术;通过获取进程堆栈的一些示例,我们通常可以确定进程花费大部分时间的地方。
进程标志:pflags
pflags 命令显示进程的各种状态信息。
信息包括进程运行的 32 位或者 64 位模式以及进程内每个线程的当前状态。
此外,还会显示每个线程堆栈上的顶级函数。
$ pflags $$ 482764: -ksh data model = _ILP32 flags = PR_ORPHAN /1: flags = PR_PCINVAL|PR_ASLEEP [ waitid(0x7,0x0,0xffbff938,0x7) ]
在 Solaris 中,有很多工具可用于分析和调试操作系统的每个部分。
最常见的是进程分析工具。
由于有很多用于进行分析的工具,因此将它们归为通用工具会有所帮助。
一般语法如下:
$ ptool pid $ ptool pid/lwpid
常见命令说明:
- prstat - 用于查看整体进程状态
- ps - 打印进程状态和信息
- ptree - 打印进程祖先树
- pgrep; pkill - 匹配进程名称;发送信号
- pstop; prun - 冻结进程;继续一个过程
- pwait - 等待进程完成
- preap - 收割僵尸
- pstack - 用于检查堆栈回溯
- pmap - 用于查看内存段详细信息
- pfiles - 用于列出文件描述符的详细信息
- ptime - 用于计时命令
- psig - 列出信号处理程序
- pldd - 列出动态库
- pflags; pcred - 列出跟踪标志;列出进程凭据
- pargs; pwdx - 列出参数,env;列出工作目录
- plockstat - 用于观察锁活动
下面将简要解释每个工具:
进程文件表:pfiles
可以使用 pfiles 命令获取进程内打开的文件列表。
# pfiles 21571 21571: /usr/lib/ssh/sshd Current rlimit: 256 file descriptors 0: S_IFCHR mode:0666 dev:286,0 ino:6815752 uid:0 gid:3 rdev:13,2 O_RDWR|O_LARGEFILE /devices/pseudo/mm@0:null 1: S_IFCHR mode:0666 dev:286,0 ino:6815752 uid:0 gid:3 rdev:13,2 O_RDWR|O_LARGEFILE /devices/pseudo/mm@0:null 2: S_IFCHR mode:0666 dev:286,0 ino:6815752 uid:0 gid:3 rdev:13,2 O_RDWR|O_LARGEFILE /devices/pseudo/mm@0:null 3: S_IFCHR mode:0000 dev:286,0 ino:38639 uid:0 gid:0 rdev:215,2 O_RDWR FD_CLOEXEC /devices/pseudo/crypto@0:crypto 4: S_IFIFO mode:0000 dev:294,0 ino:13099 uid:0 gid:0 size:0 O_RDWR|O_NONBLOCK FD_CLOEXEC 5: S_IFDOOR mode:0444 dev:295,0 ino:62 uid:0 gid:0 size:0 O_RDONLY|O_LARGEFILE FD_CLOEXEC door to nscd[89] /var/run/name_service_door
暂时停止进程:pstop
可以使用 pstop 命令暂时挂起进程。
$ pstop 22961
进程库:pldd
可以使用 pldd 显示当前映射到进程的库列表。
这对于验证正在动态链接到进程中的库的哪个版本或者路径很有用。
$ pldd $$ 482764: -ksh /usr/lib/libsocket.so.1 /usr/lib/libnsl.so.1 /usr/lib/libc.so.1 /usr/lib/libdl.so.1 /usr/lib/libmp.so.2
检查进程中的用户级锁
使用进程锁统计命令 plockstat(1M) ,我们可以观察使用用户级锁的用户应用程序中的热锁行为。
plockstat 命令使用 DTrace 来检测和测量锁统计信息。
# plockstat -p 27088 ^C Mutex block Count nsec Lock Caller ------------------------------------------------------------------------------ 102 39461866 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 4 21605652 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 11 19908101 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 12 16107603 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 10 9000198 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 14 5833887 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 10 5366750 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 120 964911 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 48 713877 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 52 575273 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 89 534127 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 14 427750 libaio.so.1`__aio_mutex libaio.so.1`_aio_lock+0x28 1 348476 libaio.so.1`__aio_mutex libaio.so.1`_aio_req_add+0x228 Mutex spin
过程信号处理:psig
可以使用 psig 显示信号列表及其当前配置。
$ psig $$ 15481: -zsh HUP caught 0 INT blocked,caught 0 QUIT blocked,ignored ILL blocked,default TRAP blocked,default ABRT blocked,default EMT blocked,default FPE blocked,default KILL default BUS blocked,default SEGV blocked,default SYS blocked,default PIPE blocked,default ALRM blocked,caught 0 TERM blocked,ignored USR1 blocked,default USR2 blocked,default CLD caught 0 PWR blocked,default WINCH blocked,caught 0 URG blocked,default POLL blocked,default STOP default
过程参数:pargs
可以使用 pargs 命令为进程显示完整的进程参数和可选的当前环境设置列表。
$ pargs -ae 22961 22961: /opt/filebench/bin/filebench argv[0]: /opt/filebench/bin/filebench envp[0]: _=/opt/filebench/bin/filebench envp[1]: MANPATH=/usr/man:/usr/dt/man:/usr/local/man:/opt/SUNWspro/man:/ws/on998 tools/teamware/man:/home/rmc/local/man envp[2]: VISUAL=/bin/vi ...
进程凭证:pcred
进程的凭据可以用 pcred 显示。
$ pcred $$ 482764: e/r/suid=36413 e/r/sgid=10 groups: 10 10512 570
杀死进程:pkill
pkill 命令提供了一种将信号发送到符合特定条件的列表或者进程的便捷方式。
$ pkill -HUP in.named
如果未指定信号,则默认为发送 SIGTERM 。
使进程可运行:修剪
可以使用 prun 命令使进程可运行。
$ prun 22961
等待进程完成:pwait
pwait 命令阻塞并等待进程终止。
$ pwait 22961 (sleep...)