Linux驱动调试-根据oops的栈信息,确定函数调用过程
上章链接入口: http://www.cnblogs.com/lifexy/p/8006748.html
在上章里,我们分析了oops的PC值在哪个函数出错的
本章便通过栈信息来分析函数调用过程
1.上章的oops栈信息如下图所示:
- 9fe0: 代表最初的栈顶SP寄存器位置
- 9e80:代表函数出错的SP寄存器位置
2.我们先来分析上图的栈信息,又是怎样的过程呢?
2.1内核主要是通过STMDB和LDMIA汇编命令来入栈和出栈
(STMDB和LDMIA汇编命令参考: http://www.cnblogs.com/lifexy/p/7363208.html)
内核每进入一个函数就会通过STMDB,将上个函数的内容值存入栈顶sp,然后栈顶sp-4.
当内核的某个函数出问题时,内核便通过LDMIA,将栈顶sp打印出来,然后栈顶sp+4,直到到达最初的栈顶
2.2我们以下图的3个函数为例:
若c()函数出问题后,内核就会打印b()函数的内容(0x03,LR), 打印a()函数的内容(0x02,LR),直到sp到达栈顶为止
其中lr值,便代表各个函数的调用关系
3.接下来我们便以上章的oops里的栈信息来分析
在上章里,我们找到PC值bf000078在26th_segmentfault驱动模块first_drv_open()函数下出错。
3.1先来看first_drv_open()函数,找到STMDB入栈的lr值,来确定被哪个函数调用的
如上图所示,first_drv_open()函数里,通过stmdb sp!, {r4, r5, fp, ip, lr, pc} 存入了6个值,
所以, 返回到上个函数的值lr =c008d888
在上章,我们便分析到:
内核的虚拟地址是c0004000~c03cebf4,所以c008d888位于内核的某个函数里
3.2 然后将内核进行反汇编
在内核源码的根目录下:
# arm-none-linux-gnueabi-objdump -D vmlinux > vmlinux.txt //-D:反汇编所有段 vmlinux:未压缩的内核
3.3 打开vmlinux.txt
如下图所示,搜索c008d888:
往上翻,找到c008d888位于函数chrdev_open()下:
如上图所示, chrdev_open()函数存了10个值,所以,返回到上个函数的值lr= c0089e48
3.4 继续搜索c0089e48:
往上翻,找到c0089e48位于函数__dentry_open ()下:
如上图所示, __dentry_open()函数存了10个值,所以,第二个值lr= c0089f64
3.5 继续搜索c0089f64:
往上翻,找到c0089f64位于函数nameidata_to_filp()下:
如上图所示, nameidata_to_filp函数存了6个值,所以,第二个值lr= c0089fb8
... ...(此处省略n字)
4.最终分析出,栈信息的调用过程如下:
- ret_fast_syscall()->
- sys_open()->
- do_sys_open()->
- do_filp_open()->
- nameidata_to_filp()->
- chrdev_open()->
- first_drv_open();
Linux驱动调试-根据oops的栈信息,确定函数调用过程的更多相关文章
- 37.Linux驱动调试-根据oops的栈信息,确定函数调用过程
上章链接入口: http://www.cnblogs.com/lifexy/p/8006748.html 在上章里,我们分析了oops的PC值在哪个函数出错的 本章便通过栈信息来分析函数调用过程 1. ...
- 36.Linux驱动调试-根据oops定位错误代码行
1.当驱动有误时,比如,访问的内存地址是非法的,便会打印一大串的oops出来 1.1以LED驱动为例 将open()函数里的ioremap()屏蔽掉,直接使用物理地址的GPIOF,如下图所示: 1.2 ...
- linux驱动调试--段错误之oops信息分析
linux驱动调试--段错误之oops信息分析 http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29401328&id= ...
- 驱动调试-根据oops定位错误代码行
1.当驱动有误时,比如,访问的内存地址是非法的,便会打印一大串的oops出来 1.1以LED驱动为例 将open()函数里的ioremap()屏蔽掉,直接使用物理地址的GPIOF,如下图所示: 1.2 ...
- 驱动调试(四)oops确定调用树
目录 驱动调试(四)oops确定调用树 内核开启调用树 栈指针分析 原理 寄存器别名 基础解释 例子分析 找到PC地址的位置 栈分析 附录:原文的excel title: 驱动调试(四)oops确定调 ...
- 驱动调试(三)oops确定函数PC
目录 驱动调试(三)oops确定函数PC 什么是oops 流程简述 代码仓库 模块例子分析 找到PC值 判断是否属于模块 查看符号表 找到模块 反汇编模块 内核例子分析 找到PC值 判断是否属于模块 ...
- linux驱动调试记录
linux驱动调试 linux 目录 /proc 下面可以配置驱动的调试信息,比如给proc目录的自己定制的驱动的一文件设置一个变量,然后驱动程序跟了proc的参数值来配置调试级别.类似于内核调试的级 ...
- linux驱动调试--修改系统时钟终端来定位僵死问题【转】
本文转载自:http://blog.chinaunix.net/uid-20671208-id-4940381.html 原文地址:linux驱动调试--修改系统时钟终端来定位僵死问题 作者:枫露清愁 ...
- Linux内核调试方法总结之栈帧
栈帧 栈帧和指针可以说是C语言的精髓.栈帧是一种特殊的数据结构,在C语言函数调用时,栈帧用来保存当前函数的父一级函数的栈底指针,当前函数的局部变量以及被调用函数返回后下一条汇编指令的地址.如下图所示: ...
随机推荐
- java设计模式-工厂模式(springweb为例子)
一般而言,工厂模式分为3种,简单工厂模式,工厂方法模式,抽象工厂模式.这三种工厂模式逐层深入吧. 一,从springWeb.jar包使用抽象工厂模式的一个例子聊起 之前对spring各种痴迷,所以在需 ...
- Appium python自动化测试系列之自动化截图(十一)
11.1 截图函数的正常使用 11.1.1 截图方法 无论是在手动测试还是自动化测试中场景复现永远是一个很重要的事情,有时候一些问题可能很难复现,这个都需要测试人员对bug有很高的敏感度,在一般的情况 ...
- express紧急回顾随笔
四行代码搭建服务器 var express = require('express'); var app = express(); //设定静态路径 所有请求优先在此路径查找 //不要把服务器配置JS文 ...
- MySQL冗余和重复索引
MySQL允许在相同列上创建多个索引,无论是有意还是无意,mysql需要单独维护重复的索引,并且优化器在优化查询的时候也需要逐个地进行考虑,这会影响性能. 重复索引是指的在相同的列上按照相同的顺序创建 ...
- Windows环境下多线程编程原理与应用读书笔记(7)————事件及其应用
<一>事件 事件主要用于线程间传递消息,通过事件来控制一个线程是处于执行状态还是处于挂起状态. 事件和互斥量之间的差别: 事件主要用于协调两个或者多个线程之间的动作,使其协调一致,符合逻辑 ...
- [MYSQL] 记一次MySQL性能调优
最近在做数据迁移工作,已有一堆数据文件,要把这些数据文件写到MySQL 数据库里面去. MySQL数据库上架了一层服务接口,可以直接调用.博主写了一个迁移程序,放在服务器A上. *********** ...
- ab使用命令
ab使用-A auth-username:password 向服务器提供基本认证信息.用户名和密码之间":"分割,以base64编码形式发送.无论服务器是否需要(即是否发送了 ...
- centos7.2构建Python3.5开发环境
1.本次使用的是一台全新的腾讯云主机,首先获取linux系统版本信息. [root@VM_46_121_centos ~]# cat /etc/redhat-release <本系统默认自带py ...
- Entity Framework 调用返回标量值的存储过程
最近项目用到EF,虽然说EF与Linq To SQL有很多地方相似,但是EF(这里指3.5版,4.0版的还没去留意)确实有些地方做得不够方便. 就拿存储过程来说吧,EF里面想调用存储过程不是直接在数据 ...
- Dubbo源码学习--环境搭建及基础准备(ServiceLoader、ExtensionLoader)
环境搭建 Github上下载Dubbo最新发布版本,楼主下载版本为2.5.7. cd到源码解压目录,maven编译,命令为: mvn clean install -Dmaven.test.skip 生 ...