RISC-V instruction exception debugging example
Preface
This article uses a simple example to introduce
the debugging process of
RISC-V
instruction exceptions. The ideas are the same, and the analysis process is similar when encountering other situations.
For related content, please refer to "
riscv-privileged-20211203.pdf
"
process
The phenomenon is that the program enters an abnormal interrupt after execution
,
which can be seen through
the
bt
command
of
GDB
in exception () at src/lib/riscv/src/exception.c:55 12 0x02002e9c
#13 0x02002b40 in is_exception ()
Backtrace stopped: frame did not save the PC
(gdb)
Since it has entered an abnormal interrupt
,
it is necessary to confirm what the abnormality is.
This can be viewed via
the mcause
register
info reg mcause
mcause 0x2 0x2
(gdb)
You can see that it is an illegal instruction exception
Then we search the document for
Illegal instruction
to
see all possible reasons that may lead to
illegal instruction
.
We found the following information:
the mtval
register stores the abnormal instruction, and
mepc
points to the abnormal instruction.
You can see
that the content of
mepc
is
0
, so it is speculated that it is caused by the direct call of the function pointer without initialization.
info reg mtval
mtval 0x0 0x0
info reg mepc
mepc 0x0 0x0
(gdb)
At this point, the direction has basically been determined. You can focus on where there are function pointers, or gradually annotate functions, or gradually locate breakpoints.
It was quickly confirmed here.
The following code causes
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);
}
Check that the function pointer is exactly
0
(gdb) p xxx_drv.ops.ioctl
$1 = (int (*)(struct xxx_dev_s *, unsigned int, void *)) 0x0
(gdb)
The code traceback confirmed that a peripheral device was not initialized successfully, so the callback function was not initialized. The cause was located.
Summarize
For debugging exceptions, you can refer to the manual "
riscv-privileged-20211203.pdf
", start with the cause of the exception, gradually work backwards, confirm the exception trigger point and then determine the cause.