我的C程序在裸机Raspberry Pi 3B +上运行。除我得到CPU本身报告为“预取中止”的随机冻结外,它工作正常。设备可能会正常工作几个小时,然后突然崩溃。它在崩溃之前没有做任何特别的事情,因此这是不可预测的。
发生此错误时,FS寄存器(FSR)设置为0xD,这表明它是权限错误:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0087e/Cihhhged.html
其他寄存器:FAR为0xE80000B6,LR为0xFFFFFFFF,PC为0xE80000B6,PSR为0x200001F1
我的程序使用FIQ和IRQ中断,并使用所有四个CPU内核。
我在这里不要求进行特定的调试,因为它太复杂了,无法深入研究细节,但是您是否知道发生预取错误的常见原因?
答案 0 :(得分:3)
鉴于您的代码是多线程的(确实是多核的),并且崩溃是不可预测的,因此我想说,预取中止几乎肯定是由于种族导致的内存损坏引起的。
如果您可以找到在何处产生异常终止,可能会有所帮助。像这样的错误很难被发现。如果代码始终在同一位置崩溃,则可能会有所帮助,但是即使发生崩溃,您也可以找出哪个地址正在损坏,可以监视该地址是否存在恶意写操作,而又不影响程序的运行时间(并因此影响程序的显示)。错误)基本上是不可能的。
根本原因很可能是缓冲区溢出,特别是考虑到上面的评论。确实,您应该事先知道缓冲区需要多大,然后再将其设置为该大小。如果您使用的任何算法不能保证对使用的缓冲区数量有限制,则应添加对缓冲区执行运行时检查并适当响应的代码(也许报告的错误很好,所以您知道哪个缓冲区正在溢出) 。可以使用堆,但是如果将包含缓冲区的函数设为不可重入,则声明为static
的较大缓冲区会更快且无泄漏。
如果还存在数据访问争用问题,请注意,您将需要更多的数据障碍指示来解决这些问题。数据屏障指令仅解决与未决内存事务相关的一致性问题。它们不会阻止共享数据的寄存器缓存(您需要使用volatile
关键字)或同时进行读取-修改-写入竞争(您需要使用互斥机制),无论您使用的是哪种框架或使用armv7上的STREX
和LDREX
指令进行自制)。