当捕获到crash以后,捕获到的其实是一堆内存地址,需要将其转化为可读的符号,才能定位问题。
说到堆栈的符号化,我们很容易联想到DSYM文件,在Xcode build setting有个Debug Infomation Format的选项,如下图所示:

可以看到Debug模式下,符号表文件会存入到可执行文件中,而Release模式则会生成出DSYM文件。由于符号表在内存中,这为我们实时符号化堆栈提供了可能性。
1、线程的调用堆栈

如上图所示,一个函数的调用栈是由若干个栈帧组成,每个栈帧通过FP和SP划分界线。所以只要知道当前栈帧的 Stack Pointer 和 Frame Pointer,就能知道上一个栈帧的 Stack Pointer 和 Frame Pointer,从而递归的获取栈底的帧。
2、获取线程的SP、FP(寄存器值)
thread_get_state函数可以获得当前线程的使用的各个寄存器的信息
thread_get_state(thread, BS_THREAD_STATE, (thread_state_t)&machineContext->__ss, &state_count);
machineContext的类型是_STRUCT_MCONTEXT结构体,_STRUCT_MCONTEXT在不同的 cpu 架构会有所不同。以ARM64为例,_STRUCT_MCONTEXT结构体如下图所示:

可以发现__ss是保存线程的状态,进入_STRUCT_ARM_THREAD_STATE64结构体继续查看

可以发现_STRUCT_ARM_THREAD_STATE64结构体里面保存了重要的寄存器值,我们最关心的SP和FP也存在这里,其它的还有PC程序计算器,

最低0.47元/天 解锁文章
970

被折叠的 条评论
为什么被折叠?



