上章链接入口: 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的栈信息,确定函数调用过程的更多相关文章

  1. Linux驱动调试-根据oops的栈信息,确定函数调用过程

    上章链接入口: http://www.cnblogs.com/lifexy/p/8006748.html 在上章里,我们分析了oops的PC值在哪个函数出错的,那如何通过栈信息来查看出错函数的整个调用 ...

  2. 36.Linux驱动调试-根据oops定位错误代码行

    1.当驱动有误时,比如,访问的内存地址是非法的,便会打印一大串的oops出来 1.1以LED驱动为例 将open()函数里的ioremap()屏蔽掉,直接使用物理地址的GPIOF,如下图所示: 1.2 ...

  3. linux驱动调试--段错误之oops信息分析

    linux驱动调试--段错误之oops信息分析 http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29401328&id= ...

  4. 驱动调试-根据oops定位错误代码行

    1.当驱动有误时,比如,访问的内存地址是非法的,便会打印一大串的oops出来 1.1以LED驱动为例 将open()函数里的ioremap()屏蔽掉,直接使用物理地址的GPIOF,如下图所示: 1.2 ...

  5. 驱动调试(四)oops确定调用树

    目录 驱动调试(四)oops确定调用树 内核开启调用树 栈指针分析 原理 寄存器别名 基础解释 例子分析 找到PC地址的位置 栈分析 附录:原文的excel title: 驱动调试(四)oops确定调 ...

  6. 驱动调试(三)oops确定函数PC

    目录 驱动调试(三)oops确定函数PC 什么是oops 流程简述 代码仓库 模块例子分析 找到PC值 判断是否属于模块 查看符号表 找到模块 反汇编模块 内核例子分析 找到PC值 判断是否属于模块 ...

  7. linux驱动调试记录

    linux驱动调试 linux 目录 /proc 下面可以配置驱动的调试信息,比如给proc目录的自己定制的驱动的一文件设置一个变量,然后驱动程序跟了proc的参数值来配置调试级别.类似于内核调试的级 ...

  8. linux驱动调试--修改系统时钟终端来定位僵死问题【转】

    本文转载自:http://blog.chinaunix.net/uid-20671208-id-4940381.html 原文地址:linux驱动调试--修改系统时钟终端来定位僵死问题 作者:枫露清愁 ...

  9. Linux内核调试方法总结之栈帧

    栈帧 栈帧和指针可以说是C语言的精髓.栈帧是一种特殊的数据结构,在C语言函数调用时,栈帧用来保存当前函数的父一级函数的栈底指针,当前函数的局部变量以及被调用函数返回后下一条汇编指令的地址.如下图所示: ...

随机推荐

  1. ASP.NET MVC的切片(Section)脚本(script)

    在ASP.NET MVC使用切片脚本,实在是很溜. 在使用layout之后,只是视图套用_Layout之后,在视图中任一位置任一时候均可以使用切片脚本. 首先在_Layout.cshtml定一些规则: ...

  2. 文本框仅可接收decimal

    文本框html如下: <div><label class="label">价格:</label><input id="TextP ...

  3. js 将一个数组插入到另一个数组的方法

    JavaScript将一个数组插入到另一个数组的方法.分享给大家供大家参考.具体分析如下: 1.通过Array.prototype.push.apply方法将一个数组插入到另外一个数组,下面的代码将数 ...

  4. 2018 Multi-University Training Contest 5

    (叹气.jpg) B.Beautiful Now 题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6351 题意:给一串长度为m的数字,k次任意交换其中 ...

  5. C#6.0语言规范(十三) 接口

    接口定义合同.实现接口的类或结构必须遵守其合同.接口可以从多个基接口继承,并且类或结构可以实现多个接口. 接口可以包含方法,属性,事件和索引器.接口本身不为它定义的成员提供实现.接口仅指定必须由实现接 ...

  6. java分模块项目在idea中使用maven打包失败(ps:maven常用到的命令)

    一.分模块项目打包失败 情况:项目是分模块创建的,一些公共的方法是单独的一个模块common,其他模块依赖于此模块,poom依赖已经添加了,项目可以正常运行,但使用maven打包时出现了问题:找不到依 ...

  7. iOS开发-自动隐藏键盘及状态栏

    1.隐藏状态栏 iOS升级至7.0以后,很多API被废止,其中原有隐藏状态栏StatusBar的方法就失效了. 原有方案 [[UIApplication sharedApplication] setS ...

  8. mongodb postgresql mysql jsonb对比

    mongodb pg mysql jsonb对比 http://erthalion.info/2017/12/21/advanced-json-benchmarks/ 使用禁用jsonb列的压缩 AL ...

  9. POJ 2572

    #include<stdio.h> #include<iostream> #include<string> using namespace std; int mai ...

  10. Spring WebSocket踩坑指南

    Spring WebSocket踩坑指南 本次公司项目中需要在后台与安卓App间建立一个长连接,这里采用了Spring的WebSocket,协议为Stomp. 关于Stomp协议这里就不多介绍了,网上 ...