RISC-V的Store AMO access fault调试实例
前言
本文以一个实例分享 RISC-V 的 Store AMO access fault 异常的调试过程。 Store AMO access fault 主要发生在非法地址访问时 ( 栈溢出 , 指针异常等 ) 。
过程
现象是程序运行时进入了异常中断, 如 下
使用 bt 回溯可以看到进入了异常处理函数 exception ()
(gdb) bt
......
#6 0x02002eb2 in exception () at src/lib/riscv/src/exception.c:55
#7 0x00000000 in ?? ()
Backtrace stopped: frame did not save the PC
(gdb)
那么首先想到的是确认异常原因
查看异常寄存器:info reg mcause
可以看到异常原因是
0x07
对应的是
Store/AMO access fault
异常
,
这是一个写数据时的异常.
那么接下来就要确认写哪个地方的数据错误了呢
?
我们可以通过
info reg mtval
查看
mtval
寄存器看到。
写
0x28382ad0
时产生了异常.
那么什么时候写这个地址导致了异常呢,之前
bt
已经看不到回溯的地方了。
我们可以使用数据断点来监控
设置数据断点
watch *(unsigned int*)0x28382ad0
重新加载程序运行
load
c
运行
看到断点停在了
memset
函数处,这印证了我们前面分析的是写数据导致的问题
继续
bt
查看
我们找到对应的代码处
看下
memset
的参数,如果看不到可以在
memset
前打断点重新运行
最终确认确实是栈初始化时写
0x28382ad0
这个地址的内容错误,原因是不具备写属性导致异常
(gdb) p pxStack
$8 = (StackType_t *) 0x28382ad0
(gdb)
当然为什么这个地址不能写和这里没关系了,是另外一回事了, 是我们的环境 DDR 的问题。
总结
以上是一个分析实例的过程
,
遇到类似问题可以参考。有几个关键点一是确认异常原因
,
异常访问的地址
,
然后通过数据断点确认什么时候访问了这个地址,到此基本就确认问题了,后面就顺藤摸瓜了。