我如何找到线程树使用gdb

How do I find thread tree using gdb?

本文关键字:gdb 线程 何找      更新时间:2023-10-16

我在网上搜索,但没有结果。info thread提供与gdb相连的进程中当前活动的所有线程。我想知道是否有可能为gdb显示一个线程树,即列出的线程之间的父子关系。

为什么我想知道这个?在十二个线程中,其中一个线程正在等待其子线程的join_all()。如果我能理解主线程在哪些线程上等待,我就能更好地调试。

元数据:GDB version 7.7

我不认为你想要的信息是可用的,所以gdb没有一个内置的方式来显示它。

如果事情非常重要,我想你有几个选择。

1,在你的后续评论中,你提到一个线程试图加入它的子线程。因此,作为一种快速而肮脏的事情,您可以切换到该线程,"向上",并查看它正在等待的线程。

或者,您可以使用Python编写一些gdb代码以某种方式自动执行此操作,可以是特定于应用程序的,也可以通过在适当的位置(pthread_create等)设置断点来记录亲子关系信息。

试着运行这个命令,以获得所有线程的良好视图,看看它们在做什么。这可能比从线程树中计算更容易:

thread apply all bt

这将生成所有线程的回溯,然后你可以直观地看到谁在等待什么。

我最近想要这个信息,并制定了以下方案。它不是很漂亮,但是它打印了所有线程之间的父/子关系。

启动gdb后,但在运行程序之前,粘贴这些gdb命令:

set pagination off
break pthread_create
commands
set $a = newthread
continue
end
break pthread_create.c:611
commands
p "parent thread"
p/x pthread_self()
p "child thread"
p/x *$a
p "created from this stack"
where
continue
end

然后运行程序。

当你遇到崩溃或者你想要查看线程时,你可以使用"info threads"来列出所有当前线程,或者"thread"来打印当前线程的信息。然后,您可以向上滚动断点的所有输出,以查看线程之间的父/子关系。这还包括每个线程创建的堆栈跟踪,这比简单的线程id树更有用。

我没有手动滚动并查找ID,而是将整个gdb会话文本复制到emacs中并搜索匹配的线程ID。

第一个断点是调用pthread_create。这发生在父线程中。pthread_create()的第一个参数("newthread")是一个指向子线程ID所在位置的指针。遇到第一个断点时,将该指针保存在$a中。然后,我们需要继续执行,直到第二个断点,此时指针的目标将被子线程ID填充。

这是在ubuntu 14.04 linux上。如果您使用的库的版本差异很大,则可能需要更改第二个断点(在pthread_create.c:611处)。我发现行号实验通过做第一个断点没有"命令"部分,然后输入"直到"answers"打印*$a",直到它被孩子的线程ID填充。