13

有没有办法在不附加 GDB 的情况下打印所有线程的堆栈跟踪?

或者是否有一个命令可以用作 gdb 批处理模式来打印所有线程的堆栈跟踪?

4

6 回答 6

13

elfutils其他实用程序包括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
于 2018-03-20T09:05:47.060 回答
11

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然后分离。

于 2012-09-12T19:28:26.557 回答
3

堆栈?

用法:

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.
于 2012-09-12T19:40:15.140 回答
2

以下脚本适用于我在 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"
于 2017-03-28T11:02:43.093 回答
1

我一直在使用这个:

pidof program | xargs -n1 sudo gdb --batch -ex "thread apply all bt" -p
于 2017-01-12T14:09:48.907 回答
0

与 linux 中一样,所有线程本质上都是轻量级进程,它们获得单独的 LWP PID。ps您可以使用基于ortop的脚本或 echo输入win来转储这些状态/proc/sysrq-trigger。这将为您I/O提供/var/log/messages.

不过,这不会为您提供完整的堆栈跟踪。但它是定期调试线程状态的好方法。

/proc/sched_debug您还可以通过查看正在安排哪些任务等来探索当前的调度程序状态。

于 2012-09-12T20:44:30.163 回答