Mips 平台报错:报错信息:CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 802bc
- MIPS架构内核查错
报错信息:
CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 802bc1f4, ra == 802bc110
[ 24.881634] Oops[#1]:
[ 24.883979] CPU: 0 PID: 127 Comm: figure Not tainted 3.10.14 #1
..................................
[ 25.021198] Call Trace:
[ 25.023720] [<802bc1f4>] jz_buffer_queue+0x128/0x178
[ 25.028840] [<802b59a0>] vb2_qbuf+0x1f8/0x254
[ 25.033334] [<802ba2fc>] soc_camera_qbuf+0x88/0xb4
[ 25.038278] [<802a8b28>] __video_do_ioctl+0x1d8/0x2dc
[ 25.043488] [<802a8ecc>] video_usercopy+0x2a0/0x3d8
[ 25.048526] [<802a2f9c>] v4l2_ioctl+0x94/0x164
[ 25.053114] [<800e26cc>] vfs_ioctl+0x2c/0x4c
...................................
关键文件:System.map vmlinux.o
1. 打开System.map
搜索epc地址,即802bc1f4,如若搜不到,将低位依次删除搜索,直到搜到你感觉是地址为止。笔者删除了三位,即802bc搜出想要值。然后对应函数如图1.1。
图1.1
2. 找到Call Trace 第一个地址
看到 Call Trace第一个地址为jz_buffer_queue的真实地址。即802bc1f4 - 802bc0cc=128,说明在0x128这个偏移位置出了问题
反汇编指令
mips-linux-gnu-objdump -dr vmlinux.o >> linux-dr
之后打开linux-dr 这个文件,找到 add_mtd_device 的定义处,如图1.2。
图 1.2
找到0x128偏移位置,看其对应行内容:
ae2302a4 sw v1,676(s1)
sw v1,676(s1)含义是 sw 把4个字节的数据存储到s1寄存器里的数值(该数值表示的是地址)偏移676个字节的位置。
ae2302a4 是sw v1,676(s1) 对应的机器码。
这句话可得知是将函数返回值存入寄存器这个操作发生错误,参考图1.3。应该是引用了空指针,试图执行0x00000000出的代码。
图 1.3
1、Unable to handle kernel paging request at virtual address 00000000
=====>> 越出内核地址空间范围,原因是由于使用空NULL指针
2、Unable to handle kernel paging request at virtual address 20100110
=====>> 越出内核地址空间范围,原因是的内存越界导致该指针
所在内存被破坏了。 接下来的困难是在什么地方这个内存被修改?为什么被修改?
3、Unable to handle kernel paging request at virtual address c074838c
=====>> 没有越出内核地址空间范围,为什么也oops?
这种情况我称之为:试图篡改受限制内存。比如:声明为const的变量!