在How do I recover from EXC_BAD_ACCESS?中,我想出了如何从EXC_BAD_ACCESS
恢复,但我将访问不良的指针存储在全局中。显然,这不会扩大规模。当我在iOS模拟器(i386)中运行代码时,我可以在faultvaddr
函数内部看到Exception State Registers
在调试器的catch_exception_raise
部分注册。但是,它的值与vm_allocate
返回的指针不同或接近。有没有办法动态获取此值?
鉴于以下catch_exception_raise
功能,我如何找到导致EXC_BAD_ACCESS
的地址?
kern_return_t
catch_exception_raise(mach_port_t exception_port,
mach_port_t thread,
mach_port_t task,
exception_type_t exception,
exception_data_t code_vector,
mach_msg_type_number_t code_count)
{
fprintf(stderr, "catch_exception_raise %d\n", exception);
return KERN_SUCCESS;
}
答案 0 :(得分:2)
OS X和iOS Internals书籍(http://www.newosxbook.com)中有大量详细信息。书中的清单11-21(同上)实际上显示了这样做的示例代码。简而言之,您有两种选择:
A)从异常数据中查看异常本身 - 将状态转换为arm_thread_state,如下所示:
struct arm_thread_state *atsh = &exc.old_state;
printf ("CPSR is %p, PC is %p, etc.\n", atsh->cpsr, atsh->pc);
或者
B)将thread_get_state调用到线程端口(因为你在那里作为参数#2),并获得pc(指令指针)或任何其他寄存器
修改强>
我不确定如何使A)工作,但以下工作(found here)B)在32位iOS模拟器上。我不确定__faultvaddr
的arm寄存器等价物是什么,所以在尝试手臂之前你必须弄明白。
// types from thread_status.h
x86_exception_state32_t x86_exception_state32;
mach_msg_type_number_t sc = x86_EXCEPTION_STATE32_COUNT;
thread_get_state(thread,
x86_EXCEPTION_STATE32,
(thread_state_t)&x86_exception_state32,
&sc);