我正在调试在超过 1000 个进程上运行的并行程序中的挂起。我想获取所有这些进程的回溯。理想情况下,我想要一个将附加到进程的单行代码,将回溯获取到标准输出或文件,然后从程序中分离
我尝试了
gdb -p 1234 -ex 'thread apply all bt' -ex detach
但是GDB在打印回溯后没有分离
pstack
命令,用法pstack pid [...]
应该能够做到这一点。但是,作为 Debian/Ubuntu 二进制包提供的版本 (sudo apt install pstack
)“目前仅适用于 Linux,仅适用于运行 32 位 ELF 二进制文件的 x86 计算机(不支持 64 位)”。
另一个版本可在
https://github.com/peadar/pstack
以源形式获得。我能够从源代码构建它并将其安装在我的 Ubuntu 系统上。使用示例:
$ sleep 123 &
[1] 1852797
$ pstack 1852797
process: /proc/1852797/mem
thread: 0x7f5f596cd740, lwp: 1852797, type: 1
#0 0x00007f5f597b578a in __clock_nanosleep()+90 in /lib/x86_64-linux-gnu/libc.so.6 at clock_nanosleep.c:78
#1 0x00007f5f597ba677 in __nanosleep()+22 in /lib/x86_64-linux-gnu/libc.so.6 at nanosleep.c:25
#2 0x00005605badf9a00 in <unknown>() in /usr/bin/sleep
#3 0x00007f5f596f9d90 in __libc_start_call_main()+127 in /lib/x86_64-linux-gnu/libc.so.6 at libc_start_call_main.h:58
#4 0x00007f5f596f9e40 in __libc_start_main_impl()+127 in /lib/x86_64-linux-gnu/libc.so.6 at libc-start.c:392
#5 0x00005605badf9bb5 in <unknown>() in /usr/bin/sleep
$
echo "thread apply all bt" > gdb-cmds
gdb -p 1234 -batch -x gdb-cmds
有效
来自@https://stackoverflow.com/users/3228495/andrew
gdb -p 84653 -batch -ex 'thread apply all bt' -ex detach
也有效
gdb 发行版有一个脚本“pstack”,它采用 PID 参数,并显示所有线程的堆栈(带有回溯)+一些附加格式、旧/新内核的逻辑等。
pstack 1234
根据评论,看起来这个脚本不是核心 gdb 包的一部分。它存在于 RH 提供的构建/RPM 中。该脚本(和文档)可以在这里找到:https://nanxiao.me/en/use-pstack-to-track-threads-on-linux/
主要缺点是性能 - 启动 GDB 需要时间 - 特别是对于大型二进制文件。从积极的一面来看 - gdb 很可靠,并且可以根据需要自定义脚本 - 我创建了打印全局/局部变量等的修改版本。