使用GDB调试Linux内核空指针问题
1.概述
在Linux内核开发中,我们会经常遇到访问空指针导致内核Oops或panic。遇到这种问题,需要先定位出是哪一个函数、哪一个变量导致的异常。通常情况下,Linux内核会打印出异常时的栈、模块、CPU寄存器等信息,但某些情况下,栈被破环,只能输出寄存器信息(U-Boot发生异常时只会输出寄存器信息),那我们只能根据寄存器信息还原出发生异常时的现场。
2,实例
如下图所示,内核明确的出了异常原因-访问空指针,空指针解引用地址为0x00000003(若异常地址不为0,应该是访问了某个结构体中的变量,加上了偏移地址),发生异常的函数为__dwc3_gadget_ep_set_halt
,上一个调用函数为dwc3_ep0_stall_and_restart
。
pc寄存器保存了CPU执行的指令地址(0xffffff8008734ae4),可以根据该地址得到异常发生时调用的函数和访问的变量,lr保存了上一个调用函数的地址(0xffffff80087369e4)。下面使用gdb,还原发生异常时的现场。
- 首先启动aarch64-linux-gnu-gdb,使用file命令读取vmlinux镜像,获取Linux内核的所有符号。
- 使用list命令获取指令地址附件的符号。
如下图所示,0xffffff8008734ae4地址在__dwc3_gadget_ep_set_halt
函数中,内部调用了usb_endpoint_xfer_isoc
内联函数,异常就发生在该内联函数中。
__dwc3_gadget_ep_set_halt
函数部分代码如下,三个参数分别使用x0、x1、x2寄存器传递,内部调用了usb_endpoint_xfer_isoc
内联函数。
[drivers/usb/dwc3/gadget.c]
int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
{struct dwc3_gadget_ep_cmd_params params;struct dwc3 *dwc = dep->dwc;int ret;if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name);return -EINVAL;}memset(¶ms, 0x00, sizeof(params));......return ret;
}
如下图所示,lr寄存器保存的地址指向了dwc3_ep0_stall_and_restart
函数,该函数内部调用了__dwc3_gadget_ep_set_halt
函数。
- 使用x命令获取异常指令附近的汇编代码。可以使用x/20i 0xffffff8008734ae4命令获取异常地址以后的20条汇编指令,也可以使用x/20i __dwc3_gadget_ep_set_halt命令直接获取发生异常的函数的汇编代码。上面已经明确了发生异常的函数,因此这里直接获取该函数的汇编代码,便于分析。
如下图红框3所示,异常地址0xffffff8008734ae4处是一条内存加载指令,将x0寄存器中保存的地址加2得到一个新的地址,再将该地址处的一个字节的数据保存到w0寄存器中。x0寄存器由红框2更新,其保存的数据来自于x19寄存器保存的地址加56。如红框1所示,x19寄存器的值又来自于x0,而x0是函数的第一个参数,即端点数据结构struct dwc3_ep
的地址,地址为x19: ffffffc0f0b5c400
。红框2和红框3都是对struct dwc3_ep
数据结构内部变量的访问,偏移值56和3是内部变量相对于结构体基地址的偏移。
- 上面我们已经明确了发生异常的函数和访问的数据结构,现在我们需要根据偏移值确定访问的具体变量。
使用ptype /o struct dwc3_ep命令获取struct dwc3_ep
数据结构各个变量的偏移值.如下图所示,偏移值为56的变量为struct usb_ep
结构体中的desc
变量,即端点描述符的地址。
使用ptype /o struct usb_endpoint_descriptor命令获取struct usb_endpoint_descriptor
数据结构各个变量的偏移值。如下图所示,偏移值为3的变量为bmAttributes
,即端点的属性。
从上面的分析中可以看出,红框3中[x0, #3]=0x00000003,x0中保存的地址为NULL,即指针变量desc
是一个空指针,空指针解引用时发生了异常,也即在内联函数usb_endpoint_xfer_isoc
中访问bmAttributes
变量导致了异常。后续我们只需要排查是什么原因导致了指针变量desc
变为空指针即可。
使用GDB调试Linux内核空指针问题相关推荐
- qemu debug linux内核,在QEMU环境中使用GDB调试Linux内核
简介 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试.其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qem ...
- Vmware+gdb调试Linux内核——工欲善其事,必先利其器
今天我最终忍受不了qemu的低速跟不可理喻的各种bug,開始寻找新的调试内核的方法.然后想到了Vmware,那么成熟的虚拟机怎么可能调试不了内核.于是尝试了一番,发现结果很的棒!所以立刻奋笔疾书.把这 ...
- qemu+gdb调试linux内核
文章目录 编译内核 下载qemu 构建initramfs根文件系统 1.编译Busybox 2.生成initrd 3.测试根文件系统 gdb调试内核 参考文献 编译内核 # make menuconf ...
- 利用QEMU+GDB搭建Linux内核调试环境
前言 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试. 其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qe ...
- linux问号符号,调试linux内核时gdb中的问号符号4.10
我想从linux内核中的函数start_kernel()调试linux内核.调试linux内核时gdb中的问号符号4.10 这基本上就是我已经做了 从kernel.org 下载4.10内核源提取源后: ...
- 使用 ftrace 调试 Linux 内核【转】
转自:http://blog.csdn.net/adaptiver/article/details/7930646 使用 ftrace 调试 Linux 内核,第 1 部分 http://blog.c ...
- 用 GDB 调试Linux程序及有用技巧
用 GDB 调试Linux程序及有用技巧(转) armlinux 2008-06-19 10:48 阅读91 评论0 字号: 大大 中中 小小 GNU的调试器称为gdb,该程序是一个交 ...
- 使用openocd调试Linux内核,OpenOCD-JTAG调试
title: OpenOCD-JTAG调试 tags: ARM date: 2018-10-13 23:36:28 Todo [ ] JTAG 调试linux内核 [ ] linux下使用OpenOC ...
- 使用openocd调试Linux内核,OpenOCD-JTAG调试(示例代码)
目录 title: OpenOCD-JTAG调试 tags: ARM date: 2018-10-13 23:36:28 --- Todo [ ] JTAG 调试linux内核 [ ] linux下使 ...
最新文章
- 接私活福音,validation组件敏捷开发,效率提升5倍!
- leetcode 752. 打开转盘锁 c代码
- epoll(eventpoll)是干嘛的?IO多路转接技术(相较select、poll的优点)
- bean定义的继承 - Spring Framework reference 2.0.5 参考手册中文版
- 大数据时代的数据存储,非关系型数据库MongoDB(一)(转)
- Django 【第十九篇】JS实现的ajax、同源策略和前端JSONP解决跨域问题
- php取汉字拼音首字母,php获取汉字拼音首字母的函数(真正可以使用的)
- 基于jquery的全局ajax函数处理session过期后的ajax操作
- (转帖出自ESRI BBS)有关于GIS思想
- CruiseControl.NET and MSBuild
- win10自带邮件mail登录qq邮箱126邮箱等时提示需注意的解决办法
- Ceph 网络模块(1) - 网络模块基本结构
- Qt自带示例演示程序
- Educoder-练习-Java循环综合练习四之日历打印
- 如何把计算机组成原理、操作系统、数据结构和计算机网络融会贯通,相互联系起来?
- Java静态类的使用
- 四. 常用EMC防护器件选型学习笔记
- 计算机组成原理第二章:运算方法和运算器
- 电力节能设备远程监控系统解决方案
- BMZCTF-Web WriteUp
热门文章
- 【Hadoop基础教程】7、Hadoop之一对一关联查询
- 扶贫工作-结对帮扶公示牌 自动化填写
- LS1046A 启动流程分析
- 专转本-计算机二级习题1
- 逻辑回归logistic原理(python代码实现)
- 【RK3399】[Android 6.0] linux4.4 调试8723BU记录过程
- Error occured processing XML 'Cannot find class [springmvc.extention.BeanArgumentResolver]
- 安利超实用的游戏技能特效素材!
- typeAliasesPackage的作用
- camunda如何插入以及获取流程审批