pstack 是 Linux 下基于 gdb 的轻量级堆栈查看工具,用于诊断进程卡死、高 CPU 等问题;需目标进程属当前用户或有 sudo 权限,且系统已安装 gdb;支持单进程及多线程堆栈输出,可结合 ps 快速定位并采样分析。

pstack 是 Linux 下一个轻量、实用的调试工具,用于打印指定进程当前的函数调用堆栈(即线程的执行路径),常用于快速定位进程卡死、CPU 占用高或响应迟缓等问题。它本质是 gdb 的简化封装,无需源码和符号表也能输出基本栈帧,但有调试符号时信息更完整。
前提条件与权限要求
使用 pstack 需满足以下几点:
- 目标进程必须由当前用户启动,或当前用户具有 sudo 权限(否则会提示 “Permission denied”)
- 系统已安装 gdb(pstack 依赖 gdb 实现,多数发行版默认不预装 gdb,需手动安装,如:
sudo apt install gdb或sudo yum install gdb) - 推荐进程启用调试符号(编译时加
-g),否则函数名可能显示为问号或十六进制地址
基本用法:查看单个进程堆栈
命令格式简单直接:
pstack <PID>
例如,查看 PID 为 1234 的进程堆栈:
pstack 1234
输出示例(节选):
#0 0x00007f9a1b2c3a60 in __read_nocancel () from /lib64/libc.so.6
#1 0x00007f9a1b9d2e25 in _IO_file_underflow () from /lib64/libc.so.6
#2 0x00007f9a1b9d41b7 in __GI__IO_default_uflow () from /lib64/libc.so.6
#3 0x00007f9a1b9c953a in getc () from /lib64/libc.so.6
#4 0x00000000004011a2 in main (argc=1, argv=0x7ffdcf1a2b78) at demo.c:12
最后一行显示了源文件 demo.c 第 12 行的 main 函数调用点,说明符号可用。
查看多线程进程的全部线程堆栈
现代服务(如 Java、Nginx、Redis)通常为多线程。pstack 默认会列出进程中所有线程的独立堆栈,每组以 Thread N (LWP XXXX): 开头:
pstack 5678
你会看到类似:
Thread 3 (LWP 5681):
#0 0x00007f1a2b3c1a60 in pthread_cond_wait () from /lib64/libpthread.so.0
#1 0x0000000000402a1c in worker_loop () at server.c:88
...
重点关注处于 pthread_cond_wait、epoll_wait、nanosleep 等等待状态的线程——属正常;若多个线程长时间停留在锁操作(如 __lll_lock_wait)或自旋/循环逻辑中,则可能存在死锁或忙等。
结合 ps 快速定位可疑进程
实际排查中,常先找高 CPU 或无响应进程:
ps aux --sort=-%cpu | head -n 5
# 或按运行时间长筛选
ps -eo pid,lwp,stime,cmd --sort=stime | tail -n 5
拿到 PID 后,立即抓栈:
pstack $(pidof nginx) 2>/dev/null | head -n 20
加 2>/dev/null 可屏蔽权限错误;用 head 避免刷屏。对关键服务建议连续采样 2–3 次(间隔 2 秒),对比栈是否“冻结”在相同位置。
替代方案与注意事项
若 pstack 不可用或受限,可考虑:
-
cat /proc/<PID>/stack:仅适用于内核线程,用户态进程不支持 -
gdb -p <PID> -ex "thread apply all bt" -ex "detach" -ex "quit":功能等价但更重,适合需要深入分析场景 - 注意:pstack 会短暂暂停目标进程(类似 gdb attach),生产环境慎用于核心服务;避免在高并发写入场景中频繁使用
不复杂但容易忽略:确认 gdb 版本兼容性,较老系统(如 CentOS 6)的 gdb 可能不支持新内核线程模型,此时建议升级 gdb 或改用 gstack(部分系统中为 pstack 的软链接)。










