如何找到EXC_BAD_ACCESS异常的地址?

时间:2013-10-18 05:46:49

标签: ios cpu-registers virtual-memory mach

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;
}

1 个答案:

答案 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);