我在网上搜索但是徒劳无功。 info thread
提供与gdb附加的进程中当前存在的所有线程。我想知道gdb是否可以显示线程树,即列出的线程之间的父子关系。
为什么我想知道?:在十几个线程中,其中一个线程正在等待其子线程的join_all()。如果我能理解主线程在哪些线程上等待,我可以更好地调试。
元数据: gdb版本7.7
答案 0 :(得分:2)
我认为您想要的信息不可用,因此gdb没有内置的显示方式。
如果非常重要,我猜你有几个选择。
一,在你的后续评论中,你提到一个主题正在尝试加入其子代。所以,作为一个快速和肮脏的东西,你可以切换到该线程,“向上”,并查看它正在等待的线程。
或者,您可以使用Python编写一些gdb代码以某种方式自动执行此操作,特定于应用程序或通过在适当的位置设置断点(pthread_create等)来记录父母信息。这有点难。
答案 1 :(得分:1)
尝试运行此操作以获得所有线程的良好视图,以查看它们正在执行的操作。它可能比从线程树中找出更容易:
thread apply all bt
这将生成所有线程的回溯,然后您可以直观地看到谁在等待什么。
答案 2 :(得分:0)
我最近想要这个信息,并制定了以下方案。它并不漂亮,但它会打印所有线程之间的父/子关系。
启动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"列出所有当前线程,或者"线程"打印有关当前线程的信息。然后,您可以向上滚动来自断点的所有输出,以查看线程之间的父/子关系。这还包括每个线程创建的堆栈跟踪,这比一个简单的线程ID树更有用。
我不是向后滚动并手动查找ID,而是将整个gdb会话文本复制到emacs中并搜索匹配的线程ID。
第一个断点是对pthread_create的调用。这发生在父线程中。 pthread_create()的第一个参数(" newthread")是指向将放置子线程ID的位置的指针。当第一个断点被击中时,我们将该指针保存在$ a中。然后我们需要继续执行直到第二个断点,此时指针的目标将被子线程的线程ID填充。
这是在ubuntu 14.04 linux上。如果您的库版本差异很大,则第二个断点(在pthread_create.c:611)可能需要更改。我通过第一个断点实验性地找到了行号而没有"命令"部分,然后键入"直到"和"打印* $ a"直到它充满了孩子的线程ID。