C++获取不同线程的回溯信息

5
我想了解如何从另一个线程中获取特定线程在软件中的状态,特别是是否出现了I/O阻塞。我考虑通过获取回溯信息(除非有其他想法?)来实现,因为我知道它应该卡在哪个函数上了。但我无法弄清楚如何获取特定线程的回溯信息,而不调用SEGFAULT处理程序。gdb可以做到这一点(我怀疑它会创建SEGFAULTS..)。有人能帮忙吗?有什么想法吗?[编辑]所有3个答案都提到了gdb,我知道我可以从gdb中进行操作,但我想知道如何从软件中实现(即使链接到gdb库也是一个答案,但是如何实现呢?)

在Linux上,您可以轻松打开/proc/<pid>/stat(或/proc/<pid>/task/<tid>/stat)并读取堆栈和指令指针。您的平台要求是什么? - Useless
如果你知道你可能卡在哪个函数里,那么你可不可以在进入和离开该函数时设置和清除一个标志,并将其作为对其他线程的指示? - Soren
你需要为哪个平台进行开发? - alk
@soren,不适用于高并发故障检测。 - Alon
如果要检查的线程正在运行,则无法可靠地执行该操作。 - Basile Starynkevitch
我知道应该在哪里停止,这就是我想要检查的内容。如果没有停止,那就是一个错误,这就是我想要找出来的。 - Alon
3个回答

4
我知道它应该卡在哪个函数上...但我不知道如何获取该特定线程的回溯(backtrace)。
您可以获取所有线程的回溯(backtraces),并尝试在回溯输出中找到应该卡在哪个函数上。以下是如何在gdb中获取所有回溯(backtraces)的方法:
(gdb) thread apply all bt

虽然这很有趣(因此加一分),但是原文提到要在软件中实现,而不是使用gdb。 - Soren
正如Soren所评论的那样,我需要知道如何从软件中完成它,而不是使用gdb。 - Alon
@Alon,gdb本身使用libthread_db库来列出线程,因此您可以在应用程序中执行相同操作。首先,您需要加载它(这并不是很明显)。请参阅此博客以了解如何加载它:http://timetobleed.com/notes-about-an-odd-esoteric-yet-incredibly-useful-library-libthread_db/ 。 - ks1322

1

(gdb) info threads [将列出所有线程,并指示您当前正在回溯的线程]

(gdb) thread apply all bt [将显示所有线程的回溯,以便您可以查看哪个线程在您感兴趣的函数上卡住,然后切换到该线程]

(gdb) thread #threadno [将切换回溯到您感兴趣的特定线程,bt 将显示其回溯。]

参考资料 http://www.delorie.com/gnu/docs/gdb/gdb_25.html


0

既然你知道你认为自己卡住的函数是哪个,那么你可以在该函数的开头设置一个断点。GDB允许你将一系列命令附加到断点上,在断点被触发时自动执行这些命令,从而允许你打印出执行该断点时正在执行的线程的回溯信息。

(gdb) break filename:line
(gdb) commands
Type commands for breakpoint(s) 1, one per line
End with a line saying just "end"
>info threads
>bt
>continue
>end

以上代码将给出线程列表,在断点处由活动线程标有*,随后是回溯信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接