【问题标题】:Signal SIGBUS on a line with no memory access在没有内存访问的线路上发出信号 SIGBUS
【发布时间】:2014-12-20 05:14:04
【问题描述】:

我的 Android 应用在以下 sn-p 的第 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]

这可能吗?

【问题讨论】:

  • 鉴于它已经发生,这是完全有可能的 ;) 有很多原因您可能会在一个无意义的地址上收到一个错误 reported,还有几个原因是在一个错误的地址上看似无害的指令的地址,但没有任何上下文很难说。周围的代码是什么样的?涉及的具体地址是什么?它在什么处理器上运行?
  • 好吧,也许它被误报了(如何?)或者我的构建档案被破坏了,我正在查看错误的 SO 文件。

标签: android assembly android-ndk arm


【解决方案1】:

假设您没有做任何事情,例如尝试直接戳 mmap 的硬件地址导致异步外部中止的乐趣,这让我最怀疑堆栈推送恰好两个指令(即 the uncorrected PC offset)。如果您不知何故对 SP 产生了误解,例如通过先前弹出损坏的堆栈帧,情况可能会这样展开:

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

要检查这一系列事件,请先尝试执行echo 5 &gt; /proc/cpu/alignment(或程序等效项)以禁用修复并正确报告对齐错误 - 这确实应该是现代内核上处理的硬件的默认设置大多数未对齐的访问,但遗憾的是,由于这种损坏,似乎仍然有太多糟糕的软件。

* 即网络层程序员过于依赖类型双关语和在 x86 上“工作”的结构打包的未定义行为,以及某些古老版本的 ARM GCC,即使对于有效代码,它们显然也会愉快地生成未对齐的 LDM/STM

【讨论】:

    猜你喜欢
    • 2010-12-03
    • 2016-12-22
    • 2020-06-16
    • 2017-09-19
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    相关资源
    最近更新 更多