linux驱动调试--段错误之栈信息分析

2023-11-13

转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29401328&id=4923529
接着上一篇来分析一下Oops的栈

s3c2440平台

关于调试源码和整个Oops信息请参考上一篇博文,这里只再次贴出关于栈的信息

Stack: (0xc3a61e30 to 0xc3a62000)
1e20: c3a61e64 c3a61e40 c00a8580 bf0d7010
1e40: c00adba8 00000000 00000000 c3b46100 c3ab84b0 c00a84b4 c3a61e8c c3a61e68
1e60: c00a3a7c c00a84c4 c3b46100 c2c0ae40 00000003 c3af0000 00000026 c3a61ed8
1e80: c3a61eac c3a61e90 c00a3d14 c00a39bc 00000000 c2c0ae40 00000000 00000000
1ea0: c3a61f64 c3a61eb0 c00b0c80 c00a3cc0 c3a61f7c c3a61ec0 c004b714 c006f8b8
1ec0: c3a61efc beb5ad9c 00000000 00000000 c3a63000 c048070c c394bc80 c34b7600
1ee0: c048077c c3a61fb0 00000000 00000101 00000001 00000000 c00441e0 c004b548
1f00: 08100875 c39568a0 c3a7ec00 0000001c 00000000 00001000 00000003 00000003
1f20: 00000000 c3b46100 00000000 c3a60000 c3a61f64 c3a61f40 c00b99b8 00000003
1f40: c3af0000 00000002 beb5ad9c ffffff9c c3a60000 00000000 c3a61f94 c3a61f68
1f60: c00a38d8 c00b0aa0 00000000 40025000 c3a61f9c 0000850c 00000000 000083e0
1f80: 00000005 c0045008 c3a61fa4 c3a61f98 c00a3988 c00a3878 00000000 c3a61fa8
1fa0: c0044e60 c00a3974 0000850c 00000000 00008590 00000002 beb5ad9c 00000001
1fc0: 0000850c 00000000 000083e0 00000005 00000000 00000000 40025000 beb5ac44
1fe0: 00000000 beb5ac28 000084b8 400efd9c 60000010 00008590 00000000 00000000

那么这一堆栈指示的是什么信息?
指示的是函数的回溯信息,我们在上一节看到了函数的回溯信息,就是函数的调用关系,栈信息不仅包含了回溯信息,
还包含了各个函数相关的寄存器,当函数切换时,会把相关的寄存器保存在自己的堆栈中,出错时,会层层打印出来。
这样会有助于我们调试,因为在内核函数中,很多数据不是在当前函数中确定的,而是由上一个函数传过来的,所以
有必要知道这么一种调用关系

下面说一下这种调用关系:

A()
{
……
B();
……
}

B()
{
……
C();
……
}

C()
{
……
}

在上面的函数调用关系中,A函数会调用B函数,B函数会调用C函数,C函数执行完之后会返回B函数,B函数执行完之后返回A函数。
那么为什么能够返回去呢?
肯定是每次发生调用切换函数时,在自己的栈中保存了一个寄存器,在函数执行完后,根据这个寄存器能够返回到调用这个函数的
代码中,这个寄存器就是lr寄存器。

每个函数都有自己的堆栈区来保存相关的寄存器,通过sp寄存器找到这个地址。如下图所示:

假如在上面的调用中,C函数出错了,会打印出相关的堆栈信息供我们分析。按什么顺序打印呢?
先打印C函数堆栈中的寄存器,在根据C堆栈中的lr寄存器找出调用它的函数,这里是B函数,然后打印出B函数
堆栈中的寄存器,同样根据B的lr寄存器找到A函数并打印,就是这样一层一层往上推的。

现在来分析栈的打印信息

首先我们知道错误处在了segment_test_open函数中,来看一下这个函数的汇编代码,确定一下它的堆栈中存了那些
寄存器
00000000 :
0: e1a0c00d mov ip, sp
4: e92dd800 push {fp, ip, lr, pc}
看到这里,由第二行知道它的堆栈中存了四个寄存器,出错时会把这个函数堆栈中这四个寄存器打印出来,就是我们看到的
前四个栈的前四个数据:
c3a61e64 c3a61e40 c00a8580 bf0d7010

这里栈地址是向上增长的,即最低地址存的是fp寄存器,fp = c3a61e64,pc = bf0d7010。如下图所示

我们根据lr寄存器来找调用它的函数,这里 lr = c00a8580,怎么根据这个地址去查找是在哪个函数呢?
首先反汇编内核(arm-none-linux-gnueabi-objdump -D vmlinux > vmlinux.dis),然后在内核的汇编代码中查找这个地址。

找到这个地址之后,向上翻看,可以看到这个地址是在 c00a84b4 :里面,也就是chrdev_open函数,就是说下一个
要打印的堆栈信息将是这个函数的。看一下这个函数的堆栈大小及寄存器

c00a84b8: e92dd8f0 push {r4, r5, r6, r7, fp, ip, lr, pc}
……
c00a84c0: e24dd008 sub sp, sp, #8 ; 0x8

这里看出chrdev_open函数的堆栈大小是 40字节,会打印出十个寄存器值(每个寄存器占4字节),lr寄存器是倒数第二个,
接下来的十个寄存器是:
c00adba8 00000000 00000000 c3b46100 c3ab84b0 c00a84b4 c3a61e8c c3a61e68 c00a3a7c c00a84c4

可以看出 lr = c00a3a7c

再去查找这个地址,知道是在 __dentry_open函数中,这个函数的反汇编:
c00a39b0: e92dddf0 push {r4, r5, r6, r7, r8, sl, fp, ip, lr, pc}

同样是十个寄存器,接下来是:
c3b46100 c2c0ae40 00000003 c3af0000 00000026 c3a61ed8 c3a61eac c3a61e90 c00a3d14 c00a39bc

lr = c00a3d14,这个地址在nameidata_to_filp函数中,然后再根据它的堆栈信息,层层网上查找,
最后会根据c0044e60地址到ret_fast_syscall 函数,再之后的地址
0000850c 00000000 00008590 …………
已经不是内核函数了,这个函数就是发生在内核调用中的最上层函数。

谁调用ret_fast_syscall函数的?
根据我们之前对系统调用的分析知道,当发生系统调用open时,会产生swi异常,陷入到内核,这个函数就是陷入内核时
首先执行的函数,然后层层调用找到我们要调用的segment_test_open函数,通过这个分析我们也可以看到系统调用open的
调用过程。

这篇博文用到了寄存器的知识,有时间再介绍

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux驱动调试--段错误之栈信息分析 的相关文章

  • Java中的内存分配

    Java把内存划分成两种 一种是栈内存 一种是堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配 当在一段代码块定义一个变量时 Java就在栈中为这个变量分配内存空间 当超过变量的作用域后 Java会自动释放掉为
  • 两个栈实现一个队列(图解),一看就懂

    两个栈实现一个队列 要想实现此方法 我们现需要了解一下什么是栈和队列 栈 栈 Stack是一种只能在一端进行插入或删除操作的线性表 表中允许进行插入 删除操作的一端称为栈顶 Top 栈顶的当前位置是动态的 栈顶的当前位置是由一个称为栈顶指针
  • Stanford CS143 速通PA1教程

    今天做完了CS143的PA1 感觉最难的地方在于官方没有具体的文档 edX 然后COOL语言调试比较困难 以下是我对同样打算入坑CS143的同学的一些帮助吧 速通前的准备 Virtual VM Setup 如果还没有搭好环境的 建议跟着官网
  • 09黑马笔记之栈的应用_中缀表达式转后缀表达式

    09黑马笔记之栈的应用 中缀表达式转后缀表达式 1 前提 1 数字 直接输出 2 左括号 直接进栈 优先级默认最低 3 右括号 将栈顶符号输出 直到匹配到左括号 4 运算符 1 若一开始没有可比较直接进栈 2 若栈顶元素优先级低 进栈 3
  • c++栈实现表达式求值

    文章目录 前言 一 思想分析 二 具体实现 前言 后缀表达式的算法思想与具体实现 一 思想分析 设定两个栈 操作数栈 OPND 操作符栈 OPTR 栈初始化 置操作数栈 OPND 为空 操作符栈 OPTR 中预设一个优先级最低的操作符 自左
  • 3分钟弄清楚javascript的堆栈原理

    首先了解一下Javascript的堆栈概念 堆 栈 两者都是存放临时数据的地方 栈 stack 栈的特点是 LIFO 即后进先出 Last in first out 数据存储时只能从顶部逐个存入 取出时也需从顶部逐个取出 比如一个乒乓球的盒
  • 鸿蒙2.0都来了,一起把环境搭建起来!

    自4月底开始 鸿蒙2 0系统便迎来公测 6月2日将举行鸿蒙操作系统以及华为全场景新品发布会 届时会正式推出鸿蒙OS稳定版 针对华为发布的鸿蒙系统 网上评论褒贬不一 有吹捧的 有无脑黑的 在这里一口君就不做评价了 但是有2点 对任何一个新兴事
  • esp和ebp详解

    我的理解 国外一个比较好的汇编网站 http www tenouk com Bufferoverflowc Bufferoverflow1b html http blog sina com cn s blog c3bab4650101ogf
  • C++语法基础之栈和队列

    栈 头文件 lt stack gt 实例化 stack在内部默认使用std deque存储数据 但是可以指定使用vector或者list存储数据 示例 std stack
  • 汇编语法

    1 通用寄存器 EAX EBX ECX EDX ESI EDI ESP EBP 它 们 的低 16 位就是 8086 的 AX BX CX DX SI DI SP BP 它们的含义如下 EAX 累加器 EBX 基址寄存器 Base ECX
  • 音频驱动篇之pop音攻略

    接触音频驱动工作也有2年的时间了 这这段时间里深刻感受了手机行业的更新换代是MB的迅速 2年的时间里 从TI到QUALCOMM 从android2 1到4 2 从单核到四核 经我参与的项目就有20款 日子是相当的难过 今天回头来说一些我在研
  • Linux驱动_多点电容触摸

    一丶Linux下多点电容触摸驱动框架 电容触摸屏IC是FT5426 为IIC协议芯片 因此需要编写IIC驱动 触摸IC会发出中断信号 并在中断服务函数中上报信息 因此需要编写中断框架 触摸屏向Linux内核上报的信息都属于Input子系统
  • 有趣的数据结构算法10——后缀表达式(PRN)介绍及利用栈计算后缀表达式的结果

    有趣的数据结构算法10 后缀表达式 PRN 介绍及利用栈计算后缀表达式的结果 解题思路 实现代码 GITHUB下载连接 在前一天已经利用栈完成2进制到8进制的转换 但是栈的应用方面还有很多 本次我将讲解如何计算后缀表达式的结果 解题思路 后
  • Leetcode题解——30. 包含min函数的栈(辅助栈思想)

    题目地址 剑指 Offer 30 包含min函数的栈 力扣 LeetCode 目录 一 算法思想 二 代码实现 三 拓展思考 首先说结论 这道题虽然难度不大 但是算法思想很重要 是辅助栈应用的生动实例 所以 这里小编不再重点将代码 而是讲思
  • 【数据结构与算法】栈的实现(附源码)

    目录 一 栈的概念和结构 二 接口实现 A 初始化 Stackinit 销毁 Stackdestroy 1 Stackinit 2 Stackdestroy B 插入 Stackpush 删除 Stackpop 1 Stackpush 2
  • 【数据结构】链栈的定义和基本操作

    链栈定义及各类操作 include
  • C语言实现栈(基于数组)

    栈是一种操作受限的数据结构 只允许从一段操作 而且先进后出 FILO first in last out 这里将栈的操作封装在C语言的头文件里 实现栈的代码如下 include
  • 反汇编笔记

    1 OD中ctrl f9 运行到返回 就是运行到当前断点所在的函数末尾 retn xxx 处 若xxx 10 那么 10等于10进制的16 就是说这个函数有4个参数 一个参数默认是占4字节 所以就是retn 10 2 调试程序时 在OD内部
  • CH3-栈和队列

    文章目录 3 1栈和队列的定义和特点 栈的应用 队列的应用 3 1 1栈的定义和特点 3 1 2队列的定义和特点 3 2案例引入 案例3 1 进制转换 案例3 2 括号匹配的检验 案例3 3 表达式求值 案例3 4 舞伴问题 3 3栈的表示
  • 使用两个栈(stack)实现一个队列(queue)

    题目 已知下面Stack类及其3个方法Push Pop和Count 请用2个Stack实现Queue类的入队 Enqueue 出队 Dequeue 方法 class Stack public void Push int x Push an

随机推荐

  • 第四章 索引和视图 总结

    第四章 索引和视图 1 索引 索引主要分为聚类索引和非聚类索引 聚类索引 表中数据行的物理存储顺序与索引顺序完全相同 每个表只能有一个聚类索引 物理的重拍表中的数据以符合索引约束 用于经常查找的列 非聚类索引 不改变表中数据行的物理存储位置
  • linux系统中解决docker: command not found

    新申请了一台阿里云的服务器 打算在上边部署一个容器服务 竟然发现机器上连docker都没安装 如果是mac OS系统 可以参考文章 mac系统中解决docker command not found 解决 针对这个问题 今天特意记录了一下 我
  • 网上总结的字节跳动前端面试题

    1 jQuery与Vue的区别是什么 Vue vue是一个兴起的前端js库 是一个精简的MVVM 从技术角度讲 Vue js 专注于 MVVM 模型的 ViewModel 层 它通过双向数据绑定把 View 层和 Model 层连接了起来
  • Python爬虫常见异常及解决办法

    文章目录 1 selenium common exceptions WebDriverException Message unknown error cannot find Chrome binary 方法一 配置参数 方法二 修改源文件
  • mysql学习-mysql数据类型学习01

    数据类型概览 数值类型 整数类型包括 TINYINT SMALLINT MEDIUMINT INT BIGINT 浮点数类型包括 FLOAT 和 DOUBLE 定点数类型为 DECIMAL tinyint smallint mediumin
  • 【MySQL】MYSQL内核:INNODB存储引擎 卷1pdf——百度网盘下载

    百度网盘地址 https pan baidu com s 1p4CsmBhYzrIawwUznmByYw 资源来之不易 需要获取密码 请关注公众号 全栈船长 并回复数字 0002
  • 前端开发:JS中截取字符串的用法总结,高级Android程序员必会

    var a 0123456789 a substring 5 2 4 start 和 stop 有字符串 但是最后的输出结果是 234 a substring 5 hh start 和 stop 有字符串 但是最后的输出结果是 234 二
  • 计算机在汽车设计方面的应用属于计算机的,计算机技术辅助设计在汽车设计中的应用.pdf...

    82 车辆与动力工程 Vehicles and Power Engineering 2017 年 2 月 计算机技术辅助设计在汽车设计中的应用 温 欣 汪 家宇 杨 海 南 沈 阳理工 大学 辽 宁 沈 阳 110159 摘 要 随着社会经
  • keil软件调试(Debug)仿真教程(软件调试和硬件调试的区别)及常用调试按键详解

    文章目录 前言 一 什么是软件调试 Debug 有什么用 二 keil Debug常用按钮 总结 前言 单片机的调试分为两种 一种是使用软件模拟调试 第二种是硬件调试 两种调试方式各有不同 软件模拟调试有误差 而硬件调试 借用仿真器调试是嵌
  • 新斗罗大陆手游服务器维护,《新斗罗大陆》新ss魂师天青龙牛天修复公告

    亲爱的魂师大人 新SS魂师天青龙牛天首发后 小舞收到了大量意见反馈 部分魂师大人认为牛天战斗结果异常 过高的伤害与其魂师定位不符 我们在接收到反馈的第一时间 进行了紧急核查 随后 我们发现该问题是由牛天的技能 龙魂觉醒 导致 当牛天施展该技
  • AQS原理解析及源码分析

    目录 1 介绍下AQS几个重要的组件 2 内部成员变量state 3 同步队列NODE 4 等待队列 condition AbstractQueuedSynchronizer又称为队列同步器 后面简称AQS AQS的核心思想是 如果被请求的
  • 对比梯度下降和正规方程解性能

    现在用导数的方式模拟线性回归中的梯度下降法 首先再来回顾一下梯度下降法的基础 梯度下降法不是一个机器学习算法 而是一个搜索算法 梯度下降法用在监督学习中 梯度下降法的过程 对比模型输出值和样本值的差异不断调整本省权重 直到最后模型输出值和样
  • Leetcode题解——26.树的子结构

    题目地址 剑指 Offer 26 树的子结构 力扣 LeetCode 目录 一 解题思路 一 大体思路 二 Search函数 三 Judge函数 二 代码实现 三 拓展思考 一 解题思路 一 大体思路 对于二叉树类的题目 一般会使用递归或层
  • YOLOv5 tensorRT C++代码详解之engine的读取

    在tensorRT中 engine模型是对yolov5序列化后的结果 在推理的时候需要进行反序列化才能进行推理 那么第一步就是读取engine文件 ifstream介绍 engine文件的读取需要用到ifstream 需要导入头文件 inc
  • SpringBoot最简单好用的导出导入功能,拿来即用

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 拿来吧你 一 接口说明 二 依赖 三 导出工具类 四 导入工具类 五 实体类的改造 BaseEntity java 六 控制层使用 七 效果 数据库表 1 下载模板
  • C++中三种产生随机数的方法

    第一种方法 使用时间做为生成随机数的种子 include
  • 190705 安卓-对抗AndResGuard的重打包

    换了一个apk实验后 apktool b f p xxx也不行 仍然报资源错误 看了一下可能是鹅厂出的AndResGuard工具 会将资源文件夹 Res xxx重命名为 r x类的目录 导致资源解析出错 针对这个混淆有shakaApktoo
  • volatile 的理解

    文章目录 前言 通过一系列的问题 了解volatile 总结 前言 在面试的时候 经常会遇到多线程的问题 然后面试官会提到 你是怎么做到线程安全的 然后就会涉及到关键字volatile 这个是在面试过程中高频率出现的 所以还是有必要对它进行
  • 岭回归(Ridge Regression)及实现

    岭回归 Ridge Regression 及实现 https blog csdn net google19890102 article details 27228279 一 一般线性回归遇到的问题 在处理复杂的数据的回归问题时 普通的线性回
  • linux驱动调试--段错误之栈信息分析

    转自 http blog chinaunix net xmlrpc php r blog article uid 29401328 id 4923529 接着上一篇来分析一下Oops的栈 s3c2440平台 关于调试源码和整个Oops信息请