37.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();
37.Linux驱动调试-根据oops的栈信息,确定函数调用过程的更多相关文章
- Linux驱动调试-根据oops的栈信息,确定函数调用过程
上章链接入口: http://www.cnblogs.com/lifexy/p/8006748.html 在上章里,我们分析了oops的PC值在哪个函数出错的,那如何通过栈信息来查看出错函数的整个调用 ...
- 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语言函数调用时,栈帧用来保存当前函数的父一级函数的栈底指针,当前函数的局部变量以及被调用函数返回后下一条汇编指令的地址.如下图所示: ...
随机推荐
- python操作excel及json
有一个存着学生成绩的文件:stuscore.txt,里面存的是json串,json串读起来特别不直观,需要你写代码把它都写到excel中,并计算出总分和平均分,json格式如下: { ":[ ...
- GridControl简单属性操作
1.单行记录整行选中 GridView->OptionsBehavior->EditorShowMode 设置为:Click 2.如何让行只能选择而不能编辑(或编辑某一单元格) 只读 Gr ...
- Easyui datagrid绑定数据,新增,修改,删除方法(一)
@{ ViewBag.Title = "UsersList"; } <script type="text/javascript"> $(functi ...
- 【CJOJ2616】 【HZOI 2016】偏序 I(cdq分治,树状数组)
传送门 CJOJ Solution 考虑这是一个四维偏序对吧. 直接cdq套在一起,然后这题有两种实现方法(树状数组的更快!) 代码实现1(cdq+cdq+cdq) /* mail: mleautom ...
- 实现域名访问网站—nginx反向代理
今天在跟项目的时候,是否被耍了三个多小时,最后在我准备号材料准备他人求助的时候,在收集材料的时候,居然访问通了, 别问我为什么,我也不知道 ,哈哈哈哈(苦逼脸...) 分享出来,大家共同学习: 这个是 ...
- lucene使用与优化
lucene使用与优化 1 lucene简介 1.1 什么是lucene Lucene是一个全文搜索框架,而不是应用产品.因此它并不像www.baidu.com 或者google Desktop那么拿 ...
- while循环中使用scanf函数
妈的,这scanf函数学了快10年了,怎么还会出现莫名其妙的问题?看下面的代码(VS2012环境下运行): #define _CRT_SECURE_NO_WARNINGS #include<st ...
- Shell - 简明Shell入门02 - 变量(Variable)
示例脚本及注释 #!/bin/bash v1=test-variable_123 # 全局变量 v2=12345 v3='This is a test!' # 赋值语句使用单引号或双引号可以包含空格 ...
- Angular使用总结 --- 模型驱动表单
模型驱动表单 之前有篇博文总结了 模版驱动表单 , 以及 模版驱动表单的自定义校验 , 本篇总结下模型驱动表单. 与模版驱动表单是不同的编程思路,偏向于数据模型.先在组件中建立表单控件的对象树,再绑定 ...
- MapReducer
MapReducer 概述 是一个分布式的计算框架(编程模型),最初由由谷歌的工程师开发,基于GFS的分布式计算框架.后来Cutting根据<Google Mapreduce ...