前言
本文以一個簡單的實例介紹RISC-V指令異常的調試過程,思路都是一樣的,遇到其他情況時分析過程也類似。
相關內容參考《riscv-privileged-20211203.pdf》
過程
現(xiàn)象是程序執(zhí)行后進入了異常中斷,可以通過GDB的bt命令看到
#12 0x02002e9c in exception () at src/lib/riscv/src/exception.c:55
#13 0x02002b40 in is_exception ()
Backtrace stopped: frame did not save the PC
(gdb)
既然是進入了異常中斷,那么就需要確認到底是什么異常,
這可以通過mcause寄存器查看
(gdb) info reg mcause
mcause 0x2 0x2
(gdb)
可以看到是非法指令異常
那么我們就搜索文檔的Illegal instruction可以查看到所有可能導致Illegal instruction的原因。
我們搜到以下信息,即mtval寄存器保存了異常指令,mepc指向了異常指令
可以看到mepc的內容是0,那么猜測應該是函數(shù)指針未初始化直接調用導致的
(gdb) info reg mtval
mtval 0x0 0x0
(gdb) info reg mepc
mepc 0x0 0x0
(gdb)
到這里基本就確認了方向了,可以重點看哪些地方有函數(shù)指針,或者逐步注釋函數(shù),或者逐步斷點定位即可。
這里很快就確認了是
是如下代碼導致
int xxx_ioctl(unsigned int dev_id, unsigned int cmd, void *data)
{
if (dev_id >= xxx_drv.dev_num)
return -1;
return xxx_drv.ops.ioctl(&(xxx_drv.dev[dev_id]), cmd, data);
}
查看函數(shù)指針正好是0
(gdb) p xxx_drv.ops.ioctl
$1 = (int (*)(struct xxx_dev_s *, unsigned int, void *)) 0x0
(gdb)
回溯代碼確認了是某個外設沒有初始化成功則這個回調函數(shù)沒有初始化。原因就定位了。
總結
對于異常的調試可以參考手冊《riscv-privileged-20211203.pdf》,從異常原因入手,逐漸反推,確認異常觸發(fā)點然后確定原因。
審核編輯:湯梓紅
-
指令
+關注
關注
1文章
617瀏覽量
37147 -
調試
+關注
關注
7文章
618瀏覽量
35203 -
命令
+關注
關注
5文章
745瀏覽量
23280 -
RISC-V
+關注
關注
47文章
2694瀏覽量
50787
發(fā)布評論請先 登錄
正式的RISC-V基礎指令集架構與特權架構規(guī)范來了,RISC-V基金會已正式批準
RISC-V的Store AMO access fault調試實例

評論