linux 内核 报错,根据epc定位linux内核报错.pdf

根据epc定位linux内核报错.pdf

韩⼤卫@吉林师范⼤学

2014.12.10

转载请表明出处

*****************************************************

关于内核报错 “Unable to handle kernel paging request at virtual address” 的问题, 绝⼤多数都是

由于程序使⽤了不可⽤的指针⽽引起的, 定位这类问题的办法很简单,也希望我的描述⾜够简单实⽤.

以我下⾯的⼀个实例说明:

epc :exception program counter , 异常程序计数器, ra : return address 返回地址

我们可以根据 “CPU 0 Unable to handle kernel paging request at virtual address

0000000000000078, epc == ffffffff805e96e8, ra == ffffffff80ec73d0” 找到epc的具体位置, 再根据具

体的汇编程序定位出引起epc的具体原因, 另外, 如有必须知道全部的调⽤路径. 那么重复定位epc的

⽅法,根据call trace 逐步定位即可.

在编译linux 的时候, 会产⽣⼀个System.map , vmlinux, 以及vmlinux.o

我们使⽤System.map 和vmlinux.o 即可. 因为vmlinux可能是被特定压缩⼯具压缩过的(根据您的

makefile), ⽆法使⽤objdump⼯具做反汇编.

先打开System.map:

将 epc == ffffffff805e96e8 ⾥的 ffffffff805e96e8 地址拷⻉下来, 直接在System.map ⾥⾯查找, 如果没

有找到, 那么将ffffffff805e96e8 最后两位删掉, 即ffffffff805e96, 查找这个地址, 绝⼤多数情况都可以找

到, 我的如下:

看起来, 问题是出在 add_mtd_device 这个函数⾥⾯.

epc 的位置是在ffffffff805e96e8, add_mtd_device 的地址是在ffffffff805e96c0 , 那么应该是在

add_mtd_device⾥的ffffffff805e96e8 - ffffffff805e96c0 = 0x28 这个偏移位置出了问题.

现在我们需要观察 vmlinux.o 的汇编代码, 找到 add_mtd_device 函数的汇编, 观察 0x28 位置的汇编

语⾔.

先使⽤xxx-objdump(xxx 为具体的交叉编译⼯具前缀) 将vmlinux.o 反汇编出来, 我的做法是:

mips64-octeon-linux-gnu-objdump -dr vmlinux.o >> linux-dr

之后打开linux-dr 这个⽂件, 找到 add_mtd_device 的定义处:

可以看到, 0x28 位置的汇编:

28: dc820078 ld v0,120(a0)

ld v0, 120(a0) 的含义是:

先取寄存器a0的数值的地址, 再将该地址后120字节处的数值加载到v0 寄存器.

(a0)是取a0寄存器的地址, a0是负责传递函数的第⼀个参数的寄存器.

dc820078 就是ld v0, 120(a0) 对应的机器码.

根据CPU 0 Unable to handle kernel paging request at virtual address 0000000000000078 这句话

的提⽰可以知道, 是在对a0的0x78(120) 地址取值的时候发⽣了错误, 很可能是a0地址本⾝不可⽤.

如果能确认的话, 就可以证明add_mtd_device的第⼀个参数使⽤⼀个不可⽤的指针.

这时候就可以检查源代码, 相信您有能⼒很快到定位问题.

但如果该函数很⼤, 不容易定位, 那么我们可以通过120这个信息定位到该函数⾥具体的语句.

我的实例:

打开linux内核源代码, 计算120字节在add_mtd_device() 第⼀个参数类型⾥的位置, 得到参数成员:

vi -t add_mtd_device

如下图:

找到第⼀个参数的类型struct mtd_info 定义, 通过逐步计算每个成员偏移(注意填充字节), 可以算出

第120字节的成员为backing_dev_info. 那么, 在代码⾥, 出现epc的程序就是第⼀个出现该成员的地

⽅.

如果这个偏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值