想看一个进程的 堆栈(stack)信息,有很多种方法,主要取决于你是想:
- 调试查看堆栈回溯(比如看看程序卡在哪)
- 分析崩溃 / 死锁 / 阻塞
- 查看线程的栈使用情况 / 栈空间地址
下面我分情况给你列出查看进程堆栈的几种常用方法:
🧵 一、用 gdb
查看进程堆栈(最强大)
适合调试或分析运行中的进程。
✅ 步骤:
gdb -p <pid>
然后进入 GDB 命令行:
(gdb) bt
bt
(backtrace)会打印出当前进程或主线程的函数调用栈。
👉 也可以查看所有线程:
(gdb) info threads
(gdb) thread <n>
(gdb) bt
退出:quit
🔍 二、用 pstack
快速查看堆栈(简洁)
pstack <pid>
输出类似这样:
#0 0x00007f8c45 in poll () from /lib/libc.so.6
#1 0x00007f8c12 in __libc_start_main () from /lib/libc.so.6
...
每个线程的调用栈都会列出来,很适合快速查看“进程卡在哪里”。
🔎 三、用 cat /proc/<pid>/stack
查看主线程栈(只看一点点)
cat /proc/<pid>/stack
这是 Linux 提供的接口,只显示主线程当前正在执行的内核栈,例如:
[<ffffffff81234567>] futex_wait_queue_me+0xd7/0x140
[<ffffffff81234567>] futex_wait+0x189/0x270
...
适合快速判断:这个进程卡在 futex 等锁了没?
📦 四、用 strace
看系统调用(间接观察栈行为)
strace -p <pid>
虽然 strace
不直接给你堆栈,但你可以看到当前进程卡在哪个系统调用,比如:
futex(0xdeadbeef, FUTEX_WAIT, 1, NULL
你就知道它在睡觉了 😂
🧵 五、分析所有线程堆栈(多线程程序)
用 gdb
或 pstack
都可以查看全部线程:
gdb -p <pid>
→info threads
pstack <pid>
(会输出所有线程的栈)cat /proc/<pid>/task/<tid>/stack
可以查看任意线程的内核栈
🔥 实战:假设你想分析一个卡住的进程
- 找 PID:
ps aux | grep <your_app>
- 看堆栈:
pstack <pid>
- 如果你想深入分析:
gdb -p <pid>
# 然后在 GDB 里用 bt 看回溯
- 想看哪个线程卡住了,可以在 GDB 用:
info threads
thread <n>
bt
🧠 bonus:查看栈空间使用情况
cat /proc/<pid>/maps | grep stack
输出示例:
7fff5d1c6000-7fff5d1e8000 rw-p 00000000 00:00 0 [stack]
这告诉你栈的虚拟内存范围,想看使用量可以用 smaps
:
cat /proc/<pid>/smaps | grep -A 15 '\[stack\]'
✅ 总结你可以用的命令
命令 | 作用 |
---|---|
gdb -p <pid> + bt | 最详细,调试视角 |
pstack <pid> | 快速查看所有线程堆栈 |
cat /proc/<pid>/stack | 查看主线程内核栈 |
strace -p <pid> | 看是否卡在系统调用 |
cat /proc/<pid>/maps | 查看栈地址空间 |
cat /proc/<pid>/task/<tid>/stack | 查看指定线程内核栈 |
如果你能告诉我你是要分析什么样的程序(比如阻塞了?挂死了?死锁了?),我可以一步一步带你排查,还可以帮你写个一键堆栈收集脚本。要不要试试?