在 Linux 中,要获得回溯,您可以使用 backtrace() 库调用,但它只返回当前线程的回溯。假设我知道它是 TID(或 pthread_t)并且我可以保证它处于睡眠状态,是否有任何方法可以获取其他线程的回溯?
似乎 libunwind (http://www.nongnu.org/libunwind/) 项目可以提供帮助。问题是 CentOS 不支持它,所以我不想使用它。
还有其他想法吗?谢谢。
在 Linux 中,要获得回溯,您可以使用 backtrace() 库调用,但它只返回当前线程的回溯。假设我知道它是 TID(或 pthread_t)并且我可以保证它处于睡眠状态,是否有任何方法可以获取其他线程的回溯?
似乎 libunwind (http://www.nongnu.org/libunwind/) 项目可以提供帮助。问题是 CentOS 不支持它,所以我不想使用它。
还有其他想法吗?谢谢。
我在这里自己实现了。
最初,我想实现与此处建议的类似的东西,即以某种方式获取线程的顶部帧指针并手动展开它(链接的源代码源自 Applebacktrace
的实现,因此可能是 Apple 特定的,但这个想法是通用的)。
然而,为了保证安全(上面的源代码不是,甚至可能被破坏),你必须在访问它的堆栈时挂起线程。我四处寻找暂停线程的不同方法,发现了这个、这个和这个。基本上,没有真正好的方法。Hotspot JAVA VM 也使用的常见技巧是使用信号并通过pthread_kill向您的线程发送自定义信号。
因此,无论如何我都需要这样的信号破解,我可以让它更简单一些,只需backtrace
在目标线程中执行的被调用信号处理程序中使用(正如sandeep 在这里所建议的那样)。这基本上就是我的实现正在做的事情。
如果您也对打印回溯感兴趣,即获取一些有用的调试信息(函数名、源代码文件名、源代码行号,...),请在此处阅读有关backtrace_symbols
基于 libbfd 的扩展。或者只是在这里查看源代码。
在回溯的帮助下进行信号处理可以解决您的目的。
我的意思是如果你有一个线程的 PID,你可以为那个线程发出一个信号。在处理程序中,您可以使用回溯。由于处理程序将在该特定线程中执行,因此回溯将是您需要的输出。
gdb 为调试多线程程序提供了这些工具:
所以只需通过 cmd 转到 GDB 中所需的线程:'thread thread-id'。然后在该线程上下文中执行“bt”以打印线程回溯。