19

在 Linux 中,要获得回溯,您可以使用 backtrace() 库调用,但它只返回当前线程的回溯。假设我知道它是 TID(或 pthread_t)并且我可以保证它处于睡眠状态,是否有任何方法可以获取其他线程的回溯?

似乎 libunwind (http://www.nongnu.org/libunwind/) 项目可以提供帮助。问题是 CentOS 不支持它,所以我不想使用它。

还有其他想法吗?谢谢。

4

3 回答 3

11

在这里自己实现了。

最初,我想实现与此处建议的类似的东西,即以某种方式获取线程的顶部帧指针并手动展开它(链接的源代码源自 Applebacktrace的实现,因此可能是 Apple 特定的,但这个想法是通用的)。

然而,为了保证安全(上面的源代码不是,甚至可能被破坏),你必须在访问它的堆栈时挂起线程。我四处寻找暂停线程的不同方法,发现了这个这个这个。基本上,没有真正好的方法。Hotspot JAVA VM 也使用的常见技巧是使用信号并通过pthread_kill向您的线程发送自定义信号。

因此,无论如何我都需要这样的信号破解,我可以让它更简单一些,只需backtrace在目标线程中执行的被调用信号处理程序中使用(正如sandeep 在这里所建议的那样)。这基本上就是我的实现正在做的事情。

如果您也对打印回溯感兴趣,即获取一些有用的调试信息(函数名、源代码文件名、源代码行号,...),请在此处阅读有关backtrace_symbols基于 libbfd 的扩展。或者只是在这里查看源代码。

于 2012-04-06T22:29:02.817 回答
9

在回溯的帮助下进行信号处理可以解决您的目的。

我的意思是如果你有一个线程的 PID,你可以为那个线程发出一个信号。在处理程序中,您可以使用回溯。由于处理程序将在该特定线程中执行,因此回溯将是您需要的输出。

于 2011-06-20T06:44:07.373 回答
1

gdb 为调试多线程程序提供了这些工具:

  • 自动通知新线程
  • 'thread thread-id',线程间切换命令
  • 'info threads',查询现有线程的命令
  • 'thread apply [thread-id-list] [all] args',将命令应用于线程列表的命令
  • 线程特定的断点
  • 'set print thread-events',控制线程启动和退出时消息的打印。
  • 'set libthread-db-search-path path',如果默认选择与程序不兼容,用户可以指定使用哪个 libthread_db。

所以只需通过 cmd 转到 GDB 中所需的线程:'thread thread-id'。然后在该线程上下文中执行“bt”以打印线程回溯。

于 2016-11-03T06:57:37.360 回答