我正在开发自定义处理器的ARM Cortex-A5核心,从SW的角度来看,这个问题似乎无法解释。 问题是,在压力测试系统(重启数百次)的某个时刻,有时从某些SVC调用返回时会发生预取中止。调用实现如下:
用户模式代码:
;...Stuff
BL foo
;.. Stuff.
foo
PUSH {r4,lr}
SVC #0x1a
POP {r4,pc}
SVC处理程序:
SVC_Handler
PUSH {r0-r12,lr}
;... Do stuff
POP {r0-r12,lr}
SUBS pc,lr,#0
当中止发生时,LR_USR
指向BL foo
旁边的指令,但IFAR
的值为零以及r4
。因此LR_ABT
的值为0x4
,如果我们尝试分支到地址零,这是有意义的。鉴于这些观察,看起来POP {r4,pc}
指令从堆栈中取出两个零而不是正确的值,在堆栈中的正确位置,如调试器所观察到的那样在中止后(它们是SP_USR
之上的两个单词)。所以看起来要么在发生pop命令之后用正确的值更新堆栈,要么POP
指令只是错误的。
值得注意的是,代码和堆栈位于可缓存的内存中。用户模式和SVC模式具有不同的堆栈。
可以从SW的角度解释这种影响,还是可能是硬件错误(内存/缓存控制器?)。谁有人在他们的职业生涯中看到类似的东不幸的是,只能调试 post-mortem 。检测代码正在将错误转移到另一个调用(是的,它是Heisenbug ......)