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],我们可以获得以下输出:

从上面的输出中我们可以得到很多信息
- 当前进程中有多少线程
- 各线程当前的调用堆栈(即这个线程正在做什么)
通过这些信息,我们可以简单判断线程是否挂死或者阻塞,再通过堆栈信息定位到代码中具体的函数进一步排查
另外需要注意一点,只有保留了 debug symbols 的程序才可以 pstack,否则将看不到调用栈(如下图)

strace 的用法
strace 的用法也很简单,常用的选项有这几个:
- -f 跟踪目标进程,以及目标进程创建的所有子进程
- -t 在输出中的每一行前加上时间信息(-tt 表示微秒级)
- -T 显示每个系统调用所耗的时间
执行 strace ... -p [pid] 我们将获得如下的输出:

通过观察系统调用我们可以确认当前程序的行为,分析其消耗的时间、返回值是否正常
可以过滤指定的线程号,确认当前线程的行为是否符合预期
如果执行命令后完全没有输出,那么可以怀疑是否由于网络、IO等原因导致阻塞,或程序产生死锁
小结
有了这两个工具,当出现线上异常时,如果情况紧急,我们可以收集程序当前状态的信息,再进行救灾
待生产环境稳定后,可以慢慢分析是哪里产生的问题
另外分析 pstack / strace 的信息时,最好和日志对照观察
Debug 利器:pstack & strace的更多相关文章
- gstack pstack strace
gstack pstack strace 通过进程号 查看 进程的工作目录 Linux神器strace的使用方法及实践 - 知乎 https://zhuanlan.zhihu.com/p/180053 ...
- linux 调试利器gdb, strace, pstack, pstree, lsof
1) 如何使用strace+pstack利器分析程序性能? http://www.cnblogs.com/bangerlee/archive/2012/04/30/2476190.html 此文有详细 ...
- __FILE__,__LINE__,__func__ 真好用,DEBUG利器啊!
我是不喜欢用类似VC下的F5,F10.曾经很喜欢用.被代码逻辑逼的没招了.所以不喜欢用了. 比如,错误是根据动态数据,产生的行为错误,无论是该写的未写,还是不该写的写了.指针跑飞什么等等,无非就是上述 ...
- java应用诊断和在线debug利器bistoury介绍与在K8S环境使用
Bistoury介绍 Bistoury 是去哪儿网开源的一个对应用透明,无侵入的java应用诊断工具,用于提升开发人员的诊断效率和能力,可以让开发人员无需登录机器或修改系统,就可以从日志.内存.线程. ...
- MySQL 几种调式分析利器
目录 pstack gdb strace perf pstack 获取堆栈信息 问题线程的定位 负载较低 mysql_pid=4522 pstack $mysql_pid>pstack.info ...
- ps命令,性能监控,grep命令
Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...
- ansible配置文件详解
# ansible配置文件配置 配置项介绍 , 配置文件ansible.cfg, 运行playbook时,默认时在yaml文件所在路径寻找,然后再去/etc/ansible/下寻找 [defaults ...
- 浅谈 Java JPDA
前言 程序员在坊间有非常多有趣的故事,其中就有这么一则:”这个在我的电脑上是好的,没问题的呀,诺,你看咯,一定是你打开姿势不正确,浏览器版本不正确,操作系统不统一等,总之不是我代码问题(傲娇)”.看到 ...
- whistle学习(一)之安装、使用、软件功能了解
前言 whistle是基于Node实现的跨平台抓包调试代理工具,有以下基本功能: 查看HTTP.HTTPS请求响应内容 查看WebSocket.Socket收发的帧数据 设置请求hosts.上游htt ...
随机推荐
- 设计模式C++描述----09.桥接(Bridge)模式
一. 举例 N年前: 计算机最先出来时,软件和硬件是一绑在一起的,比如IBM出了一台电脑,上面有一个定制的系统,假如叫 IBM_Win,这个IBM_Win系统当然不能在HP电脑上运行,同样HP出的HP ...
- html2canvas 生成电子合同书
首先给合同书父级加个ref 然后用html2canvas 插件 然后html2canvas 坑区来了,生成页面的时候,合同书是很长的.他有一部分是黑色的, 最开始从前辈们了解到是滚至顶部解决偏移.然后 ...
- 《Effective Java》 读书笔记(五)使用依赖注入取代原本的资源依赖
相信接触过Spring的同学,对于依赖注入并不陌生. 刚开始在听说这个名字的时候,一直不明白到底什么叫依赖注入,后来才发现,依赖注入一直都存在我们日常代码中,只是我们没有刻意的把它提出来,然后再取这样 ...
- 使用float设置经典的网站前端结构(深入探讨)
.要是DIV的子元素宽度大于它自己的宽度,不管子元素有没有脱离文档流,子元素会在横向向右溢出. 关于高度:1.要是DIV的高度没有设定,其高度受“没有脱离文档流”的子元素影响.以下是DIV宽度为0的情 ...
- continue和break在while中用法
continue用法:结束本次循环,不执行continue下面的语句,返回执行下一次循环.注意:当执行完while的循环后,执行else 后的语句 break:结束循环,else下面语句也不执行
- CSPS模拟 87
考场上思考量不可减少 否则分数秒变弟弟,考后秒变弱智 T1 二分答案.打的稍恶心 T2 线段树维护“如果我在这个点开枪,前方点的贡献有多大” 想明白了就很好理解了 另外已经飞过去八千里的鸟还输入进来干 ...
- NOIP模拟 11
差点迟到没赶上开题 开题后看了T1,好像一道原题,没分析复杂度直接敲了个NC线段树,敲了个暴力,敲了个对拍,就1h了.. 对拍还对出错了,发现标记下传有点问题,改了以后对拍通过,就把T1扔掉看T2 觉 ...
- 使用Typescript重构axios(二十五)——文件上传下载进度监控
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 微信小程序云开发获取文件夹下所有文件
上周一个高中同学让我帮他做个图片展示的公众号,因为一直在加班的原因,所以一时忘了,昨晚想起来就赶紧加班加点的帮他弄了下,遇到了个问题,记录一下. 他的需求是要有个后台给他上传图片并且将图片归类,前端公 ...
- 深入理解计算机系统 第二章 信息的表示和处理 Part2 第二遍
<深入理解计算机系统> 第三版 第二遍读这本书,每周花两到三小时时间,能读多少读多少(这次看了 29 ~ 34 页) 第一遍对应笔记链接 https://www.cnblogs.com/s ...