Debug 利器:pstack & strace
工作中难免会遇到各种各样的 bug,对于开发环境 or 测试环境的问题还好解决,可以使用 gdb 打断点或者在代码中埋点来定位异常;
但是遇到线上的 bug 就很难受了,由于生产环境不能随意替换、中断程序,如果日志中找不到问题原因,解决问题就会很棘手
这时候就需要请出这两位 debug 利器了 ———— pstack & strace
什么是 pstack
pstack 是 Linux 系统下的一个命令行工具,此命令可以显示指定进程每个线程的堆栈快照,便于排查程序异常和性能评估
pstack 是基于 gdb 实现的,通过 man pstack 可以发现,它其实是 gstack 的一个软链接
GSTACK(1) Linux Programmer's Manual GSTACK(1) NAME gstack - print a stack trace of a running process SYNOPSIS gstack pid DESCRIPTION gstack attaches to the active process named by the pid on the command line, and prints out an execution stack trace. If ELF symbols exist in the binary (usually the case unless you have run strip(1)), then symbolic addresses are printed as well. If the process is part of a thread group, then gstack will print out a stack trace for each of the threads in the group. SEE ALSO nm(1), ptrace(2), gdb(1) AUTHORS Ross Thompson <ross@whatsis.com> Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla> Red Hat Linux Feb 15 2008 GSTACK(1)
[root@Centos6x64 bin]# pwd /usr/bin [root@Centos6x64 bin]# ll -h | grep gstack -rwxr-xr-x. 1 root root 1.1K 3月 22 2017 gstack lrwxrwxrwx. 1 root root 6 8月 24 21:21 pstack -> gstack
而 gstack 则是封装了 gdb 功能的 shell 脚本,通过 " thread apply all bt " 的命令获得输出所有的线程堆栈信息,再用 sed 进行替换和过滤
# Run GDB, strip out unwanted noise. $GDB --quiet $readnever -nx /proc/$1/exe $1 <<EOF 2>&1 | set width 0 set height 0 set pagination no $backtrace EOF /bin/sed -n \ -e 's/^\((gdb) \)*//' \ -e '/^#/p' \ -e '/^Thread/p'
什么是 strace
使用 pstack 获得的进程堆栈是程序的静态信息,而使用 strace 可以获得程序的动态信息,即程序现在正在做什么(执行哪些系统调用和所接收的信号)
strace 的功能主要是通过 ptrace 这个系统调用来实现的,它提供了父进程观察/控制子进程的能力
#include <sys/ptrace.h> long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
当使用了 pstrace 跟踪子进程后,所有发送给被跟踪子进程的信号都会转发给父进程(SIGKILL 除外),而子进程则会阻塞,被标注为 TASK_TRACED 状态
父进程收到信号后,可以对阻塞的子进程进行检查和修改,然后让子进程继续运行
关于 strace 的参数可以参考:strace 跟踪进程中的系统调用
或者查看 Linux 手册 man strace
如何使用 pstack & strace 排查程序问题
pstack 的用法
通过 ps / pidof 命令获取到异常进程的 pid,执行 pstack [pid],我们可以获得以下输出:
从上面的输出中我们可以得到很多信息
- 当前进程中有多少线程
- 各线程当前的调用堆栈(即这个线程正在做什么)