oops_根据epc定位linux_kernel_panic位置
韩大卫@吉林师范大学
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的程序就是第一个出现该成员的地方.
如果这个偏移太大, 很难计算的话, 不妨在代码里, 在调用该函数前自定义一个该参数类型的变量,
估计一个大概的成员, 计算他们的偏移, 在知道这个成员偏移量的基础上, 再计算120的成员位置. 会容易一些.
我的做法是:
struct mtd_info my = {0};
unsigned long len = (unsigned long)&(my.backing_dev_info) - (unsigned long)&my;
printk("sizeof is = 0x%lu\n", len);
当然, 这需要重启设备, 并load新编译的linux.
关于定位epc 位置, 总结一下:
1, 打开System.map, 找到epc之前的最近函数的地址.计算出epc距离该函数的偏移值.
2, 使用objdump 找到该函数, 分析 epc 偏移处的汇编代码.
3, 打开源代码, 根据分析汇编代码得到的信息进行定位.
oops_根据epc定位linux_kernel_panic位置的更多相关文章
- hp小机定位网卡位置
rad已经被olrad取代 HPUX下定位网卡位置 一台HP小型机,可能配了多块网卡,在系统中以la ...
- TextArea中定位光标位置
原文:TextArea中定位光标位置 在项目中,遇到一个场景:希望能在TextArea中输入某条记录中的明细(明细较简单,没有附属信息,只用记录顺序和值即可,譬如用"+"号来作为明 ...
- linux下编译make文件报错“/bin/bash^M: 坏的解释器,使用grep快速定位代码位置
一.linux下编译make文件报错“/bin/bash^M: 坏的解释器 参考文章:http://blog.csdn.net/liuqiyao_01/article/details/41542101 ...
- 利用.dSYM跟.app文件准确定位Crash位置
本文转载至 http://blog.csdn.net/lvxiangan/article/details/28102629 利用.dSYM和.app文件准确定位Crash位置首先,确保 ...
- springmvc请求参数异常统一处理,结合钉钉报告信息定位bug位置
参考之前一篇博客:springmvc请求参数异常统一处理 1.ExceptionHandlerController package com.oy.controller; import java.tex ...
- iOS开发----地图与导航--定位和位置信息获取
要实现地图.导航功能,往往需要先熟悉定位功能,在iOS中通过Core Location框架进行定位操作.Core Location自身可以单独使用,和地图开发框架MapKit完全是独立的,但是往往地图 ...
- scroll、scrollBy和 scrollTo三种方法定位滚动条位置
在默认情况下,页面加载完后默认滚动在最顶端,有些时候我们需要在页面打开后,定位滚动条的位置,比如,横向和纵向滚动条居中,实现页面滚动的方法有三种:scroll.scrollBy和 scrollTo,三 ...
- wireshark抓包获取好友ip,定位所在位置
1.打开wireshark 2.按Ctrl + F 键进行搜索 1,选择搜索 “字符串”; 2,选择搜索 “分组详情”; 3,填写搜索数据 “020048″; 3.对qq好友发起语言或视频通话(需要对 ...
- 线上CPU飚高(死循环,死锁……)?帮你迅速定位代码位置
top基本使用: top命令参考本篇文章 查看内存和CPU的top命令,别看输出一大堆,理解了其实很简单 top 命令运行图: 第一行:基本信息 第二行:任务信息 第三行:CPU使用情况 第四行:物理 ...
随机推荐
- Java中的资源文件加载方式
文件加载方式有两种: 使用文件系统自带的路径机制,一个应用程序只能有一个当前目录,但可以有Path变量来访问多个目录 使用ClassPath路径机制,类路径跟Path全局变量一样也是有多个值 在Jav ...
- 微软解决方案框架 - MSF的团队模型、MSF的开发模型,关于SA系统分析师信息的一篇好帖子
msf中的开发模型 书中关于六个小组的人员的案例: MSF 组队模型 v. 3.1-http://bbs.51cto.com/thread-1171-1.html 微软解决方案框架 - MSF的团队模 ...
- 百度UEditor富文本编辑器去除过滤div等标签
将设计排版好的页面html代码上传到数据库,再读取出来的时候发现所有的div都被替换成了p标签. 解决方法: 首先在ueditor.all.js文件内搜索allowDivTransToP,找到如下的代 ...
- JS打开新窗口防止被浏览器阻止的方法[转]
本文实例讲述了JS打开新窗口防止被浏览器阻止的方法.分享给大家供大家参考.具体分析如下: 用传统的window.open()方式打开新窗口,会被浏览器阻止,那么,我们如何才能让JS打开新窗口不被浏览器 ...
- 制作IOS 后台极光推送时,遇到的小问题
推送广义上分为两种, 一种是 程序在前台的时候,不想在任务栏里面显示通知,直接在app中进行某种操作.这个叫做自定义消息.这个是在前台时,app与极光后台建立了一个长链接. 另一种是 程序处于前. ...
- lsnrctl: error while loading shared libraries: /opt/app/oracle/product/11.2/db_1/lib/libclntsh.so.11
错误描述: 安装好数据库后,在oralce用户下敲入 查看监听状态命令,返回错误提示 [oracle@centos3 ~]$ lsnrctl statuslsnrctl: error while lo ...
- Android Fragment之间传递List数据
要说的是在两个Fragment之间传递List数据,比如有个List<User>,以及传递字符串数据,比如testId,该如何从FragmentA传递到FragmentB呢? 下面这个例子 ...
- 套接字I/O超时设置方法和用select实现超时
注:如无特殊说明,sockfd 原始状态都是阻塞的. 一.使用alarm 函数设置超时 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 void handler( ...
- 让thinkphp 支持ftp上传到远程,ftp删除
让thinkphp真正的支持FTP上传.删除. 原创by default7#zbphp.com,如需转载请保留作者信息. /** * This is not a free software, All ...
- 使用Xfire发布WebService接口遇到的问题:
问题一: log4j:WARN No appenders could be found for logger (org.codehaus.xfire.transport.DefaultTranspor ...