当前,我们正在寻找一种幻像,其形式是当我们编译某些代码(不调用它)时,对memset的一个特定调用会生成一个硬故障异常。
赋予memset的地址和长度有效。在单指令模式下单步执行它表明它总是在OR指令下失败。但是处理器不计算值,而是决定调用0xfffffff9,然后由于一条未知指令的原因而跳入hardfault处理程序。
发生memset的反汇编:
0x80192f0 <+0x0020> 03 2c cmp r4, #3
0x80192f2 <+0x0022> 2e d9 bls.n 0x8019352 <memset+130>
0x80192f4 <+0x0024> cd b2 uxtb r5, r1
# The following line crashes
0x80192f6 <+0x0026> 45 ea 05 25 orr.w r5, r5, r5, lsl #8
0x80192fa <+0x002a> 0f 2c cmp r4, #15
0x80192fc <+0x002c> 45 ea 05 45 orr.w r5, r5, r5, lsl #16
反汇编0xfffffff9:
0xfffffff7 00 00 movs r0, r0
0xfffffff9 00 00 movs r0, r0
0xfffffffb 00 00 movs r0, r0
我们在哪里可以找到此异常的来源?
我们在STM32F429II(即Cortex-M4)上运行该软件。
答案 0 :(得分:0)
请记住,对于Cortex-M,链接寄存器值指示如何从异常返回,而不是要返回的地址。相关地址将位于堆栈上(假设堆栈也不会失败)。
0xFFFFFFF1返回处理程序模式。
异常返回从主堆栈获取状态。
返回后,执行将使用MSP。
0xFFFFFFF9返回线程模式。
Exception从主堆栈返回获取状态。返回后,执行将使用MSP。
0xFFFFFFFD返回线程模式。
异常返回从进程堆栈获取状态。返回后,执行将使用PSP。
Cortex-M也永远无法从“本地外设”存储空间执行代码。
答案 1 :(得分:0)
@Rudi! 希望您已经解决了这个问题。 我刚刚遇到了同样的问题,并希望分享我的经验。
MCU从 orr.w 指令进入HardFault的事实并不意味着您的问题出在指令本身。 我使用HFSR寄存器(由@starblue提及)来查找发生变化的时刻。 如果您使用Eclipse-只需添加内存观察点或
(uint32_t)*((uint32_t *) 0xE000ED2C)
到表达式并找到值不等于零的行。
在我的情况下,这是空指针值分配的行。在跳到Hardfault处理程序之前,只有15条装配线。 在您的情况下,它甚至可能在其他线程中。