本文介绍了从另一个线程打印堆栈跟踪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know I can get the stack trace of the current thread using backtrace() or [NSThread callStackSymbols], but how would I get at the stack trace of a DIFFERENT thread (assuming it's been frozen)?

推荐答案

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

My original answer will not print from an arbitrary thread. I've since written a proper implementation in my crash handler project: 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()填充其堆栈状态
  • 获取程序计数器(第一个堆栈跟踪条目)和帧指针(其余所有帧)
  • 逐步遍历帧指针所指向的堆栈帧,并将所有指令地址存储在缓冲区中以备后用.

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

Note that you should pause the thread before doing this or else you can get unpredictable results.

堆栈框架填充了包含两个指针的结构:

The stack frame is filled with structures containing two pointers:

  • 指向堆栈中的下一个级别
  • 说明地址

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

So you need to take that into account when walking the frame to fill out your stack trace. There's also the possibility of a corrupted stack, leading to a bad pointer, which will crash your program. You can get around this by copying memory using vm_read_overwrite(), which first asks the kernel if it has access to the memory, so it doesn't crash.

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

Once you have the stack trace, you can just call backtrace() on it like normal (The crash handler has to be async-safe so it implements its own backtrace method, but in normal cases backtrace() is fine).

这篇关于从另一个线程打印堆栈跟踪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-17 16:44