1、异常表现
图1 debug
图2 pctrace view
图3 control-registers
图4 disassembly
图5 main-registers
2、分析
(1)epsr 0x80010151
分析知:未对齐访问异常
(2)epc 0x8003b8de
和 图4 disassembly
和 图2 pctrace view
分析知:
在0x8003b8de 处,st r3,(r7 + 4):发现 (r7 + 4)表示的存储地址是错误的,不可能是0x57207265。
(3)
猜测0x8003b8de 这行代码的意思
121 (new_node -> cs_previous) -> cs_next = new_node;
0x8003b8de st r3,(r7 + 4):
将寄存器r3的值,放到(r7 + 4) 地址上。
那么: r3 表示new_node;
r7 表示(new_node -> cs_previous)
+4表示-> cs_next
分析知:
(new_node -> cs_previous)地址错误。
(4)
图 6 fun
(new_node -> cs_previous) 源自(*head) -> cs_previous;
那么,就是(*head) -> cs_previous的地址错误。
(4)
图7 fun1
图8 expressions
(*head)就是SMD_Created_Semaphores_List,SMD_Created_Semaphores_List的地址是0x8006f034。
0x8006f034这个地址上保存的值是:0x57207265
图9 0x8006f034 hex.png
SMD_Created_Semaphores_List的地址是0x8006f034。
0x8006f034这个地址上保存的值是:0x57207265
发现这个值0x57207265和r7的值一模一样。
0x57207265就是(*head) -> cs_previous;
即指针cs_previous的值是0x57207265;
那么向指针cs_previous保存数据,一定会发生未对齐错误。
因为地址0x57207265不是正确的内存地址。
(5)
无意中将hex显示,改为ascill显示,发现:
图10 0x8006f034 string.png
这个竟然是字符串。
然后,查看字符串位置,即地址。
图11 expression.png
发现dataArray_2全局数组的长度为256,但是使用memcpy向其拷贝了310个字节,超出了buffer的界限。
(6)
将dataArray_2全局数组长度变得足够大,发现异常解决,在异常处跟踪,也没有出现问题。
(7)
思考:
拷贝时数组越界,难查。写拷贝动作代码时,需谨慎。
dataArray_2全局数组只是在前边使用了一次,就不再使用了。但是后边的代码还是出错了。
说明后边的代码要求必须要初始化,就是因为dataArray_2全局数组越界,将初始化破坏了,造成了错误。