我知道我可以使用backtrace()或[NSThread callStackSymbols]来获取当前线程的堆栈跟踪,但是如何获得不同线程的堆栈跟踪(假设它已卡住)?

最佳答案

编辑:我的原始答案将不会从任意线程打印。此后,我在崩溃处理程序项目中编写了正确的实现:https://github.com/kstenerud/KSCrash

具体来说,这些文件:

  • https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSBacktrace.h
  • https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSBacktrace.c

  • 在以下方面的帮助下:
  • https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSMach.h
  • https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSMach.c

  • 您要做的是:
  • 新建机器上下文结构(_STRUCT_MCONTEXT)
  • 使用thread_get_state()填充其堆栈状态
  • 获取程序计数器(第一个堆栈跟踪条目)和帧指针(其余所有)
  • 逐步浏览帧指针指向的堆栈帧,并将所有指令地址存储在缓冲区中,以备后用。

  • 请注意,您应该在执行此操作之前先暂停线程,否则可能会导致无法预料的结果。

    堆栈框架填充有包含两个指针的结构:
  • 指向堆栈
  • 上一个上一级
  • 指令地址

  • 因此,在遍历框架以填充堆栈轨迹时,您需要考虑到这一点。还有可能发生堆栈损坏,导致指针错误,从而使程序崩溃的情况。您可以通过使用vm_read_overwrite()复制内存来解决此问题,它首先询问内核是否有权访问内存,因此它不会崩溃。

    一旦有了堆栈跟踪,就可以像正常情况一样在其上调用backtrace()(崩溃处理程序必须是异步安全的,因此它可以实现自己的backtrace方法,但在正常情况下,backtrace()可以)。

    关于iphone - 从另一个线程打印堆栈跟踪,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4765158/

    10-10 02:53