信号SIGBUS在没有内存访问的线路上

时间:2014-12-20 05:14:04

标签: android assembly android-ndk arm

我的Android应用在以下代码段的第4行报告了SIGBUS错误(这是一个功能序幕):

MOV R12, SP
STMFD SP!, {R4-R12,LR,PC}
SUB R11, R12, #4
SUB SP, SP, #0xA4         <- SIGBUS here
STR R0, [R11,#var_30]
MOV R2, #0
MOV R0, #0
STR R0, [R11,#var_70]
STR R0, [R11,#var_68]
STR R0, [R11,#var_60]
STR R0, [R11,#var_5C]

这甚至可能吗?

1 个答案:

答案 0 :(得分:1)

假设你没有做任何事情,比如试图直接调用mmap的硬件地址导致异步外部中止的乐趣,这让我最担心堆栈推送恰好两个指令(即the uncorrected PC offset)预先。如果你以某种方式对SP进行无意义的话,例如通过先前弹出一个损坏的堆栈帧,情况可能会展开:

  • SP中的无意义值不是4字节对齐的,因此架构不允许未对齐的加载/存储倍数,STM会导致对齐错误(对齐错误的优先级高于其他任何错误) MMU故障)。
  • 由于愚蠢的遗留原因 * 内核then tries to pretend没有对齐错误,所以使用多个“安全”访问来模拟它。
  • 内核然后在对齐处理程序中尝试访问无意义地址时发生MMU错误。此时,所有内容都会向“完全放弃”路径返回到用户空间 - 您获得原始对齐异常的SIGBUS,但没有正确的报告(因为修复程序从未完成),并且可能与'秘密'内核端页面错误。净结果:混乱。

要检查这个事件过程,首先尝试执行echo 5 > /proc/cpu/alignment(或程序化等效)以禁用修正并正确报告对齐错误 - 这确实应该是现代内核的默认设置,用于处理< em>大多数未对齐的访问,但遗憾的是,根据这种破坏,似乎仍有太多糟糕的软件。

*即网络层程序员过于依赖于未定义的行为,类型为punning,结构打包在x86上“有效”,而某些古老版本的ARM GCC显然很高兴生成未对齐的LDM / STM,即使对于有效代码< /子>