【发布时间】:2014-10-26 00:12:19
【问题描述】:
这是在 armv7 上崩溃的 c 源代码行:
ret = fnPtr (param1, param2);
在调试器中,fnPtr 的地址为 0x04216c00。当我在指向上述语句的电脑上反汇编时,这是我得到的:
0x18918e: movw r0, #0x73c
0x189192: movt r0, #0x1
0x189196: add r0, r2
0x189198: ldr r0, [r0]
0x18919a: str r0, [sp, #0x20]
0x18919c: ldr r0, [sp, #0x20]
0x18919e: ldr r1, [sp, #0x28]
0x1891a0: ldr r2, [sp, #0x2c]
0x1891a2: str r0, [sp, #0x14]
0x1891a4: mov r0, r1
0x1891a6: mov r1, r2
0x1891a8: ldr r2, [sp, #0x14]
0x1891aa: blx r2
现在,当我反汇编地址 $r2 (=0x4216c00) 处的内存时,我得到了看似有效的代码,应该毫无问题地执行:
(lldb) disassemble -s 0x4216c00 -C 10
0x4216c00: push {r4, r5, r6, r7, lr}
0x4216c04: add r7, sp, #0xc
0x4216c08: push {r8, r10, r11}
0x4216c0c: vpush {d8, d9, d10, d11, d12, d13, d14, d15}
0x4216c10: sub r7, r7, #0x280
0x4216c14: mov r6, r0
0x4216c18: bx r1
0x4216c1c: add r7, r7, #0x280
然而真正发生的是:
EXC_BAD_ACCESS(代码=2,地址=0x4216c00)
谁能解释什么是错的以及为什么该地址被认为是非法的?
完全披露:我不是装配专家。编译和链接的代码都是 c 代码。编译器很响。
【问题讨论】:
-
堆栈是什么样的?快速浏览一下就会发现,由于不可能的大分配或失控的递归而耗尽堆栈可能会在看似无辜的代码中出现此错误。
-
@Notlikethat:好的;这听起来很合理。我怎样才能弄清楚这个?什么构成“快速浏览”。 '非常感谢!
-
@Notlikethat:所以,我想我会增加应用程序的内存分区,直到收到您的回复。 (≈快速检查我是否遇到了我看不到的低内存问题)。我仍然因同样的异常而崩溃。
-
尝试在 C 中重现问题并分享它可能会很好。如果它是堆栈损坏,它可能在您被咬之前的其他地方。你在用函数指针和可变参数等做一些花哨的事情吗?