for*_*rk0 12
thread apply allGDB中有一个命令:
(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
Run Code Online (Sandbox Code Playgroud)
遗憾的是,GDB似乎无法从管道中读取命令,因此要以批处理模式运行命令,必须使用临时文件:
$ gdbbt() {
tmp=$(tempfile)
echo thread apply all bt >"$tmp"
gdb -batch -nx -q -x "$tmp" -p "$1"
rm -f "$tmp"
}
$ gdbbt $(pidof $SHELL)
Run Code Online (Sandbox Code Playgroud)
ks1*_*322 12
elfutils和其他实用程序包括eu-stack:
Run Code Online (Sandbox Code Playgroud)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
Run Code Online (Sandbox Code Playgroud)
以下脚本在 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"
Run Code Online (Sandbox Code Playgroud)