我知道我可以使用backtrace()或[NSThread callStackSymbols]获取当前线程的堆栈跟踪,但是我如何获得不同线程的堆栈跟踪(假设它被冻结)?
答案 0 :(得分:11)
编辑:我的原始答案不会从任意线程打印出来。我已经在崩溃处理程序项目中编写了一个正确的实现:https://github.com/kstenerud/KSCrash
具体来说,这些文件:
得到一些帮助:
你做的是:
请注意,您应该在执行此操作之前暂停线程,否则可能会产生不可预测的结果。
堆栈框架中填充了包含两个指针的结构:
因此,您需要在走框架时考虑到这一点,以填写堆栈跟踪。还有可能堆栈损坏,导致指针坏,这会导致程序崩溃。你可以通过使用vm_read_overwrite()复制内存来解决这个问题,vm_read_overwrite()会首先询问内核是否可以访问内存,因此它不会崩溃。
一旦你有了堆栈跟踪,就可以像往常一样在它上面调用backtrace()(崩溃处理程序必须是异步安全的,所以它实现了自己的backtrace方法,但在正常情况下,backtrace()很好)。
答案 1 :(得分:3)
以下是从另一个线程获取callstack的更安全的方法:Implementation和some background information。它使用信号处理并在目标线程中生成信号处理程序。它的优点还在于它比您的解决方案更具跨平台性,即它应该适用于<signal.h>
和<execinfo.h>
的任何位置。
对于打印,您可以像在自己的建议中一样使用backtrace_symbols
。但是您可能对实现here的扩展版本感兴趣。它使用libbfd(来自binutils;最新版本也主要适用于MacOSX,请参阅here以获取可能与您无关的小限制)来读取调试信息并添加行号和其他信息(如果所有其他信息都失败,它也会回退到dladdr
;这就是backtrace_symbols
正在做的事情。