在不附加GDB的情况下获取所有线程的堆栈跟踪
Getting stacktrace of all threads without attaching GDB
有没有一种方法可以在不附加GDB的情况下打印所有线程的堆栈跟踪?
或者有没有一个命令可以作为gdb批处理模式来打印所有线程的堆栈?
elutils和其他实用程序包括eu-stack
:
eu-stack Print a stack for each thread in a process or core file.
它比gdb或pstack更快,后者只是围绕gdb的shell脚本包装器。要打印堆栈跟踪,请按如下方式运行eu-stack
:
$ eu-stack -p 2209
PID 2209 - process
TID 2209:
#0 0x00007f53476b667b __poll
#1 0x00007f5348f98e99 g_main_context_iterate.isra.23
#2 0x00007f5348f99232 g_main_loop_run
#3 0x000055e604b1e56a main
#4 0x00007f53475cc00a __libc_start_main
#5 0x000055e604b1e76a _start
TID 2223:
#0 0x00007f53476b667b __poll
#1 0x00007f5348f98e99 g_main_context_iterate.isra.23
#2 0x00007f5348f98fac g_main_context_iteration
#3 0x00007f5348f98ff1 glib_worker_main
#4 0x00007f5348fc0486 g_thread_proxy
#5 0x00007f534813761b start_thread
#6 0x00007f53476c2c2f __clone
TID 2224:
#0 0x00007f53476b667b __poll
#1 0x00007f5348f98e99 g_main_context_iterate.isra.23
#2 0x00007f5348f99232 g_main_loop_run
#3 0x00007f5349581b56 gdbus_shared_thread_func
#4 0x00007f5348fc0486 g_thread_proxy
#5 0x00007f534813761b start_thread
#6 0x00007f53476c2c2f __clone
GDB:中有一个thread apply all
命令
(gdb) thread apply all bt
Thread 12 (Thread 0x7f7fe2116700 (LWP 5466)):
#0 sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
#1 0x0000000000425358 in ?? ()
...
Thread 1 (Thread 0x7f7feabc27c0 (LWP 5465)):
#0 0x00007f7fe76c5203 in select () at ../sysdeps/unix/syscall-template.S:82
遗憾的是,GDB似乎无法从管道中读取命令,因此要在其批处理模式下运行命令,必须使用一个临时文件:
$ gdbbt() {
tmp=$(tempfile)
echo thread apply all bt >"$tmp"
gdb -batch -nx -q -x "$tmp" -p "$1"
rm -f "$tmp"
}
$ gdbbt $(pidof $SHELL)
那么你只会";暂时地";用gdb
连接然后分离。
以下脚本在linux上适用请注意,它首先找到可执行文件的目录并更改到该目录(因为可执行文件可以通过使用链接期间指定的-Wl、-rpath、$dir具有具有相对路径的共享库,并且您希望gdb为堆栈跟踪找到这些共享库的符号)。它还假设gdb存在于系统中。
#!/bin/bash
pid=$1
EXE=`readlink -f /proc/$pid/exe`
DIR=`dirname $EXE`
cd $DIR
gdb $EXE --batch -ex "attach $pid" -ex "thread apply all bt"
pstack?
用法:
pstack <pid>
来自手册页:
pstack - print a stack trace of a running process
...
If the process is part of a thread group, then pstack will print out a stack trace for each of the threads in the group.
我一直在使用这个:
pidof program | xargs -n1 sudo gdb --batch -ex "thread apply all bt" -p
在linux中,所有线程本质上都是轻量级进程,它们获得单独的LWP PID。您可以使用基于ps
或top
的脚本或使用/proc/sysrq-trigger
中的w
的echo
来转储这些脚本的状态。这将为您提供/var/log/messages
中线程的I/O
状态。
不过,这不会为您提供完整的堆栈跟踪。但这是一种以周期性间隔调试线程状态的好方法。
您还可以通过查看/proc/sched_debug
来了解当前调度程序的状态,查看哪些任务正在被调度等等。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 异常属于C++中的线程还是进程
- C++中的线程安全删除
- C++使用params创建线程函数会导致转换错误
- 类与私有变量的其他类之间的线程安全性
- CoInitialize()在单独的线程上崩溃而不返回
- c++中的线程池
- 线程之间的布尔停止信号
- 为什么std::async使用同一个线程运行函数
- 用于矢量处理的多个线程
- 来自回溯的堆栈跟踪未显示导致多线程环境下崩溃的方法
- 如果一个且只有一个线程被停止,可以从多线程进程中跟踪读/写数据